Deep Dive into
Thursday, May 3 16:35 - 17:10
Waldemar Quevedo / wally@nats.io
Colin Sullivan / colin@nats.io
Agenda
● Internal workings of NATS & NATS Streaming
● Highlights from the NATS Ecosystem
● Demos
NATS
NATS
● High Performance Messaging Server written in Go
⇢ originally started in Ruby with Eventmachine for CloudFoundry
● Pure PubSub on top of TCP/IP and TLS
● Simple Plain Text Protocol
⇢ makes writing clients for it much easier and fun
● Binary name is gnatsd
⇢ http://github.com/nats-io/gnatsd
The NATS Protocol
telnet demo.nats.io 4222
Connected to demo.nats.io.
INFO {"server_id":"T8NVSIWciEMgVSyFLHiDEs",...,"max_payload":1048576}
SUB hello.copenhagen 1
+OK
PUB hello.copenhagen 5
world
+OK
MSG hello.copenhagen 1 5
world
Straightforward use with telnet to interact with the NATS server
The NATS Protocol
telnet demo.nats.io 4222
Connected to demo.nats.io.
INFO {"server_id":"T8NVSIWciEMgVSyFLHiDEs",...,"max_payload":1048576}
SUB hello.* 1
+OK
PUB hello.copenhagen 5
world
+OK
MSG hello.copenhagen 1 5
world
Straightforward use with telnet to interact with the NATS server
The NATS Protocol
telnet demo.nats.io 4222
Connected to demo.nats.io.
INFO {"server_id":"T8NVSIWciEMgVSyFLHiDEs",...,"max_payload":1048576}
SUB > 1
+OK
PUB hello.copenhagen 5
world
+OK
MSG hello.copenhagen 1 5
world
Straightforward use with telnet to interact with the NATS server
The NATS Protocol
Client → Server := | PUB | SUB | UNSUB | CONNECT |
Client ← Server := | INFO | MSG | -ERR | +OK |
Client ⇆ Server := | PING | PONG |
Complete NATS protocol is only 10 commands
The NATS Clients
nc, _:= nats.Connect("nats://demo.nats.io:4222")
done := make(chan struct{})
nc.Subscribe("hello", func(m *nats.Msg){
log.Printf("[Received] %s", string(m.Data))
done <- struct{}{}
})
nc.Publish("hello", []byte("world"))
<-done
The latest features are in the Go client but there are clients available
for most platforms and are fairly simple
The NATS Server
$ gnatsd -m 8222 --logtime=false
[28110] [INF] Starting nats-server version 1.1.1
[28110] [INF] Starting http monitor on 0.0.0.0:8222
[28110] [INF] Listening for client connections on 0.0.0.0:4222
[28110] [INF] Server is ready
Server is a 7MB binary, no dependencies
Releases are in Github: https://github.com/nats-io/gnatsd/releases
Examples
Used Ports
Client
Routes
(6222)
NATS
NATSNATS
Clients
(4222)
HTTP
Client
Monitoring
(8222)
Production setup typically has the following 3 ports
NATS Clustering
For high availability, a full mesh of NATS servers can be setup
Client
Cluster
Routes
NATS
NATSNATS
Client
Client
Client
NATS Clustering
Clients can connect to any of the nodes to communicate with other
clients, the NATS cluster would then route the messages.
Client
Cluster
Routes
NATS
NATSNATS
Client
Client
Client
PUB MSG
PUB
MSG
PUB
MSG
NATS Clustering
Routing would only be done if clients showed interest in subject
Client
Cluster
Routes
NATS
NATSNATS
Client
Client
Client
PUB MSG
PUB
MSG
PUB
MSG
Setting up a NATS cluster
$ gnatsd -m 8222 -p 4222 --cluster "nats://127.0.0.1:6222"
$ gnatsd -m 8223 -p 4223 --cluster "nats://127.0.0.1:6223" 
--routes "nats://127.0.0.1:6222"
$ gnatsd -m 8224 -p 4224 --cluster "nats://127.0.0.1:6224" 
--routes "nats://127.0.0.1:6222"
A simple way to setup clustering is via the auto discovery support
Setting up a NATS cluster
$ gnatsd -m 8222 -p 4222 --cluster "nats://127.0.0.1:6222"
$ gnatsd -m 8223 -p 4223 --cluster "nats://127.0.0.1:6223" 
--routes "nats://127.0.0.1:6222"
$ gnatsd -m 8224 -p 4224 --cluster "nats://127.0.0.1:6224" 
--routes "nats://127.0.0.1:6222"
A simple way to setup clustering is via the auto discovery support
Cluster Auto Discovery
NATS
NATSNATS
172.16.0.15:4222CONNECT
INFO {“connect_urls”: [“172.16.0.15:4222”]}
Whenever a new NATS servers joins, its network location is announced...
Cluster Auto Discovery
...then members already in cluster connect as well to form the full mesh
NATS
NATSNATS
CONNECT
Cluster Auto Discovery
NATSNATS
CONNECT
INFO {“connect_urls”: [“172.16.0.15:4222”]}
Client
Its network endpoint is also gossiped to the clients already connected
NATS 172.16.0.15:4222
Cluster Auto Discovery
NATS
NATSNATS
172.16.0.15:4222
❌
INFO {“connect_urls”: [“172.16.0.15:4222”]}
Client❌
On failure, clients that are able to...
Cluster Auto Discovery
NATS
NATSNATS Client
CONNECT
automatically failover.
TLS support
INFO {“tls_required”: true}
Client
Create TCP connection
NATS
Secure connection to NATS can be setup to be enforced by the server
TLS support
Client TLS Handshake NATS
Secure connection to NATS can be setup to be enforced by the server
TLS support
CONNECT {...}
Secure connection to NATS can be setup to be enforced by the server
Client NATS
Secure NATS setup
Client
Routes TLS
(6222)
NATS
NATSNATS
Clients TLS
(4222)
HTTP
Client
Https /varz
(8222)
For a secure setup, TLS can be enabled for clients, routes, and the
monitoring endpoint as well
Resiliency
PUB hello
SUB hello
MSG hello
MSG hello
NATS
Client
Client
Client
PUB hello
NATS was developed with resiliency in mind. Keeping balance when
communicating is very important.
Resiliency: Slow Consumers
If a client is not able to consume messages the server is sending,
then it becomes a slow consumer.
PUB
hello
SUB hello
NATS
Client
Client
Client
ClientPUB hello
PUB
hello
MSG hello
MSG hello
MSG hello
Resiliency: Slow Consumers
The slow consumer is determined when the client has not been able
to consume new messages for more than 2 seconds.
PUB
hello
SUB hello
NATS
Client
Client
Client
ClientPUB hello
PUB
hello
-ERR ‘Slow Consumer’
# nats.conf
write_deadline: ‘2s’ # is default
❌
NATS
Streaming
NATS Streaming
● Layer on top of NATS which enables at-least-once delivery
⇢ Codename: STAN
● It is the complete opposite of NATS
⇢ Stateful; it has built-in persistence of messages enabling message
replay features
● Protocol is Request/Response based using Protobufs
⇢ Payload sent by clients still handled opaquely
● Binary name is nats-streaming-server
⇢ https://github.com/nats-io/nats-streaming-server
NATS ➡ NATS Streaming
NATS
Streaming
Client
NATS
NATSNATS
NATS
Streaming
Server
NATS Streaming connects to a NATS server/cluster and uses it as
it’s transport to communicate with NATS Streaming clients.
NATS ➡ NATS Streaming
NATS clients and NATS Streaming clients can all use the same cluster
NATS
Streaming
Client
NATS
NATSNATSNATS
Client
NATS
Client
NATS
Streaming
Server
NATS ➡ NATS Streaming
Since NATS Streaming uses a NATS connection, it has the same
reconnect features found in NATS.
NATS
Streaming
Client
NATS
NATSNATSNATS
Client
NATS
Client
NATS
Streaming
Server
❌ ❌
NATS ➡ NATS Streaming
Since NATS Streaming uses a NATS connection, it has the same
reconnect features found in NATS.
NATS
Streaming
Client
NATS
NATSNATSNATS
Client
NATS
Client
NATS
Streaming
Server
NATS Streaming Fault Tolerance
NATS
Streaming
Client
NATS
NATSNATS
NATS
Streaming
Server
Standby
NATS
Streaming
Server
Active
NATS
Streaming
Server
Standby
When using shared storage, the NATS Streaming server can be run in Fault
Tolerance mode so that extra servers are in standby and became active only on
active server failure.
NATS Streaming Clustering
For replication and high availability, NATS Streaming can also use the
Raft consensus algorithm.
NATS
NATSNATS
NATS
Streaming
Server
Follower
NATS
Streaming
Server
Leader
NATS
Streaming
Server
Follower
NATS
Streaming
Client
NATS Streaming Clustering
NATS
Streaming
Client
NATS
NATSNATS
NATS
Streaming
Server
‘cluster-A’
NATS
Streaming
Server
‘cluster-A’
NATS
Streaming
Server
‘cluster-A’
NATS
Streaming
Server
‘cluster-B’
NATS
Streaming
Server
‘cluster-B’
Multiple NATS Streaming clusters can coexist using the same NATS cluster
by using different names
NATS Streaming using
Embedded NATS Server
NATS
NATS
NATS
Streaming
Server
w/ NATS
NATS
Streaming
Server
w/ NATS
NATS
Streaming
Server
w/ NATS
6222
6222
6222
4222
NATS
Streaming
Client
For convenience, the NATS Streaming server embeds a NATS server by
default which can be used as its transport.
NATS
Ecosystem
Official Docker Images
● The NATS Team maintains official Docker images
⇢ NATS: https://hub.docker.com/_/nats/
⇢ NATS Streaming: https://hub.docker.com/_/nats-streaming/
● They are very lightweight, using the FROM scratch to keep
few layers
Prometheus NATS Exporter
● Officially supported by NATS team
⇢ https://github.com/nats-io/prometheus-nats-exporter
● Can be used as a sidecar to monitor the /varz metrics from a
single NATS server.
github.com/prometheus
Gloo + Envoy NATS Streaming
● Developed by the solo-io team as part of the Gloo project;
a function gateway
⇢ https://github.com/solo-io/gloo
● Gloo developed C++ clients for NATS & NATS Streaming
⇢ https://github.com/solo-io/envoy-nats-streaming
● Demo: https://www.youtube.com/watch?v=6mtvPrHfX1Q
github.com/solo-io
nRPC: like gRPC but over NATS
● Interesting project developed by the rapidloop team
⇢ https://github.com/rapidloop/nrpc
github.com/rapidloop
NATS Operator for Kubernetes
● Original contribution from Paulo Pires
⇢ https://github.com/nats-io/nats-operator
● Creates a CRD in Kubernetes which could be used to help
with the creation of NATS clusters
⇢ Current version: nats.io/v1alpha2
● Projects using it:
⇢ Kubeless NATS support
https://github.com/kubeless/kubeless/pull/689
github.com/pires
NATS Operator: Example
apiVersion: "nats.io/v1alpha2"
kind: "NatsCluster"
metadata:
name: "nats"
spec:
# Number of nodes in the cluster
size: 3
version: "1.1.0"
tls:
# Certificates to secure the NATS client connections:
serverSecret: "nats-clients-tls"
# Certificates to secure the routes.
routesSecret: "nats-routes-tls"
Thanks!
Be part of the NATS community :)
https://nats.io/community/

