Introduction
The new shared subscriptions feature in AWS IoT Core brings the load balancing capability to multiple subscribing MQTT sessions or consumers. While non-shared subscription sends all the published messages to all its subscribers, shared subscription sends a published message to only one of its subscribers in a random manner. In this blog post, we’ll show how to get started with the shared subscriptions over MQTT in AWS IoT Core. We’ll detail the steps for using the feature and demonstrate the load sharing mechanism of shared subscriptions.
Non-shared Subscriptions Flow | Shared Subscriptions Flow |
---|---|
Shared subscriptions find its uses in verticals like connected automotive solutions, industrial and manufacturing, connected homes, and more. It is highly advantageous in a setup where millions of devices publish messages to a common topic. There may be consumer applications that need to process the incoming data, example storage in data lake after some pre-processing, a machine learning pipeline for predictive maintenance, a location-based application and more. These slower application servers can be grouped together to process the high-speed incoming data. Each group can read from the shared topic on a shared subscription. This will help in distributing the processing load amongst the application servers within a group. Without the shared subscription feature, any messages that gets post on the MQTT topic will be published to all the clients subscribing to the topic. With the shared subscription feature only one of the groups clients will receive the message on this topic. To summarize, some of the advantages that come with load balanced shared subscription topics are –
- load balanced highly available consumers based on downstream systems’ health,
- consumer infrastructure horizontal scaling for variable published message load,
- time consuming downstream processing slowing the message consumer, etc.
Overview
To illustrate this, a sample setup and message flow is shown below. There are N cars publishing data to a common topic cars/data. The topic has five subscribers. Subscribers 1A and 1B are in consumer group1 and subscribers 2A and 2B are in consumer group2. Consumer3 is an independent consumer.
Shared Subscriptions defined in the MQTT5 standard are enabled for both MQTT3 and MQTT5 clients. It does not make use of any MQTT 5 specific features, rather it uses a dedicated reserved topic space, $share. New and existing MQTT3 clients can publish or subscribe to shared subscriptions.
To use shared subscriptions, clients subscribe to a Shared Subscription’s topic filter as follows:
$share/{ShareName}/{TopicFilter}
Different subscribing clients are permitted to ask for different requested QoS levels in their SUBSCRIBE packets. If the Server is processing a Quality of Service 1(QoS1) message to its chosen subscriber loses connection before an acknowledgment message is received (i.e PubAck), the serve will resend the message to the next subscriber in the shared group. If a subscriber to the share group becomes disconnected, the message will then be sent to another subscriber in the share to ensure message delivery.
Prerequisites
To follow through this blog post, you will need an AWS account, an AWS IoT Core supported region, permissions to create AWS IoT Rules, AWS Lambda Functions, AWS Identity and Access Management (IAM) roles and policies, and access to AWS CloudShell. We also assume you are familiar with the basics of Linux bash commands.
Walkthrough
Now that we have seen an overview of this feature, let us walk-through the steps to implement them. It will take less than 30 minutes for users to run the upcoming setup.
For this walk through, we will be creating car1 and car2 as the publishers and consumer group2 with subscribers 2A, 2B, and an independent consumer3 as the subscribers (refer architecture diagram above). With the shared subscription feature when a message gets published to consumer group2, only one of the subscribers (2A or 2B in our example) will get the message in a random manner. Also, consumer3 gets all the messages.
Step1: Use the AWS CLI or the AWS Console to create the IoT things car1, car2, subscriber2A, subscriber2B and consumer3. If you are not familiar with how to create virtual devices, please refer to this documentation for step by step instructions on how to create these devices.
Output:
Folder structure below for reference
Step 2: After creating the virtual devices, we will use any one of the mosquitto MQTT clients (Eclipse Mosquitto in our case) to publish and subscribe messages. To download and install the clients, please refer to the steps in this documentation. We will use five terminals to verify this use case. The publishers car1 and car2 will publish to cars/data topic and the subscriber 2A and subscriber 2B will subscribe to topic $share/group2/cars/data. Open the terminals and run each of these commands in separate terminals. consumer3 is not part of any group and subscribes to topic cars/data.
Setting up environment variable for IoT endpoint:
If you are using a *.nix based operating system like mac, ubuntu, redhat etc., run the command below. Ensure that jq library is installed prior to running the command.
endpoint=`aws iot describe-endpoint --endpoint-type iot:Data-ATS | jq -r '.endpointAddress'`
If you are using windows follow the below command to set the environment variable
$endpoint = aws iot describe-endpoint --endpoint-type iot:Data-ATS | jq -r '.endpointAddress'
Setting up subscribers:
Terminal 1: Navigate to the folder where you have the certs for subscriber 2A and run the command given below
mosquitto_sub --cafile AmazonRootCA1.pem \
--cert subscriber2a.certificate.pem \
--key subscriber2a.private.key -h $endpoint -p 8883 \
-q 0 -t "\$share/group2/cars/data" -i subscriber2a-sub \
--tls-version tlsv1.2 -d -V mqttv5
Output:
Terminal 2: Navigate to the folder where you have the certs for subscriber 2B and run the command given below.
mosquitto_sub --cafile AmazonRootCA1.pem \
--cert subscriber2b.certificate.pem \
--key subscriber2b.private.key -h $endpoint-p 8883 \
-q 0 -t "\$share/group2/cars/data" -i subscriber2b-sub \
--tls-version tlsv1.2 -d -V mqttv5
Output:
Terminal 3: Navigate to the folder where you have the certs for consumer3 and run the command given below.
mosquitto_sub --cafile AmazonRootCA1.pem \
--cert consumer3.certificate.pem \
--key consumer3.private.key -h $endpoint -p 8883 \
-q 0 -t "cars/data" -i consumer3-sub \
--tls-version tlsv1.2 -d -V mqttv5
Output:
Setting up publishers:
Open a new terminal and run the below command to publish data to the cars/data topic. For this illustration, we will be publishing the speed information of the car through a .json file. Copy the contents below and save them in messages.json file in the cars1 folder.{"ID": "car1", "speed": "75"}
{"ID": "car1", "speed": "77"}
{"ID": "car1", "speed": "79"}
Run the command below, to publish data to the topiccat messages.json |mosquitto_pub --cafile AmazonRootCA1.pem \
--cert car1.certificate.pem \
--key car1.private.key -h <<IoT_endpoint>> -p 8883 \
-q 0 -t cars/data -i car1 --tls-version tlsv1.2 \
-d -V mqttv5 -D publish topic-alias 2 -l
Repeat the above step again from car2 folder and observe the subscribers.
Output:
The below output shows consumer3 receives all the messages, whereas only of one of subscriber 2A or 2B gets each of the messages.
Cleaning Up
To avoid any recurring charges, remove the resources created in this blog. Follow the steps to delete these resources:
Step1: Delete the certificates associated with the things.
On your AWS console, navigate to aws IoT core and on the left pane select Security → Certificates and delete all the certificates associated with car1, car2, subscriber 2A, 2B and consumer3 by clicking on Actions→Delete.
Step2: Delete the IoT things created.
On the AWS IoT core service page, select Manage→All devices→Things. Select all the things created for this walkthrough and select delete
Conclusion
In this post, you learned how to get started with the new AWS IoT Core shared subscriptions features, key steps to take before using the feature, and information to load balance your topic subscribers by creating a group. For a more in depth look at using the shared subscriptions with AWS IoT Core, please take a look at the developer guide. To get started and to learn more about MQTT5 features supported by AWS, refer to the technical documentation.
Authors