Cloud Native Messaging System — NATS (Part -2)

Hemant Jain
7 min readOct 4, 2022

This article is in continuation of the Part -1 article published before.If you haven’t read it I would recommend to read it before moving on this article. Link to the article: Cloud Native Messaging System — NATS (Part -1)

What is NATS

Software applications and services need to exchange data. NATS is an infrastructure that allows such data exchange, segmented in the form of messages. We call this a “message oriented middleware”.

With NATS, application developers can:

  • Effortlessly build distributed and scalable client-server applications.
  • Store and distribute data in realtime in a general manner. This can flexibly be achieved across various environments, languages, cloud providers and on-premises systems.

NATS Client Applications

Developers use one of the NATS client libraries in their application code to allow them to publish, subscribe, request and reply between instances of the application or between completely separate applications. Those applications are generally referred to as ‘client applications’ or sometimes just as ‘clients’ throughout this manual (since from the point of view of the NATS server, they are clients).

NATS Service Infrastructure

The NATS services are provided by one or more NATS server processes that are configured to interconnect with each other and provide a NATS service infrastructure. The NATS service infrastructure can scale from a single NATS server process running on an end device (the nats-server process is less than 20 MB in size!) all the way to a public global super-cluster of many clusters spanning all major cloud providers and all regions of the world such as Synadia's NGS.

Connecting NATS Client applications to the NATS servers

To connect a NATS client application with a NATS service, and then subscribe or publish messages to subjects, it only needs to be configured with:

  1. URL: This is a string (in a URL format) that specifies the IP address and port where the NATS server(s) can be reached, and what kind of connection to establish (plain TCP, TLS, or Websocket).
  2. Authentication: It details for the application to identify itself with the NATS server(s). NATS supports multiple authentication schemes (username/password, decentralized JWT, token, TLS certificates and Nkey with challenge).

Simple messaging design

NATS makes it easy for applications to communicate by sending and receiving messages. These messages are addressed and identified by subject strings, and do not depend on network location.

Data is encoded and framed as a message and sent by a publisher. The message is received, decoded, and processed by one or more subscribers.

With this simple design, NATS lets programs share common message-handling code, isolate resources and interdependencies, and scale by easily handling an increase in message volume, whether those are service requests or stream data.

NATS Quality of service (QoS)

NATS offers multiple qualities of service, depending on whether the application uses just the Core NATS functionality or also leverages the added functionalities enabled by NATS JetStream (JetStream is built into nats-server but may not be enabled on all service infrastructures).

  • At most once QoS: Core NATS offers an at most once quality of service. If a subscriber is not listening on the subject (no subject match), or is not active when the message is sent, the message is not received. This is the same level of guarantee that TCP/IP provides. Core NATS is a fire-and-forget messaging system. It will only hold messages in memory and will never write messages directly to disk.
  • At-least / exactly once QoS: If you need higher qualities of service (at least once and exactly once), or functionalities such as persistent streaming, de-coupled flow control, and Key/Value Store, you can use NATS JetStream, which is built in to the NATS server (but needs to be enabled). Of course, you can also always build additional reliability into your client applications yourself with proven and scalable reference designs such as acks and sequence numbers.

Walkthrough Setup

We have provided Walkthroughs for you to try NATS (and JetStream) on your own. In order to follow along with the walkthroughs, you could choose one of these options:

  • The nats CLI tool must be installed, and a local NATS server must be installed (or you can use a remote server you have access to).
  • You can use Synadia’s NGS.
  • You could even use the demo server from where you installed NATS. This is accessible via nats://demo.nats.io (this is a NATS connection URL; not a browser URL. You pass it to a NATS client application).

Installing the nats CLI Tool

For MacOS:

brew tap nats-io/nats-tools
brew install nats-io/nats-tools/nats

For Arch Linux:

yay natscli

For other versions of Linux and for Windows: The .deb or .rpm files and Windows binaries (even for ARM) are available here Github Releases.

Installing the NATS server locally (if needed)

If you are going to run a server locally you need to first install it and start it. Alternatively if you already know how to use NATS on a remote server, you only need to pass the server URL to nats using the -s option or preferably create a context using nats context add, to specify the server URL(s) and credentials file containing your user JWT.

Installing the NATS server via a Package Manager

On Mac OS:

brew install nats-server

On Windows:

choco install nats-server

On Arch Linux:

yay nats-server

For other versions of Linux or other architectures, you can install a release build as shown below.

Downloading a Release Build

