narutaro / note

0 stars 0 forks source link

Shared Subscription with Persistent Session の動作をテストする #14

Open narutaro opened 1 year ago

narutaro commented 1 year ago

はじめに

MQTT5で追加された機能であるShared Subscriptionは簡単にいうとロードバランスであり、再接続時にキューイングしたメッセージを受け取ることのできるPersistent Sessionとは相容れないように思える。これらを組み合わせたときにどのような動作となるかMosquittoおよびAWS IoT Coreにて確認する。

接続構成

flowchart LR
A[car] --MQTT--- B[Broker\nShared Subscription]
B --Persistent Session--- D[app1]
B --Persistent Session--- E[app2]
B --Persistent Session--- F[app3]

テストシナリオ

  1. Carがpayload 1を送信
  2. Carがpayload 2を送信
  3. Carがpayload 3を送信
  4. app1がdisconnect
  5. Carがpayload 4を送信
  6. Carがpayload 5を送信
  7. Carがpayload 6を送信
  8. app2がdisconnect
  9. Carがpayload 7を送信
  10. Carがpayload 8を送信
  11. Carがpayload 9を送信
  12. Carがpayload 0を送信
  13. app1がre-connect
  14. app2がre-connect

クライアントの設定とテストログ - AWS IoT Core

aws-car

endpointAddress="<code>-ats.iot.ap-northeast-1.amazonaws.com"

mosquitto_pub --cafile AmazonRootCA1.pem \
  --cert device.pem.crt \
  --key private.pem.key \
  -h $endpointAddress \
  -p 8883 \
  -t "cars/data" \
  -i $0 \
  -l \
  -V 5 \
  -q 1 \
  -d
masainox@~/Projects/shared-subscription-with-persistent-session/car ❱❱❱ ./aws-car.sh 
Client ./aws-car.sh sending CONNECT
Client ./aws-car.sh received CONNACK (0)
1
Client ./aws-car.sh sending PUBLISH (d0, q1, r0, m1, 'cars/data', ... (1 bytes))
Client ./aws-car.sh received PUBACK (Mid: 1, RC:0)
2
Client ./aws-car.sh sending PUBLISH (d0, q1, r0, m2, 'cars/data', ... (1 bytes))
Client ./aws-car.sh received PUBACK (Mid: 2, RC:0)
3
Client ./aws-car.sh sending PUBLISH (d0, q1, r0, m3, 'cars/data', ... (1 bytes))
Client ./aws-car.sh received PUBACK (Mid: 3, RC:0)
4
Client ./aws-car.sh sending PUBLISH (d0, q1, r0, m4, 'cars/data', ... (1 bytes))
Client ./aws-car.sh received PUBACK (Mid: 4, RC:0)
5
Client ./aws-car.sh sending PUBLISH (d0, q1, r0, m5, 'cars/data', ... (1 bytes))
Client ./aws-car.sh received PUBACK (Mid: 5, RC:0)
6
Client ./aws-car.sh sending PUBLISH (d0, q1, r0, m6, 'cars/data', ... (1 bytes))
Client ./aws-car.sh received PUBACK (Mid: 6, RC:0)
7
Client ./aws-car.sh sending PUBLISH (d0, q1, r0, m7, 'cars/data', ... (1 bytes))
Client ./aws-car.sh received PUBACK (Mid: 7, RC:0)
8
Client ./aws-car.sh sending PUBLISH (d0, q1, r0, m8, 'cars/data', ... (1 bytes))
Client ./aws-car.sh received PUBACK (Mid: 8, RC:0)
9
Client ./aws-car.sh sending PUBLISH (d0, q1, r0, m9, 'cars/data', ... (1 bytes))
Client ./aws-car.sh received PUBACK (Mid: 9, RC:0)
0

Subscriber

aws-app1

endpointAddress="<code>-ats.iot.ap-northeast-1.amazonaws.com"

mosquitto_sub --cafile AmazonRootCA1.pem \
  --cert device.pem.crt \
  --key private.pem.key \
  -h $endpointAddress \
  -V 5 \
  -p 8883 \
  -t "\$share/group1/cars/data" \
  -i $0 \
  -q 1 \
  -c \
  -x 300 \
  -F '%j' \
  -d
