Open narutaro opened 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]
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
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
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
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
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)
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-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
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ともに以下の結果。
普通にShared Subscriptionのグループ内でラウンドロビンされる。期待される動作。
動作が予測できない...。AWS IoT Coreはクライアントごとにキューがあるような動作に見えるが、app1がdisconnectした際にはapp2とapp3でラウンドロビンをしているようにみえる。一方で、app1がre-connectした際に、payload 7は再送された。詳細は上記のログを参照。
クライアントごとにキューがあるように見える。そのため、app1とapp2がdisconnectした場合、app3が代わりにメッセージを受けるという動作にはならなずに、app3は二つ飛ばしでメッセージを受け取る。app1, app2がre-connectするとキューに溜まっていたメッセージを受け取る。
はじめに
MQTT5で追加された機能であるShared Subscriptionは簡単にいうとロードバランスであり、再接続時にキューイングしたメッセージを受け取ることのできるPersistent Sessionとは相容れないように思える。これらを組み合わせたときにどのような動作となるかMosquittoおよびAWS IoT Coreにて確認する。
接続構成
テストシナリオ
クライアントの設定とテストログ - AWS IoT Core
aws-car
Subscriber
aws-app1
aws-app2
app1と同様のクライアント設定
aws-app3
app1と同様のクライアント設定
クライアントの設定とテストログ - Mosquitto Broker
mos-car
mos-app1
mos-app2
mos-app1と同様のクライアント設定
mos-app3
mos-app1と同様のクライアント設定
結果
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するとキューに溜まっていたメッセージを受け取る。