Introduction

In part 1 and part 2 I showed how you can connect to MQ AMQP channels from .Net using the Amqp.Net Lite library and how you set your own client ID.

In this post I’ll show you how to use a more advanced feature of the MQ Light API – shared subscriptions.

Shared Subscriptions

As I described in part 1, the link address is used by MQ Light to specify the topic string a consumer wishes to receive messages from.

However, when you run multiple instances of the consumer each one will get a copy of every message. This is typical pub/sub behaviour and is well suited to delivering events to many subscribers. But what if you want each message to be delivered to only 1 consumer? The way to do this is by using shared subscriptions.

The MQ Light API supports shared subscriptions, but because there is no provision in the AMQP 1.0 specification for specifying this semantic MQ Light uses a naming convention on link addresses.

You will remember from part 1 that to guarantee uniqueness among other links created by the client, MQ Light clients set the link name to:

private:<topic-string>

The link address is set to the same topic string, so our ReceiverLink constructor for a non-shared subscription looks like this:

ReceiverLink receiver = new ReceiverLink(session, "private:public", "public");

In order to join a shared subscription however, we need to make two changes to this call.

Firstly, the client needs to indicate that the address to receive messages from is a shared address, not a private one. So MQ Light uses the naming convention

share:<share-name>:<topic-string>

Secondly, because link names must be unique and because it’s possible to join several shared subscriptions using the same topic string, the link name needs to incorporate the share name as well as the topic string. For consistency with the link address, the link name used by MQ Light follows the same naming convention.

The Code

Most of the code from parts 1 and 2 can be used to test out shared subscriptions. The publishing code can be used unchanged because the publisher has no awareness of whether consumers are using shared subscriptions or not.

When it comes to the consumer we need to change the ReceiverLink constructor using the changes described above. We simply change

ReceiverLink receiver = new ReceiverLink(session, "private:public", "public");

to

ReceiverLink receiver = new ReceiverLink(session, "share:myshare:public", "share:myshare:public");

 

Now if you create a second consumer using the same share name and topic string, the 2 consumers will share the messages between them instead of both consumers getting a copy of each message.

Try running the updated application and then use runmqsc to check that the MQ subscription name is “:share:myshare:public” (note, the ‘:’ prefix is intentionally added by MQ to the beginning of the subscription name)

DISPLAY SUB(*) TOPICSTR

AMQ8096: IBM MQ subscription inquired.
 SUBID(414D5120514D34202020202020202020918F375A221DDE0D)
 SUB(:share:myshare:public) TOPICSTR(public)
AMQ8096: IBM MQ subscription inquired.
 SUBID(414D5120514D3420202020202020202008CBED592544F207)
 SUB(QM4 SYSTEM.BROKER.INTER.BROKER.COMMUNICATIONS 414D51590101000000000000000000000000000000000000 SYSTEM.BROKER.ADMIN.STREAM MQ/QM4 /StreamSupport)
 TOPICSTR(SYSTEM.BROKER.ADMIN.STREAM/MQ/QM4 /StreamSupport)
AMQ8096: IBM MQ subscription inquired.
 SUBID(414D5120514D34202020202020202020FCCAED5911267E06)
 SUB(SYSTEM.DEFAULT.SUB) TOPICSTR()

You can now scale the number of consumers up and down and each message will only be delivered to one of the consumers. This works well for scenarios where you don’t want messages to be processed multiple times. For example, product orders where each order should only be handled once.

MQ will not guarantee that messages are distributed evenly to the different consumers. In a typical scenario messages may be distributed evenly but this is based on other factors such as the AMQP link credit used by the consumers.

Next Steps?

Shared subscriptions let you scale consumers up and down without worrying about messages being processed in duplicate. If one consumer temporarily loses connectivity, other consumers will continue to process messages on that subscription. However, what happens if all of the consumers disconnect? In the next article we’ll look at making subscriptions durable so that messages aren’t lost if all of the consumers temporarily go away.

1 comment on"MQ Light messaging from Microsoft®.NET™ (Part 3)"

  1. anxiously awaiting your next post – i’m working on an event bus that is utilizing AMQPNetLite. Great stuff!

Join The Discussion

Your email address will not be published.