masainox@~/Projects/shared-subscription-with-persistent-session/app1 ❱❱❱ ./aws-app1.sh 
Client ./aws-app1.sh sending CONNECT
Client ./aws-app1.sh received CONNACK (0)
Client ./aws-app1.sh sending SUBSCRIBE (Mid: 1, Topic: $share/group1/cars/data, QoS: 1, Options: 0x00)
Client ./aws-app1.sh received SUBACK
Subscribed (mid: 1): 1
Client ./aws-app1.sh received PUBLISH (d0, q1, r0, m1, 'cars/data', ... (1 bytes))
Client ./aws-app1.sh sending PUBACK (m1, rc0)
{"tst":"2023-07-18T10:32:14.736447+0900","topic":"cars/data","qos":1,"retain":0,"payloadlen":1,"mid":1,"payload":"1"}
^CClient ./aws-app1.sh sending DISCONNECT
masainox@~/Projects/shared-subscription-with-persistent-session/app1 ❱❱❱ ./aws-app1.sh
Client ./aws-app1.sh sending CONNECT
Client ./aws-app1.sh received CONNACK (0)
Client ./aws-app1.sh sending SUBSCRIBE (Mid: 1, Topic: $share/group1/cars/data, QoS: 1, Options: 0x00)
Client ./aws-app1.sh received SUBACK
Subscribed (mid: 1): 1
Client ./aws-app1.sh received PUBLISH (d0, q1, r0, m1, 'cars/data', ... (1 bytes))
Client ./aws-app1.sh sending PUBACK (m1, rc0)
{"tst":"2023-07-18T10:32:48.919770+0900","topic":"cars/data","qos":1,"retain":0,"payloadlen":1,"mid":1,"payload":"7"}
Client ./aws-app1.sh sending PINGREQ
Client ./aws-app1.sh received PINGRESP

aws-app2

app1と同様のクライアント設定

masainox@~/Projects/shared-subscription-with-persistent-session/app2 ❱❱❱ ./aws-app2.sh 
Client ./aws-app2.sh sending CONNECT
Client ./aws-app2.sh received CONNACK (0)
Client ./aws-app2.sh sending SUBSCRIBE (Mid: 1, Topic: $share/group1/cars/data, QoS: 1, Options: 0x00)
Client ./aws-app2.sh received SUBACK
Subscribed (mid: 1): 1
Client ./aws-app2.sh received PUBLISH (d0, q1, r0, m1, 'cars/data', ... (1 bytes))
Client ./aws-app2.sh sending PUBACK (m1, rc0)
{"tst":"2023-07-18T10:32:15.531578+0900","topic":"cars/data","qos":1,"retain":0,"payloadlen":1,"mid":1,"payload":"2"}
Client ./aws-app2.sh received PUBLISH (d0, q1, r0, m1, 'cars/data', ... (1 bytes))
Client ./aws-app2.sh sending PUBACK (m1, rc0)
{"tst":"2023-07-18T10:32:22.821081+0900","topic":"cars/data","qos":1,"retain":0,"payloadlen":1,"mid":1,"payload":"4"}
Client ./aws-app2.sh received PUBLISH (d0, q1, r0, m1, 'cars/data', ... (1 bytes))
Client ./aws-app2.sh sending PUBACK (m1, rc0)
{"tst":"2023-07-18T10:32:25.330008+0900","topic":"cars/data","qos":1,"retain":0,"payloadlen":1,"mid":1,"payload":"6"}
^CClient ./aws-app2.sh sending DISCONNECT
masainox@~/Projects/shared-subscription-with-persistent-session/app2 ❱❱❱ ./aws-app2.sh
Client ./aws-app2.sh sending CONNECT
Client ./aws-app2.sh received CONNACK (0)
Client ./aws-app2.sh sending SUBSCRIBE (Mid: 1, Topic: $share/group1/cars/data, QoS: 1, Options: 0x00)
Client ./aws-app2.sh received SUBACK
Subscribed (mid: 1): 1
Client ./aws-app2.sh sending PINGREQ
Client ./aws-app2.sh received PINGRESP
Client ./aws-app2.sh sending PINGREQ
Client ./aws-app2.sh received PINGRESP