KubeConEU - NATS Deep Dive

  • 1.
    Deep Dive into Thursday,May 3 16:35 - 17:10 Waldemar Quevedo / wally@nats.io Colin Sullivan / colin@nats.io
  • 2.
    Agenda ● Internal workingsof NATS & NATS Streaming ● Highlights from the NATS Ecosystem ● Demos
  • 3.
  • 4.
    NATS ● High PerformanceMessaging Server written in Go ⇢ originally started in Ruby with Eventmachine for CloudFoundry ● Pure PubSub on top of TCP/IP and TLS ● Simple Plain Text Protocol ⇢ makes writing clients for it much easier and fun ● Binary name is gnatsd ⇢ http://github.com/nats-io/gnatsd
  • 5.
    The NATS Protocol telnetdemo.nats.io 4222 Connected to demo.nats.io. INFO {"server_id":"T8NVSIWciEMgVSyFLHiDEs",...,"max_payload":1048576} SUB hello.copenhagen 1 +OK PUB hello.copenhagen 5 world +OK MSG hello.copenhagen 1 5 world Straightforward use with telnet to interact with the NATS server
  • 6.
    The NATS Protocol telnetdemo.nats.io 4222 Connected to demo.nats.io. INFO {"server_id":"T8NVSIWciEMgVSyFLHiDEs",...,"max_payload":1048576} SUB hello.* 1 +OK PUB hello.copenhagen 5 world +OK MSG hello.copenhagen 1 5 world Straightforward use with telnet to interact with the NATS server
  • 7.
    The NATS Protocol telnetdemo.nats.io 4222 Connected to demo.nats.io. INFO {"server_id":"T8NVSIWciEMgVSyFLHiDEs",...,"max_payload":1048576} SUB > 1 +OK PUB hello.copenhagen 5 world +OK MSG hello.copenhagen 1 5 world Straightforward use with telnet to interact with the NATS server
  • 8.
    The NATS Protocol Client→ Server := | PUB | SUB | UNSUB | CONNECT | Client ← Server := | INFO | MSG | -ERR | +OK | Client ⇆ Server := | PING | PONG | Complete NATS protocol is only 10 commands
  • 9.
    The NATS Clients nc,_:= nats.Connect("nats://demo.nats.io:4222") done := make(chan struct{}) nc.Subscribe("hello", func(m *nats.Msg){ log.Printf("[Received] %s", string(m.Data)) done <- struct{}{} }) nc.Publish("hello", []byte("world")) <-done The latest features are in the Go client but there are clients available for most platforms and are fairly simple
  • 10.
    The NATS Server $gnatsd -m 8222 --logtime=false [28110] [INF] Starting nats-server version 1.1.1 [28110] [INF] Starting http monitor on 0.0.0.0:8222 [28110] [INF] Listening for client connections on 0.0.0.0:4222 [28110] [INF] Server is ready Server is a 7MB binary, no dependencies Releases are in Github: https://github.com/nats-io/gnatsd/releases
  • 11.
  • 12.
  • 13.
    NATS Clustering For highavailability, a full mesh of NATS servers can be setup Client Cluster Routes NATS NATSNATS Client Client Client
  • 14.
    NATS Clustering Clients canconnect to any of the nodes to communicate with other clients, the NATS cluster would then route the messages. Client Cluster Routes NATS NATSNATS Client Client Client PUB MSG PUB MSG PUB MSG
  • 15.
    NATS Clustering Routing wouldonly be done if clients showed interest in subject Client Cluster Routes NATS NATSNATS Client Client Client PUB MSG PUB MSG PUB MSG
  • 16.
    Setting up aNATS cluster $ gnatsd -m 8222 -p 4222 --cluster "nats://127.0.0.1:6222" $ gnatsd -m 8223 -p 4223 --cluster "nats://127.0.0.1:6223" --routes "nats://127.0.0.1:6222" $ gnatsd -m 8224 -p 4224 --cluster "nats://127.0.0.1:6224" --routes "nats://127.0.0.1:6222" A simple way to setup clustering is via the auto discovery support
  • 17.
    Setting up aNATS cluster $ gnatsd -m 8222 -p 4222 --cluster "nats://127.0.0.1:6222" $ gnatsd -m 8223 -p 4223 --cluster "nats://127.0.0.1:6223" --routes "nats://127.0.0.1:6222" $ gnatsd -m 8224 -p 4224 --cluster "nats://127.0.0.1:6224" --routes "nats://127.0.0.1:6222" A simple way to setup clustering is via the auto discovery support
  • 18.
    Cluster Auto Discovery NATS NATSNATS 172.16.0.15:4222CONNECT INFO{“connect_urls”: [“172.16.0.15:4222”]} Whenever a new NATS servers joins, its network location is announced...
  • 19.
    Cluster Auto Discovery ...thenmembers already in cluster connect as well to form the full mesh NATS NATSNATS CONNECT
  • 20.
    Cluster Auto Discovery NATSNATS CONNECT INFO{“connect_urls”: [“172.16.0.15:4222”]} Client Its network endpoint is also gossiped to the clients already connected NATS 172.16.0.15:4222
  • 21.
    Cluster Auto Discovery NATS NATSNATS 172.16.0.15:4222 ❌ INFO{“connect_urls”: [“172.16.0.15:4222”]} Client❌ On failure, clients that are able to...
  • 22.
    Cluster Auto Discovery NATS NATSNATSClient CONNECT automatically failover.
  • 23.
    TLS support INFO {“tls_required”:true} Client Create TCP connection NATS Secure connection to NATS can be setup to be enforced by the server
  • 24.
    TLS support Client TLSHandshake NATS Secure connection to NATS can be setup to be enforced by the server
  • 25.
    TLS support CONNECT {...} Secureconnection to NATS can be setup to be enforced by the server Client NATS
  • 26.
    Secure NATS setup Client RoutesTLS (6222) NATS NATSNATS Clients TLS (4222) HTTP Client Https /varz (8222) For a secure setup, TLS can be enabled for clients, routes, and the monitoring endpoint as well
  • 27.
    Resiliency PUB hello SUB hello MSGhello MSG hello NATS Client Client Client PUB hello NATS was developed with resiliency in mind. Keeping balance when communicating is very important.
  • 28.
    Resiliency: Slow Consumers Ifa client is not able to consume messages the server is sending, then it becomes a slow consumer. PUB hello SUB hello NATS Client Client Client ClientPUB hello PUB hello MSG hello MSG hello MSG hello
  • 29.
    Resiliency: Slow Consumers Theslow consumer is determined when the client has not been able to consume new messages for more than 2 seconds. PUB hello SUB hello NATS Client Client Client ClientPUB hello PUB hello -ERR ‘Slow Consumer’ # nats.conf write_deadline: ‘2s’ # is default ❌
  • 30.
  • 31.
    NATS Streaming ● Layeron top of NATS which enables at-least-once delivery ⇢ Codename: STAN ● It is the complete opposite of NATS ⇢ Stateful; it has built-in persistence of messages enabling message replay features ● Protocol is Request/Response based using Protobufs ⇢ Payload sent by clients still handled opaquely ● Binary name is nats-streaming-server ⇢ https://github.com/nats-io/nats-streaming-server
  • 32.
    NATS ➡ NATSStreaming NATS Streaming Client NATS NATSNATS NATS Streaming Server NATS Streaming connects to a NATS server/cluster and uses it as it’s transport to communicate with NATS Streaming clients.
  • 33.
    NATS ➡ NATSStreaming NATS clients and NATS Streaming clients can all use the same cluster NATS Streaming Client NATS NATSNATSNATS Client NATS Client NATS Streaming Server
  • 34.
    NATS ➡ NATSStreaming Since NATS Streaming uses a NATS connection, it has the same reconnect features found in NATS. NATS Streaming Client NATS NATSNATSNATS Client NATS Client NATS Streaming Server ❌ ❌
  • 35.
    NATS ➡ NATSStreaming Since NATS Streaming uses a NATS connection, it has the same reconnect features found in NATS. NATS Streaming Client NATS NATSNATSNATS Client NATS Client NATS Streaming Server
  • 36.
    NATS Streaming FaultTolerance NATS Streaming Client NATS NATSNATS NATS Streaming Server Standby NATS Streaming Server Active NATS Streaming Server Standby When using shared storage, the NATS Streaming server can be run in Fault Tolerance mode so that extra servers are in standby and became active only on active server failure.
  • 37.
    NATS Streaming Clustering Forreplication and high availability, NATS Streaming can also use the Raft consensus algorithm. NATS NATSNATS NATS Streaming Server Follower NATS Streaming Server Leader NATS Streaming Server Follower NATS Streaming Client
  • 38.
  • 39.
    NATS Streaming using EmbeddedNATS Server NATS NATS NATS Streaming Server w/ NATS NATS Streaming Server w/ NATS NATS Streaming Server w/ NATS 6222 6222 6222 4222 NATS Streaming Client For convenience, the NATS Streaming server embeds a NATS server by default which can be used as its transport.
  • 40.
  • 41.
    Official Docker Images ●The NATS Team maintains official Docker images ⇢ NATS: https://hub.docker.com/_/nats/ ⇢ NATS Streaming: https://hub.docker.com/_/nats-streaming/ ● They are very lightweight, using the FROM scratch to keep few layers
  • 42.
    Prometheus NATS Exporter ●Officially supported by NATS team ⇢ https://github.com/nats-io/prometheus-nats-exporter ● Can be used as a sidecar to monitor the /varz metrics from a single NATS server. github.com/prometheus
  • 43.
    Gloo + EnvoyNATS Streaming ● Developed by the solo-io team as part of the Gloo project; a function gateway ⇢ https://github.com/solo-io/gloo ● Gloo developed C++ clients for NATS & NATS Streaming ⇢ https://github.com/solo-io/envoy-nats-streaming ● Demo: https://www.youtube.com/watch?v=6mtvPrHfX1Q github.com/solo-io
  • 44.
    nRPC: like gRPCbut over NATS ● Interesting project developed by the rapidloop team ⇢ https://github.com/rapidloop/nrpc github.com/rapidloop
  • 45.
    NATS Operator forKubernetes ● Original contribution from Paulo Pires ⇢ https://github.com/nats-io/nats-operator ● Creates a CRD in Kubernetes which could be used to help with the creation of NATS clusters ⇢ Current version: nats.io/v1alpha2 ● Projects using it: ⇢ Kubeless NATS support https://github.com/kubeless/kubeless/pull/689 github.com/pires
  • 46.
    NATS Operator: Example apiVersion:"nats.io/v1alpha2" kind: "NatsCluster" metadata: name: "nats" spec: # Number of nodes in the cluster size: 3 version: "1.1.0" tls: # Certificates to secure the NATS client connections: serverSecret: "nats-clients-tls" # Certificates to secure the routes. routesSecret: "nats-routes-tls"
  • 47.
    Thanks! Be part ofthe NATS community :) https://nats.io/community/