You can find the latest release of nats-server here

You could manually download the zip file matching your systems architecture, and unzip it. You could also use curl to download a specific version. The example below shows for example, how to download version 2.6.2 of the nats-server for Linux AMD64:

curl -L https://github.com/nats-io/nats-server/releases/download/v2.6.5/nats-server-v2.6.5-linux-amd64.zip -o nats-server.zipunzip nats-server.zip -d nats-serverArchive:  nats-server.zip
creating: nats-server-v2.6.2-linux-amd64/
inflating: nats-server-v2.6.2-linux-amd64/README.md
inflating: nats-server-v2.6.2-linux-amd64/LICENSE
inflating: nats-server-v2.6.2-linux-amd64/nats-server

and finally, copy it to the bin folder (this allows you to run the executable from anywhere in the system):

sudo cp nats-server/nats-server-v2.6.2-linux-amd64/nats-server /usr/bin

Start the NATS server (if needed)

To start a simple demonstration server locally, simply run:

nats-server(or nats-server -m 8222 if you want to enable the HTTP monitoring functionality)

When the server starts successfully, you will see the following messages:

[14524] 2022/09/25 22:53:53.525530 [INF] Starting nats-server
[14524] 2022/09/25 22:53:53.525640 [INF] Version: 2.6.1
[14524] 2022/09/25 22:53:53.525643 [INF] Git: [not set]
[14524] 2022/09/25 22:53:53.525647 [INF] Name: NDAUZCA4GR3FPBX4IFLBS4VLAETC5Y4PJQCF6APTYXXUZ3KAPBYXLACC
[14524] 2022/09/25 22:53:53.525650 [INF] ID: NDAUZCA4GR3FPBX4IFLBS4VLAETC5Y4PJQCF6APTYXXUZ3KAPBYXLACC
[14524] 2022/09/25 22:53:53.526392 [INF] Starting http monitor on 0.0.0.0:8222
[14524] 2022/09/25 22:53:53.526445 [INF] Listening for client connections on 0.0.0.0:4222
[14524] 2022/09/25 22:53:53.526684 [INF] Server is ready

The NATS server listens for client connections on TCP Port 4222.

Subject-Based Messaging

Fundamentally, NATS is about publishing and listening for messages. Both of these depend heavily on Subjects.

What is a Subject?

At its simplest, a subject is just a string of characters that form a name which the publisher and subscriber can use to find each other. It helps scope messages into streams or topics.

Characters allowed for subject names

For compatibility across clients, we recommend using ASCII characters (this may change in future).

  • Recommended characters: a to z, A to Z and 0 to 9 (names are case sensitive, and cannot contain whitespace).
  • Special characters: The period . (which is used to separate the tokens in the subject) and * and also > (the * and > are used as wildcards).
  • Reserved subject names: By convention subject names starting with a $ are reserved for system use (e.g. subject names starting with $SYS or $JS or $KV, etc...)

Subject Hierarchies

The . character is used to create a subject hierarchy. For example, a world clock application might define the following to logically group related subjects:

time.us
time.us.east
time.us.east.atlanta
time.eu.east
time.eu.warsaw

Wild Cards

NATS provides two wildcards that can take the place of one or more elements in a dot-separated subject. Subscribers can use these wildcards to listen to multiple subjects with a single subscription but Publishers will always use a fully specified subject, without the wildcard.

Matching a Single Token

The first wildcard is * which will match a single token. For example, if an application wanted to listen for eastern time zones, they could subscribe to time.*.east, which would match time.us.east and time.eu.east.

Matching Multiple Tokens

The second wildcard is > which will match one or more tokens, and can only appear at the end of the subject. For example, time.us.> will match time.us.east and time.us.east.atlanta, while time.us.* would only match time.us.east since it can't match more than one token.

Monitoring and Wire Traps

Subject to your security configuration, wildcards can be used for monitoring by creating something sometimes called a wire tap. In the simplest case you can create a subscriber for >. This application will receive all messages -- again, subject to security settings -- sent on your NATS cluster.

Mixing WildCards

The wildcard * can appear multiple times in the same subject. Both types can be used as well. For example, *.*.east.> will receive time.us.east.atlanta.

Subject Tokens

It is recommended to keep the maximum number of tokens in your subjects to a reasonable value of 16 tokens max.

--

--

Hemant Jain

Sr. SRE at Oracle, Ex-PayPal, Ex-RedHat. Professional Graduate Student interested in Cloud Computing and Advanced Big Data Processing and Optimization.