aws-app3

app1と同様のクライアント設定

masainox@~/Projects/shared-subscription-with-persistent-session/app3 ❱❱❱ ./aws-app3.sh 
Client ./aws-app3.sh sending CONNECT
Client ./aws-app3.sh received CONNACK (0)
Client ./aws-app3.sh sending SUBSCRIBE (Mid: 1, Topic: $share/group1/cars/data, QoS: 1, Options: 0x00)
Client ./aws-app3.sh received SUBACK
Subscribed (mid: 1): 1
Client ./aws-app3.sh received PUBLISH (d0, q1, r0, m1, 'cars/data', ... (1 bytes))
Client ./aws-app3.sh sending PUBACK (m1, rc0)
{"tst":"2023-07-18T10:32:16.779762+0900","topic":"cars/data","qos":1,"retain":0,"payloadlen":1,"mid":1,"payload":"3"}
Client ./aws-app3.sh received PUBLISH (d0, q1, r0, m1, 'cars/data', ... (1 bytes))
Client ./aws-app3.sh sending PUBACK (m1, rc0)
{"tst":"2023-07-18T10:32:24.090761+0900","topic":"cars/data","qos":1,"retain":0,"payloadlen":1,"mid":1,"payload":"5"}
Client ./aws-app3.sh received PUBLISH (d0, q1, r0, m1, 'cars/data', ... (1 bytes))
Client ./aws-app3.sh sending PUBACK (m1, rc0)
{"tst":"2023-07-18T10:32:33.111704+0900","topic":"cars/data","qos":1,"retain":0,"payloadlen":1,"mid":1,"payload":"8"}
Client ./aws-app3.sh received PUBLISH (d0, q1, r0, m1, 'cars/data', ... (1 bytes))
Client ./aws-app3.sh sending PUBACK (m1, rc0)
{"tst":"2023-07-18T10:32:35.452787+0900","topic":"cars/data","qos":1,"retain":0,"payloadlen":1,"mid":1,"payload":"9"}
Client ./aws-app3.sh received PUBLISH (d0, q1, r0, m2, 'cars/data', ... (1 bytes))
Client ./aws-app3.sh sending PUBACK (m2, rc0)
{"tst":"2023-07-18T10:32:35.453929+0900","topic":"cars/data","qos":1,"retain":0,"payloadlen":1,"mid":2,"payload":"0"}
Client ./aws-app3.sh sending PINGREQ
Client ./aws-app3.sh received PINGRESP
Client ./aws-app3.sh sending PINGREQ
Client ./aws-app3.sh received PINGRESP

クライアントの設定とテストログ - Mosquitto Broker

mos-car

endpointAddress="localhost"

mosquitto_pub \
  -h $endpointAddress \
  -p 1883 \
  -t "cars/data" \
  -i $0 \
  -l \
  -V 5 \
  -q 1 \
  -d
masainox@~/Projects/shared-subscription-with-persistent-session/car ❱❱❱ ./mos-car.sh 
Client ./mos-car.sh sending CONNECT
Client ./mos-car.sh received CONNACK (0)
1
Client ./mos-car.sh sending PUBLISH (d0, q1, r0, m1, 'cars/data', ... (1 bytes))
Client ./mos-car.sh received PUBACK (Mid: 1, RC:0)
2
Client ./mos-car.sh sending PUBLISH (d0, q1, r0, m2, 'cars/data', ... (1 bytes))
Client ./mos-car.sh received PUBACK (Mid: 2, RC:0)
3
Client ./mos-car.sh sending PUBLISH (d0, q1, r0, m3, 'cars/data', ... (1 bytes))
Client ./mos-car.sh received PUBACK (Mid: 3, RC:0)
4
Client ./mos-car.sh sending PUBLISH (d0, q1, r0, m4, 'cars/data', ... (1 bytes))
Client ./mos-car.sh received PUBACK (Mid: 4, RC:0)
5
Client ./mos-car.sh sending PUBLISH (d0, q1, r0, m5, 'cars/data', ... (1 bytes))
Client ./mos-car.sh received PUBACK (Mid: 5, RC:0)
6
Client ./mos-car.sh sending PUBLISH (d0, q1, r0, m6, 'cars/data', ... (1 bytes))
Client ./mos-car.sh received PUBACK (Mid: 6, RC:0)
7
Client ./mos-car.sh sending PUBLISH (d0, q1, r0, m7, 'cars/data', ... (1 bytes))
Client ./mos-car.sh received PUBACK (Mid: 7, RC:0)
8
Client ./mos-car.sh sending PUBLISH (d0, q1, r0, m8, 'cars/data', ... (1 bytes))
Client ./mos-car.sh received PUBACK (Mid: 8, RC:0)
9
Client ./mos-car.sh sending PUBLISH (d0, q1, r0, m9, 'cars/data', ... (1 bytes))
Client ./mos-car.sh received PUBACK (Mid: 9, RC:0)
0
Client ./mos-car.sh sending PUBLISH (d0, q1, r0, m10, 'cars/data', ... (1 bytes))
Client ./mos-car.sh received PUBACK (Mid: 10, RC:0)

