Durable topics persist messages, which allows the messages to be received later if a subscriber is not online. A durable topic subscription is useful when a subscriber client needs to be able to receive messages that are published even when the client is inactive.
Creating durable topic subscriptions
If a client subscriber creates a durable subscription to the topic, the subscriber will be able to recover the messages that were published to the topic while the client was inactive. For example, a durable topic subscriber will receive all the messages that are published to the topic while the subscriber is active. However, if the subscriber becomes inactive for a time period and later returns to active state, the messages that were published during the inactive period will be fetched from the database and dispatched to the subscriber.
The following points will elaborate on the different elements that you need to be mindful of when creating a durable topic subscription:
Creating a durable topic subscription is similar to creating a nondurable subscription, but you must additionally provide a name that identifies the durable subscription as shown below.
// Create a durable subscriber, supplying a uniquely-identifying name TopicSubscriber sub = session.createDurableSubscriber( topic, "mySub1_0001" );
The session used to create a durable topic subscriber must have an associated client identifier. The client identifier can be specified by setting the CLIENTID property of the ConnectionFactory object. The client identifier associated with a session is the same as that associated with the connection that is used to create the session as shown below. The name that identifies a durable subscription must be unique only within the client identifier, and therefore the client identifier forms part of the full, unique identifier of the durable subscription.
For example, shown below is how the ClientID is set for an amqp session:
connectionfactory.Connectionfactory = amqp://admin:admin@clientID/carbon?brokerlist='tcp://192.168.10.5:5682'
Alternatively, an application can specify the client identifier by calling the
setClientID()
method of the Connection object. For more information about client identifiers and their relationship with durable topic subscribers and durable subscriptions, see Java™ Message Service Specification, Version 1.1.- Reusing a durable topic subscription: To reuse a durable subscription that was created previously, the subscriber client must create a durable topic subscriber using a session with the same client identifier as that associated with the durable subscription.
Tenant-specific durable subscriptions
When creating a JMS subscription in tenant mode, the username, topic name and subscription ID should be set in the following manner:
username =username!tenantdomain
Example: username =testuser!test.com;
topicName = tenantdomain/topicName;
Example: topicName = test.com/testTopic;
subscription Id=tenantdomain/subscription id
Example: subscription Id=test.com/K1;
Unsubscribing non-durable topic subscriptions
Nondurable message consumers in the publish/subscribe domain automatically deregister themselves when their close()
method is called or when they fall out of scope. However, if you want to terminate a durable subscription, you must explicitly notify the broker. To do this, use the unsubscribe()
method of the session and pass in the name that identifies the durable subscription:
// Unsubscribe the durable subscriber created above session.unsubscribe( "mySub1_0001" );
It is not possible to unsubscribe a durable consumer from inside the onMessage()
method in the listener. If you need to unsubscribe, write a separate class/thread etc. with a different session, give the subscription ID and unsubscribe.
Sharing a durable topic subscription
As explained in the previous section, durable topic subscriptions are unique. That is, the subscription ID and client ID, which are used for identifying the durable subscription should be unique. This means that it is not possible to have multiple subscriber clients sharing a single subscription. Now let's look at what is meant by 'sharing' a durable subscription and how this possibility can be enabled for WSO2 MB.
Understanding shared durable topic subscriptions
Consider the following scenario:
In the above example, there are two subscribers (A and B) with durable subscriptions to the topic and each subscriber performs a specific task with the messages received through the subscription. Therefore, when messages are published to the topic, copies of the messages are dispatched to both subscribers and each subscriber will perform a unique task. This is how the default configuration of WSO2 MB works. You will note here that it is not possible to have two subscriber clients performing the same task. For example, consider that the task that should be performed by subscriber A is time consuming and requires a lot of CPU memory. In such a situation, we need to be able to scale the work load of subscriber A among multiple subscriber clients. The following diagram depicts this requirement:
As shown above, what we need is to establish a single subscription where the messages received are shared by multiple subscriber clients using the round-robin method. In the default set up of WSO2 MB, this is not possible, because when there are multiple subscriber clients connecting to the topic, copies of the same messages are dispatched to all the subscriber clients. Therefore, sharing a subscription is only possible if the subscription ID can be shared by all the subscriber clients.
Shared durable subscriptions in a clustered setup
Now, lets look at how this functionality of sharing a durable topic subscription works when the brokering facility is distributed among multiple MB nodes. Consider the following scenario:
In this example, we have a cluster of 3 WSO2 MB nodes and all 3 nodes have the 'SportsNews' topic created. The following points will elaborate how this clustered setup works:
- There are multiple durable topic subscribers (Sub-1, Sub-2, Sub-3 and Sub-4) connecting to the MB cluster using a shared subscription ID (Sub1). Note that the subscribers Sub-2 and Sub-3 are connecting to the same MB node in the cluster.
There are 3 other clients (Pub-1, Pub-2 and Pub-3) publishing messages to the SportsNews topic.
When a client publishes messages to a topic, the client must connect to a particular MB node in the cluster. In the above example, publishers Pub-1, Pub-2 and Pub-3 connects to MB nodes A, B and C respectively. However, since all three nodes belong to a clustered setup, the messages published to each node are received by the slot manager of the cluster and not by the specific node to which the publisher sends the message. The slot manager then allocates all the received messages among the 3 nodes. This means that the messages published to the MB cluster can be dispatched to the subscriber clients from any one of the 3 nodes in the cluster.
All the messages published to the cluster will be evenly distributed among the subscribers, because the subscription is shared. Therefore, the total number of messages that are published to the MB cluster will equal the total number of messages that are received by all the subscribers (x1+x2+x3 = y1+y2+y3+y4).
Note that if you unsubscribe one shared topic subscriber, it will affect all other durable topic subscriptions with the same subscription ID.
Enabling shared durable topic subscription in WSO2 MB
You can enable shared topic subscriptions in WSO2 MB by following the steps given below.
- Open the
broker.xml
file stored in the<MB_HOME>/repository/conf
folder. Enable the
allowSharedTopicSubscriptions
element as shown below. Note that this property is only applicable to AMQP.<broker> <transports> <amqp enabled="true"> <allowSharedTopicSubscriptions>true</allowSharedTopicSubscriptions> </amqp> </transports> </broker>
- The JMS clients that are subscribing to the topic should create durable subscriptions using the same subscription ID. See the previous section on creating durable topics subscriptions.