Exploring NATS Message Queues with Docker & Go

What is NATS?

The NATS website takes care of providing a simple description:

NATS Server is a simple, high performance open source messaging system for cloud native applications, IoT messaging, and microservices architectures.

The core of the product is written in golang with official and community clients available across a gamut of development languages. As you might expect, the official site provides a number of resources to help introduce users new to the concept and product. They also helpfully provide an official Docker image which expediates the setup, allowing us more time in the evaluation process. No only does it negate many of the pre-requisites but it also means we can have a NATS server up and running through a single command:

$ docker run -d -p 4222:4222 -p 6222:6222 -p 8222:8222 --name nats-main nats

This will pull the image from the hub if you don't already have it locally and start a single server with the exposed ports mapped to the equivalent host ports.

Build a client

There are a number of client examples in the NATS GitHub repositories. I chose Go since I have a ready made development environment, which means we can get going with a single command (Thanks to Alex Ellis for the steer).

go get github.com/nats-io/go-nats/

This will pull the go-nats repo, along with any dependencies into your go src location; in my case:

$GOPATH/src/github.com/nats-io/go-nats

Now with everything in place head over to the examples directory:

cd $GOPATH/src/github.com/nats-io/go-nats/examples

Subscribing is easy:

go run nats-sub.go <subject>

And to publish:

go run nats-pub.go <subject> <message>

In this, the simplest mode, there is importance to the order of events, as we will see shortly.

NATS Publish Subscribe

This is probably the simplest mode, described as a fire and forget mechanism. It's analogous to an aural message in that subscribers who aren't listening when the message is broadcast won't receive the message. However, everyone who is listening will get the same message - good for notifications, not so good for despatching distinct units of work.

Demonstrating NATS publish subscribe mode

Here we can see the publisher in the red window publishing messages on the subject of 'rgee0' and subsequently the messages being picked up by the three subscribers in the three light windows.

NATS Queuing

Sometimes it may be desirable to publish a message and have only one subscriber receive the message. This is where queue groups can be used. In queue groups a message is still published with a particular subject but message is removed once one subscriber belonging to a queue group has received the message. The previous principle of subscribers needing to be listening is still extant, however.
Demonstrating NATS Queuing mode Here we can see that the format of the published message is the same as the previous example but the subscribers have passed a second argument, a queue identifier, into nats-qsub.go. Now when a message is published only one of the three queue subscribers receives that message.

Further concepts

We have only begun to scratch the surface of NATS here. Clearly where units of work are being buffered, then delivery guarantees and a degree of persistence is required; this could be achieve through NATS Streaming. Similarly a degree of server-side fault tolerance and resilience might be desirable and clustering is available in this regard (also possible via Docker). These are more detailed concepts which may be worthy of dedicated future articles.

Show Comments