NATS Logo by Example

Simple Leafnode in Topologies

This example showcases the most minimal leafnode configuration and how clients interact.

CLI Go Python Deno Node Rust C# Java Ruby Elixir Crystal C
Jump to the output or the recording
$ nbe run topologies/simple-leafnode/cli
View the source code or learn how to run this example yourself

Code

#!/bin/sh


set -xeuo pipefail

For this example, we are going to have a service connected to the main server and then another client send a request via a connection to the leaf node.

NATS_MAIN_URL="nats://0.0.0.0:4222"
NATS_LEAF_URL="nats://0.0.0.0:4223"

The nats CLI provides a way to manage different contexts by name. We save two, one for the main server and one for the leaf node. In subsequent calls to nats, we can pass the --context option to refer to either server.

nats context save main \
  --server "$NATS_MAIN_URL" \


nats context save leaf \
  --server "$NATS_LEAF_URL"

Create the most basic server config which enables leaf node connections.

echo 'Creating the main server conf...'
cat <<- EOF > main.conf
port: 4222
leafnodes: {
  port: 7422
}
EOF

The second config is for the leaf node itself. This needs to define the leaf node remotes which is the main server it will be connecting to.

echo 'Creating the leaf node conf...'
cat <<- EOF > leaf.conf
port: 4223
leafnodes: {
  remotes: [
    {url: "nats-leaf://0.0.0.0:7422"}
  ]
}
EOF

Start the main server first.

nats-server -c main.conf 2> /dev/null &
MAIN_PID=$!


sleep 1

Now we can start the leaf node which uses the credentials for the remote connection.

nats-server -c leaf.conf 2> /dev/null &
LEAF_PID=$!


sleep 1

Here we create a simple service which is connected via the main server. We will put this in the background since this will block while serving.

nats --context main reply 'greet' 'hello from main' &
SERVICE_PID=$!

Tiny sleep to ensure the service is connected.

sleep 1

Let’s try out a request that is performed by a client connecting to the leaf node. As expected, this will get routed to the service connected to to the main server.

nats --context leaf request 'greet' ''

Let’s start another service connected to the leaf node servicing the same subject.

nats --context leaf reply 'greet' 'hello from leaf' &
SERVICE2_PID=$!

NATS is smart enough to route messages to closest service relative to where the client request comes from.

nats --context leaf request 'greet' ''
nats --context leaf request 'greet' ''
nats --context leaf request 'greet' ''

If we remove the leaf-base service, it will fallback to the main service.

kill $SERVICE2_PID
nats --context leaf request 'greet' ''

Finally stop the service and servers.

kill $SERVICE_PID
kill $LEAF_PID
kill $MAIN_PID

Output

Network 048d641d_default  Creating
Network 048d641d_default  Created
             _             _               
 _ __   __ _| |_ ___      | |__   _____  __
| '_ \ / _` | __/ __|_____| '_ \ / _ \ \/ /
| | | | (_| | |_\__ \_____| |_) | (_) >  < 
|_| |_|\__,_|\__|___/     |_.__/ \___/_/\_\
                                           
nats-box v0.12.0
+ NATS_MAIN_URL=nats://0.0.0.0:4222
+ NATS_LEAF_URL=nats://0.0.0.0:4223
+ nats context save main --server nats://0.0.0.0:4222
NATS Configuration Context "main"

      Server URLs: nats://0.0.0.0:4222
             Path: /nsc/.config/nats/context/main.json

+ nats context save leaf --server nats://0.0.0.0:4223
NATS Configuration Context "leaf"

      Server URLs: nats://0.0.0.0:4223
             Path: /nsc/.config/nats/context/leaf.json

+ echo 'Creating the main server conf...'
Creating the main server conf...
+ cat
+ echo 'Creating the leaf node conf...'
Creating the leaf node conf...
+ cat
+ MAIN_PID=34
+ sleep 1
+ nats-server -c main.conf
+ LEAF_PID=44
+ sleep 1
+ nats-server -c leaf.conf
+ SERVICE_PID=54
+ sleep 1
+ nats --context main reply greet 'hello from main'
12:12:26 Listening on "greet" in group "NATS-RPLY-22"
+ nats --context leaf request greet 
12:12:27 Sending request on "greet"


12:12:27 [#0] Received on subject "greet":
12:12:27 Received with rtt 732.112µs
hello from main

+ SERVICE2_PID=76
+ nats --context leaf request greet 
+ nats --context leaf reply greet 'hello from leaf'
12:12:27 Sending request on "greet"
12:12:27 [#1] Received on subject "greet":


12:12:27 Received with rtt 3.891391ms
hello from main

12:12:27 Listening on "greet" in group "NATS-RPLY-22"
+ nats --context leaf request greet 
12:12:28 Sending request on "greet"
12:12:28 [#0] Received on subject "greet":


12:12:28 Received with rtt 591.02µs
hello from leaf

+ nats --context leaf request greet 
12:12:28 Sending request on "greet"


12:12:28 [#1] Received on subject "greet":
12:12:28 Received with rtt 492.585µs
hello from leaf

+ kill 76
+ nats --context leaf request greet 
12:12:28 Sending request on "greet"


12:12:28 [#2] Received on subject "greet":
12:12:28 Received with rtt 631.337µs
hello from main

+ kill 54
+ kill 44
+ kill 34

Recording

Note, playback is half speed to make it a bit easier to follow.