mos-app1

endpointAddress="localhost"

mosquitto_sub \
  -h $endpointAddress \
  -V 5 \
  -p 1883 \
  -t "\$share/group1/cars/data" \
  -i $0 \
  -q 1 \
  -c \
  -x 300 \
  -F '%j' \
  -d
masainox@~/Projects/shared-subscription-with-persistent-session/app1 ❱❱❱ ./mos-app1.sh 
Client ./mos-app1.sh sending CONNECT
Client ./mos-app1.sh received CONNACK (0)
Client ./mos-app1.sh sending SUBSCRIBE (Mid: 1, Topic: $share/group1/cars/data, QoS: 1, Options: 0x00)
Client ./mos-app1.sh received SUBACK
Subscribed (mid: 1): 1
Client ./mos-app1.sh received PUBLISH (d0, q1, r0, m1, 'cars/data', ... (1 bytes))
Client ./mos-app1.sh sending PUBACK (m1, rc0)
{"tst":"2023-07-18T10:47:26.494477+0900","topic":"cars/data","qos":1,"retain":0,"payloadlen":1,"mid":1,"payload":"1"}
^CClient ./mos-app1.sh sending DISCONNECT

masainox@~/Projects/shared-subscription-with-persistent-session/app1 ❱❱❱ ./mos-app1.sh
Client ./mos-app1.sh sending CONNECT
Client ./mos-app1.sh received CONNACK (0)
Client ./mos-app1.sh sending SUBSCRIBE (Mid: 1, Topic: $share/group1/cars/data, QoS: 1, Options: 0x00)
Client ./mos-app1.sh received PUBLISH (d0, q1, r0, m2, 'cars/data', ... (1 bytes))
Client ./mos-app1.sh sending PUBACK (m2, rc0)
{"tst":"2023-07-18T10:47:44.700015+0900","topic":"cars/data","qos":1,"retain":0,"payloadlen":1,"mid":2,"payload":"4"}
Client ./mos-app1.sh received PUBLISH (d0, q1, r0, m3, 'cars/data', ... (1 bytes))
Client ./mos-app1.sh sending PUBACK (m3, rc0)
{"tst":"2023-07-18T10:47:44.700073+0900","topic":"cars/data","qos":1,"retain":0,"payloadlen":1,"mid":3,"payload":"7"}
Client ./mos-app1.sh received PUBLISH (d0, q1, r0, m4, 'cars/data', ... (1 bytes))
Client ./mos-app1.sh sending PUBACK (m4, rc0)
{"tst":"2023-07-18T10:47:44.700111+0900","topic":"cars/data","qos":1,"retain":0,"payloadlen":1,"mid":4,"payload":"0"}
Client ./mos-app1.sh received SUBACK

mos-app2

mos-app1と同様のクライアント設定

