Clustering
NATS Server Clustering
NATS supports running each server in clustered mode. You can cluster servers together for high volume messaging systems and resiliency and high availability.
NATS servers achieve this by gossiping about and connecting to, all of the servers they know, thus dynamically forming a full mesh. Once clients connect or re-connect to a particular server, they are informed about current cluster members. Because of this behavior, a cluster can grow, shrink and self heal. The full mesh does not necessarily have to be explicitly configured either.
Note that NATS clustered servers have a forwarding limit of one hop. This means that each nats-server
instance will only forward messages that it has received from a client to the immediately adjacent nats-server
instances to which it has routes. Messages received from a route will only be distributed to local clients.
For the cluster to successfully form a full mesh and NATS to function as intended and described throughout the documentation - temporary errors permitting - it is necessary that servers can connect to each other and that clients can connect to each server in the cluster.
Cluster URLs
In addition to a port to listen for clients, nats-server
listens on a "cluster" URL (the -cluster
option). Additional nats-server
servers can then add that URL to their -routes
argument to join the cluster. These options can also be specified in a config file, but only the command-line version is shown in this overview for simplicity.
Running a Simple Cluster
Here is a simple cluster running on the same machine:
Server A - the 'seed server'
Server B
Check the output of the server for the selected client and route ports.
Server C
Check the output of the server for the selected client and route ports.
Each server has a client and cluster port specified. Servers with the routes option establish a route to the seed server. Because the clustering protocol gossips members of the cluster, all servers are able to discover other server in the cluster. When a server is discovered, the discovering server will automatically attempt to connect to it in order to form a full mesh. Typically only one instance of the server will run per machine, so you can reuse the client port (4222) and the cluster port (4248), and simply the route to the host/port of the seed server.
Similarly, clients connecting to any server in the cluster will discover other servers in the cluster. If the connection to the server is interrupted, the client will attempt to connect to all other known servers.
There is no explicit configuration for seed server. They simply serve as the starting point for server discovery by other members of the cluster as well as clients. As such these are the servers that clients have in their list of connect urls and cluster members have in their list of routes. They reduce configuration as not every server needs to be in these lists. But the ability for other server and clients to successfully connect depends on seed server running. If multiple seed server are used, they make use of the routes option as well, so they can establish routes to one another.
Command Line Options
The following cluster options are supported:
When a NATS server routes to a specified URL, it will advertise its own cluster URL to all other servers in the route effectively creating a routing mesh to all other servers.
Note: when using the -routes
option, you must also specify a -cluster
option.
Clustering can also be configured using the server config file.
Three Server Cluster Example
The following example demonstrates how to run a cluster of 3 servers on the same host. We will start with the seed server and use the -D
command line parameter to produce debug information.
Alternatively, you could use a configuration file, let's call it seed.conf
, with a content similar to this:
And start the server like this:
This will produce an output similar to:
It is also possible to specify the hostname and port independently. At the minimum, the port is required. If you leave the hostname off it will bind to all the interfaces ('0.0.0.0').
Now let's start two more servers, each one connecting to the seed server.
When running on the same host, we need to pick different ports for the client connections -p
, and for the port used to accept other routes -cluster
. Note that -routes
points to the -cluster
address of the seed server (localhost:4248
).
Here is the log produced. See how it connects and registers a route to the seed server (...GzM
).
From the seed's server log, we see that the route is indeed accepted:
Finally, let's start the third server:
Again, notice that we use a different client port and cluster address, but still point to the same seed server at the address nats://localhost:4248
:
First a route is created to the seed server (...IOW
) and after that, a route from ...3PK
- which is the ID of the second server - is accepted.
The log from the seed server shows that it accepted the route from the third server:
And the log from the second server shows that it connected to the third.
At this point, there is a full mesh cluster of NATS servers.
Testing the Cluster
Now, the following should work: make a subscription to the first server (port 4222). Then publish to each server (ports 4222, 5222, 6222). You should be able to receive messages without problems.
Testing server A
Testing server B
Testing server C
Testing using seed (i.e. A, B and C) server URLs
Last updated