masainox@~/Projects/shared-subscription-with-persistent-session/app2 ❱❱❱ ./mos-app2.sh 
Client ./mos-app2.sh sending CONNECT
Client ./mos-app2.sh received CONNACK (0)
Client ./mos-app2.sh sending SUBSCRIBE (Mid: 1, Topic: $share/group1/cars/data, QoS: 1, Options: 0x00)
Client ./mos-app2.sh received SUBACK
Subscribed (mid: 1): 1
Client ./mos-app2.sh received PUBLISH (d0, q1, r0, m1, 'cars/data', ... (1 bytes))
Client ./mos-app2.sh sending PUBACK (m1, rc0)
{"tst":"2023-07-18T10:47:27.623416+0900","topic":"cars/data","qos":1,"retain":0,"payloadlen":1,"mid":1,"payload":"2"}
Client ./mos-app2.sh received PUBLISH (d0, q1, r0, m2, 'cars/data', ... (1 bytes))
Client ./mos-app2.sh sending PUBACK (m2, rc0)
{"tst":"2023-07-18T10:47:34.367673+0900","topic":"cars/data","qos":1,"retain":0,"payloadlen":1,"mid":2,"payload":"5"}
^CClient ./mos-app2.sh sending DISCONNECT
masainox@~/Projects/shared-subscription-with-persistent-session/app2 ❱❱❱ ./mos-app2.sh
Client ./mos-app2.sh sending CONNECT
Client ./mos-app2.sh received CONNACK (0)
Client ./mos-app2.sh sending SUBSCRIBE (Mid: 1, Topic: $share/group1/cars/data, QoS: 1, Options: 0x00)
Client ./mos-app2.sh received PUBLISH (d0, q1, r0, m3, 'cars/data', ... (1 bytes))
Client ./mos-app2.sh sending PUBACK (m3, rc0)
{"tst":"2023-07-18T10:47:47.647603+0900","topic":"cars/data","qos":1,"retain":0,"payloadlen":1,"mid":3,"payload":"8"}
Client ./mos-app2.sh received SUBACK

mos-app3

mos-app1と同様のクライアント設定

masainox@~/Projects/shared-subscription-with-persistent-session/app3 ❱❱❱ ./mos-app3.sh 
Client ./mos-app3.sh sending CONNECT
Client ./mos-app3.sh received CONNACK (0)
Client ./mos-app3.sh sending SUBSCRIBE (Mid: 1, Topic: $share/group1/cars/data, QoS: 1, Options: 0x00)
Client ./mos-app3.sh received SUBACK
Subscribed (mid: 1): 1
Client ./mos-app3.sh received PUBLISH (d0, q1, r0, m1, 'cars/data', ... (1 bytes))
Client ./mos-app3.sh sending PUBACK (m1, rc0)
{"tst":"2023-07-18T10:47:28.126668+0900","topic":"cars/data","qos":1,"retain":0,"payloadlen":1,"mid":1,"payload":"3"}
Client ./mos-app3.sh received PUBLISH (d0, q1, r0, m2, 'cars/data', ... (1 bytes))
Client ./mos-app3.sh sending PUBACK (m2, rc0)
{"tst":"2023-07-18T10:47:34.719915+0900","topic":"cars/data","qos":1,"retain":0,"payloadlen":1,"mid":2,"payload":"6"}
Client ./mos-app3.sh received PUBLISH (d0, q1, r0, m3, 'cars/data', ... (1 bytes))
Client ./mos-app3.sh sending PUBACK (m3, rc0)
{"tst":"2023-07-18T10:47:40.391782+0900","topic":"cars/data","qos":1,"retain":0,"payloadlen":1,"mid":3,"payload":"9"}
Client ./mos-app3.sh sending PINGREQ
Client ./mos-app3.sh received PINGRESP

結果

MosquittoおよびAWS IoT Coreともに以下の結果。

QoS0 の場合

普通にShared Subscriptionのグループ内でラウンドロビンされる。期待される動作。

QoS1 && Disable Clean Session && Session Interval 300sec の場合

AWS IoT Core

動作が予測できない...。AWS IoT Coreはクライアントごとにキューがあるような動作に見えるが、app1がdisconnectした際にはapp2とapp3でラウンドロビンをしているようにみえる。一方で、app1がre-connectした際に、payload 7は再送された。詳細は上記のログを参照。

Mosquitto

クライアントごとにキューがあるように見える。そのため、app1とapp2がdisconnectした場合、app3が代わりにメッセージを受けるという動作にはならなずに、app3は二つ飛ばしでメッセージを受け取る。app1, app2がre-connectするとキューに溜まっていたメッセージを受け取る。