SlideShare a Scribd company logo
Simple and Scalable
Microservices
NATS and the Docker tooling
+
Waldemar Quevedo / @wallyqs
Docker SF Meetup, Oct 2016
1 . 1
2 . 1
ABOUT
Waldemar Quevedo /
So ware Developer at in SF
Development of the Apcera Platform
Past: PaaS DevOps at Rakuten in Tokyo
NATS client maintainer (Ruby, Python)
@wallyqs
Apcera
3 . 1
ABOUT THIS TALK
What is NATS
Features from NATS
NATS + Docker
4 . 1
What is NATS?
4 . 2
4 . 3
NATS
High Performance Messaging System
Created by
First written in in 2010
Originally built for Cloud Foundry
Rewritten in in 2012
Better performance
Open Source, MIT License
Used by Apcera, Ericsson, HTC, GE, Baidu
Derek Collison
Ruby
Go
https://github.com/nats-io
4 . 4
NATS
Design constrained to keep it as operationally simple and
reliable as possible while still being both performant and
scalable.
4 . 5
Acts as an always available dial-tone
4 . 6
It's Fast
single byte message
Around 10M messages/second
4 . 7
4 . 8
and Simple
4 . 9
DESIGN
Concise feature set (pure PubSub!)
No built-in persistence of messages
No exactly-once-delivery promises either
Those concerns are simplified away from NATS
→ NATS Streaming
4 . 10
DESIGN
TCP/IP based
Plain text protocol
fire and forget
at most once
4 . 11
Very simple protocol
telnet demo.nats.io 4222
sub hello 1
+OK
pub hello 5
world
+OK
MSG hello 1 5
world
ping
PONG
nats.io/documentation/nats-protocol
4 . 12
Demo
4 . 13
Clients
4 . 14
GO
nc, err := nats.Connect()
// ...
nc.Subscribe("hello", func(m *nats.Msg){
fmt.Printf("[Received] %s", m.Data)
})
nc.Publish("hello", []byte("world"))
4 . 15
RUBY
require 'nats/client'
NATS.start do |nc|
nc.subscribe("hello") do |msg|
puts "[Received] #{msg}"
end
nc.publish("hello", "world")
end
4 . 16
PYTHON (ASYNCIO)
yield from nc.connect()
@asyncio.coroutine
def handler(msg):
print("[Received] {data}".format(
data=msg.data.decode()))
# Coroutine based subscriber
yield from nc.subscribe("foo", cb=handler)
yield from nc.publish("foo", "bar")
4 . 17
NODE.JS
var nats = require('nats').connect();
// Simple Publisher
nats.publish('foo', 'Hello World!');
// Simple Subscriber
nats.subscribe('foo', function(msg) {
console.log('[Received] ' + msg);
});
4 . 18
C
natsConnection_Publish(nc,"foo",data,5);
natsConnection_Subscribe(&sub,nc,"foo",onMsg, NULL);
void
onMsg(natsConnection *nc, natsSubscription *sub,
natsMsg *msg, void *closure)
{
printf("[Received] %.*sn",
natsMsg_GetData(msg));
// ...
}
4 . 19
C#
using (ISyncSubscription s = c.SubscribeSync("foo"))
{
for (int i = 0; i < 10; i++)
{
Msg m = s.NextMessage();
System.Console.WriteLine("[Received] " + m);
}
}
4 . 20
JAVA
// Simple Publisher
nc.publish("foo", "Hello World".getBytes());
// Simple Async Subscriber
nc.subscribe("foo", m -> {
System.out.println("[Received] %sn",
new String(m.getData()));
});
Many more available!
C C# Java
Python NGINX Go
Node.js Elixir Ruby
PHP Erlang Rust
Haskell Scala Perl
( italics → community contributed)
4 . 21
4 . 22
Great community!
Growing ecosystem
nats.io/community
4 . 23
Connectors
4 . 24
Community contributed dashboards
github.com/cmfatih/natsboard
4 . 25
Docker Hub activity from NATS users
4 . 26
Docker Hub activity from NATS users
4 . 27
Docker Store (Beta)
4 . 28
5 . 1
NATS Features
5 . 2
FEATURES
Pure PubSub based Request/Reply
Subject routing with wildcards
Authorization
Distribution queue groups for balancing
Cluster mode for HA
Auto discovery of topology
/varzstyle monitoring
Secure TLS connections with certificates
5 . 3
REQUEST/REPLY
It is pure PubSub based using and by
signaling in the subject:
NATS unique identifiers
limited interest
SUB _INBOX.y1JxglDi76shQQIhPbTDme 2
UNSUB 2 1
PUB help _INBOX.y1JxglDi76shQQIhPbTDme 6
please
tells the server to unsubscribe from subscription with sid=2
a er getting 1 message before sending a request on the
helpsubject.
5 . 4
REQUEST/REPLY
If another subscriber is connected and interested in the
helpsubject, it will then receive a message with that inbox.
SUB help 90
# Message received from server
MSG help 90 _INBOX.y1JxglDi76shQQIhPbTDme 6
please
# Use the inbox to reply back
PUB _INBOX.y1JxglDi76shQQIhPbTDme 11
I can help!
5 . 5
REQUEST/REPLY
Finally, original requestor will be receiving the message:
SUB _INBOX.y1JxglDi76shQQIhPbTDme 2
UNSUB 2 1
PUB help _INBOX.y1JxglDi76shQQIhPbTDme 6
please
MSG _INBOX.y1JxglDi76shQQIhPbTDme 2 11
I can help!
5 . 6
REQUEST/REPLY
NATS clients libraries have helpers for generating the unique
inboxes which act as ephemeral subscriptions:
nats.NewInbox()
// _INBOX.y1JxglDi76shQQIhPbTDme
Used internally when making a Request:
nc, _ := nats.Connect(nats.DefaultURL)
t := 250*time.Millisecond
// Request sets to AutoUnsubscribe after 1 response
msg, err := nc.Request("help", []byte("please"), t)
if err == nil {
fmt.Println(string(msg.Data))
// => I can help!
}
REQUEST/REPLY → LOWEST LATENCY
Result of publishing a request to all nodes with limited
interest means we are getting the fastest reply back:
5 . 7
REQUEST/REPLY → LOWEST LATENCY
Result of publishing a request to all nodes with limited
interest means we are getting the fastest reply back:
5 . 85 . 9
SUBJECTS ROUTING
Wildcards: *
SUB foo.*.bar 90
PUB foo.hello.bar 2
hi
MSG foo.hello.bar 90 2
hi
e.g. subscribe to all requests being made on the demo site:
telnet demo.nats.io 4222
INFO {"auth_required":false,"version":"0.9.4",...}
SUB _INBOX.* 99
MSG _INBOX.y1JxglDi76shQQIhPbTDme 99 11
I can help!
5 . 10
SUBJECTS ROUTING
Full wildcard: >
SUB hello.> 90
PUB hello.world.again 2
hi
MSG hello.world.again 90 2
hi
e.g. subscribe to all subjects and see whole traffic going
through the server:
telnet demo.nats.io 4222
INFO {"auth_required":false,"version":"0.9.4",...}
sub > 1
+OK
5 . 11
DISTRIBUTION QUEUES
Balance work among nodes randomly
5 . 12
DISTRIBUTION QUEUES
Balance work among nodes randomly
5 . 13
DISTRIBUTION QUEUES
Balance work among nodes randomly
5 . 14
DISTRIBUTION QUEUES
Service A workers subscribe to service.Aand create
workersdistribution queue group for balancing the work.
nc, _ := nats.Connect(nats.DefaultURL)
// SUB service.A workers 1rn
nc.QueueSubscribe("service.A", "workers",
func(m *nats.Msg) {
nc.Publish(m.Reply, []byte("hi!"))
})
5 . 15
DISTRIBUTION QUEUES
Note: NATS does not assume the audience!
5 . 16
DISTRIBUTION QUEUES
All interested subscribers receive the message!
5 . 17
CLUSTERING
Avoid SPOF on NATS by assembling a full mesh cluster
5 . 18
CLUSTERING
Clients reconnect logic is triggered
5 . 19
CLUSTERING
Connecting to a NATS cluster of 2 nodes explicitly
srvs := "nats://10.240.0.1:4222,nats://10.240.0.2:4223"
nc, _ := nats.Connect(srvs)
NOTE: NATS servers have a forwarding limit of one hop.
Each server will only forward a message that it has
received from a client to all connected servers that
expressed interest in the message's published subject.
A message received from a route will only be distributed
to local clients.
5 . 20
CLUSTERING
Reconnect and disconnect handlers can be useful to trace
connection failures.
nc, err := nats.Connect(uri,
nats.DisconnectHandler(func(nc *nats.Conn) {
fmt.Printf("Got disconnected!n")
}),
nats.ReconnectHandler(func(nc *nats.Conn) {
fmt.Printf("Got reconnected to %v!n",
nc.ConnectedUrl())
}),
nats.ClosedHandler(func(nc *nats.Conn) {
fmt.Printf("Connection closed. Reason: %qn",
nc.LastError())
}),
)
5 . 21
CLUSTER AUTO DISCOVERY
Since release, topology can be discovered
dynamically by clients!
v0.9.2
We can start with a single node…
5 . 22
Then have new nodes join the cluster…
5 . 23
As new nodes join, server announces INFOto clients.
5 . 24
Clients auto reconfigure to be aware of new nodes.
5 . 25
Clients auto reconfigure to be aware of new nodes.
5 . 26
Now fully connected!
5 . 27
On failure, clients reconnect to an available node.
5 . 28
5 . 29
MONITORING
style monitoring endpoint available for inspecting the
internal state of the server.
/varz
Other available endpoints:
- Info of clients connected to this server/connz
- Subscriptions metrics/subsz
- Cluster routes/routez
5 . 30
MONITORING: EXAMPLES
Gathering connections metrics from demo:
curl demo.nats.io:8222/varz | grep connections
Result:
"max_connections": 65536,
"connections": 25,
"total_connections": 12429,
5 . 31
MONITORING: EXAMPLES
Gathering metrics regarding languages used when
connecting to demo
curl demo.nats.io:8222/connz?subsz=1 | grep lang | sort | uniq -c
Result:
10 "lang": "go",
7 "lang": "node",
8 "lang": "python2",
5 . 32
MONITORING
polls from these endpoints providing a terminal UInats-top
5 . 33
TLS
Supported for client and route connections, and for
monitoring.
https_port: 6443
tls {
cert_file: "./configs/certs/server-cert.pem"
key_file: "./configs/certs/server-key.pem"
ca_file: "./configs/certs/ca.pem"
# Require client certificates
verify: true
}
5 . 34
CLUSTER TLS
Securing route connections with TLS
cluster {
listen: 0.0.0.0:6222
tls {
# Route cert
cert_file: "./configs/certs/srva-cert.pem"
# Private key
key_file: "./configs/certs/srva-key.pem"
# Optional certificate authority verifying routes
# Required when we have self-signed CA, etc.
ca_file: "./configs/certs/ca.pem"
}
}
5 . 35
SUBJECTS AUTHORIZATION
PubSub on certain subjects can be disallowed in the server's
configuration:
authorization {
admin = { publish = ">", subscribe = ">" }
requestor = {
publish = ["req.foo", "req.bar"]
subscribe = "_INBOX.*"
}
users = [
{user: alice, password: foo, permissions: $admin}
{user: bob, password: bar, permissions: $requestor}
]
}
5 . 36
SUBJECTS AUTHORIZATION
Clients are not allowed to publish on _SYS(reserved):
PUB _SYS.foo 2
hi
-ERR 'Permissions Violation for Publish to "_SYS.foo"'
6 . 1
NATS and the Docker tooling
6 . 2
THE NATS DOCKER IMAGE
Small binary → Lightweight Docker image
No deployment dependencies
6 . 3
2-STEP BUILD PROCESS
6 . 4
FIRST STEP: COMPILE
github.com/nats-io/gnatsd/Dockerfile
FROM golang:1.6.3
MAINTAINER Derek Collison <derek@apcera.com>
COPY . /go/src/github.com/nats-io/gnatsd
WORKDIR /go/src/github.com/nats-io/gnatsd
RUN CGO_ENABLED=0 go install ...(elided)
EXPOSE 4222 8222
ENTRYPOINT ["gnatsd"]
CMD ["--help"]
6 . 5
SECOND STEP: FROM SCRATCH
github.com/nats-io/nats-docker/Dockerfile
FROM scratch
COPY gnatsd /gnatsd
COPY gnatsd.conf /gnatsd.conf
EXPOSE 4222 6222 8222
ENTRYPOINT ["/gnatsd", "-c", "/gnatsd.conf"]
CMD []
6 . 6
THE NATS DOCKER IMAGE
By default it is exposing these ports:
# Clients, Cluster and Monitoring ports
EXPOSE 4222 6222 8222
- Clients will be connecting against this port4222
- Port used for the cluster routes6222
- HTTP Monitoring endpoint8222
6 . 7
USING NATS + DOCKER
All examples can be found at
github.com/wallyqs/nats-docker-examples
6 . 8
EXAMPLE: SINGLE NODE
API Server which receives HTTP requests and communicates
internally through NATS to a pool of workers.
6 . 96 . 10
EXAMPLE: CLUSTERED SETUP
API Server which receives HTTP requests and communicates
internally through NATS to a pool of workers.
6 . 11
LOCAL NATS CLUSTER VIA DOCKER COMPOSE
Docker Compose tooling comes in handy here for doing
development as it helps us in assembling NATS clusters
locally.
version: "2"
networks:
nats-network: {}
services:
nats-server-A:
networks: ["nats-network"]
image: "nats:0.9.4"
entrypoint: "/gnatsd --routes nats://nats-server-B:6222,nats://nats-server-C:6222 --cluster nats://0.0.0.0:6222"
nats-server-B:
networks: ["nats-network"]
image: "nats:0.9.4"
entrypoint: "/gnatsd --routes nats://nats-server-A:6222,nats://nats-server-C:6222 --cluster nats://0.0.0.0:6222"
nats-server-C:
networks: ["nats-network"]
image: "nats:0.9.4"
entrypoint: "/gnatsd --routes nats://nats-server-A:6222,nats://nats-server-B:6222 --cluster nats://0.0.0.0:6222"
NATS + Docker Compose Demo
6 . 12
6 . 13
DOCKER SWARM BASED NATS CLUSTER
Auto discovery becomes helpful in this context, we can
assemble one with the following commands.
docker network create --driver overlay nats-cluster-example
docker service create --network nats-cluster-example --name nats-A 
nats:0.9.4 -cluster nats://0.0.0.0:6222
docker service create --network nats-cluster-example --name nats-B 
nats:0.9.4 -routes nats://nats-A:6222 
-cluster nats://0.0.0.0:6222
docker service create --network nats-cluster-example --name nats-C 
nats:0.9.4 -routes nats://nats-A:6222,nats://nats-B:6222 
-cluster nats://0.0.0.0:6222
6 . 14
DOCKER SWARM BASED NATS CLUSTER
Even easier: just use same configuration in all nodes.
for node in A B C; do
docker service create --network nats-cluster-example 
--name nats-$node nats:0.9.4 
-routes nats://nats-A:6222 
-cluster nats://0.0.0.0:6222
done
Initial server becomes the seed server, ignoring route to self.
NATS + Docker Swarm mode Demo
6 . 15
7 . 1
Summary
NATS is a simple, fast and reliable solution for the internal
communication of a distributed system.
Docker flexible tooling is a good complement for building
NATS based applications.
7 . 2
7 . 3
BONUS: NATS STREAMING
NATS Streaming recently became an official image too!
It is a layer on top of NATS totalling in ~10MB.
Further info: github.com/nats-io/nats-streaming-server
8 . 1
THANKS!
/github.com/nats-io @nats_io
Play with the demo site!
telnet demo.nats.io 4222

More Related Content

PDF
GopherFest 2017 - Adding Context to NATS
PDF
The Zen of High Performance Messaging with NATS (Strange Loop 2016)
PDF
Debugging Network Issues
PDF
NATS: Simple, Secure and Scalable Messaging For the Cloud Native Era
PDF
Micro on NATS - Microservices with Messaging
PDF
Microservices Meetup San Francisco - August 2017 Talk on NATS
PDF
Simple Solutions for Complex Problems - Boulder Meetup
PDF
OSMC 2017 | SNMP explained by Rob Hassing
GopherFest 2017 - Adding Context to NATS
The Zen of High Performance Messaging with NATS (Strange Loop 2016)
Debugging Network Issues
NATS: Simple, Secure and Scalable Messaging For the Cloud Native Era
Micro on NATS - Microservices with Messaging
Microservices Meetup San Francisco - August 2017 Talk on NATS
Simple Solutions for Complex Problems - Boulder Meetup
OSMC 2017 | SNMP explained by Rob Hassing

What's hot (13)

PDF
NATS: Control Flow for Distributed Systems
PDF
KubeConEU - NATS Deep Dive
PDF
NATS for Rubyists - Tokyo Rubyist Meetup
PDF
GopherCon 2017 - Writing Networking Clients in Go: The Design & Implementati...
PDF
OSMC 2017 | Monitoring MySQL with Prometheus and Grafana by Julien Pivotto
PPTX
NATS for Modern Messaging and Microservices
PDF
Easy, Secure, and Fast: Using NATS.io for Streams and Services
PDF
Kubernetes networking - basics
PDF
KubeCon NA 2018 - NATS Deep Dive: The Evolution of NATS
PPTX
Commication Framework in OpenStack
PPTX
Docker Swarm secrets for creating great FIWARE platforms
PPTX
Connect Everything with NATS - Cloud Expo Europe
PDF
Preview of Apache Pulsar 2.5.0
NATS: Control Flow for Distributed Systems
KubeConEU - NATS Deep Dive
NATS for Rubyists - Tokyo Rubyist Meetup
GopherCon 2017 - Writing Networking Clients in Go: The Design & Implementati...
OSMC 2017 | Monitoring MySQL with Prometheus and Grafana by Julien Pivotto
NATS for Modern Messaging and Microservices
Easy, Secure, and Fast: Using NATS.io for Streams and Services
Kubernetes networking - basics
KubeCon NA 2018 - NATS Deep Dive: The Evolution of NATS
Commication Framework in OpenStack
Docker Swarm secrets for creating great FIWARE platforms
Connect Everything with NATS - Cloud Expo Europe
Preview of Apache Pulsar 2.5.0
Ad

Viewers also liked (19)

PDF
eTAT journal 1/2555
PDF
TAT Review Magazine 2/2016
PDF
Catálogo Vestuarios
PPTX
Escola de mídia tv re ação
PDF
Serie Nerea by Ortus Fitness
PDF
TAT TOURISM JOURNAL 2/2013
PDF
eTAT journal 3/2554
PDF
TAT TOURISM JOURNAL 4/2013
PPT
Prezentacja Dish stories
PPTX
Final editted ppt terminolgy of advertising
PPTX
Ignacy Łukaszewicz
PPTX
Belleza al limite
PPTX
Antonio e vitoria
PPT
Advance transferable skills
PDF
Abonamenty Medyczne dla wybranego personelu i bliskich w firmie
PDF
Catalogo bermuda well fit
PPTX
Praca na dish_stories_,,tosty,,[1]
KEY
Poisonwood bible project
PPTX
Polish inventor by Justyna
eTAT journal 1/2555
TAT Review Magazine 2/2016
Catálogo Vestuarios
Escola de mídia tv re ação
Serie Nerea by Ortus Fitness
TAT TOURISM JOURNAL 2/2013
eTAT journal 3/2554
TAT TOURISM JOURNAL 4/2013
Prezentacja Dish stories
Final editted ppt terminolgy of advertising
Ignacy Łukaszewicz
Belleza al limite
Antonio e vitoria
Advance transferable skills
Abonamenty Medyczne dla wybranego personelu i bliskich w firmie
Catalogo bermuda well fit
Praca na dish_stories_,,tosty,,[1]
Poisonwood bible project
Polish inventor by Justyna
Ad

Similar to NATS + Docker meetup talk Oct - 2016 (20)

PDF
The Zen of High Performance Messaging with NATS
PDF
The Zen of High Performance Messaging with NATS
PDF
Simple, Secure, Scalable Messaging for the Cloud Native Era - AllThingsOpen 2...
PDF
NATS: Simple, Secure, and Scalable Messaging for the Cloud Native Era
PDF
OSCON: Building Cloud Native Apps with NATS
PDF
KubeCon NA 2019 Keynote | NATS - Past, Present, and the Future
PDF
NATS.io Meetup October - Community Update
PDF
Nats.io meetup october 2015 - Community Update
PPTX
NATS for Modern Messaging and Microservices
PDF
Deploy Secure and Scalable Services Across Kubernetes Clusters with NATS
PDF
Writing Networking Clients in Go - GopherCon 2017 talk
PDF
NATS Connector Framework - Boulder Meetup
PDF
NATS: A Cloud Native Messaging System
PDF
NATS - A new nervous system for distributed cloud platforms
PDF
Using NATS for Control Flow in Distributed Systems
PDF
NATS & IoT
PDF
Simple Solutions for Complex Problems - Boulder Meetup
PDF
Simple Solutions for Complex Problems
PDF
Simple Solutions for Complex Problems
PDF
GoSF: Decoupling Services from IP networks with NATS
The Zen of High Performance Messaging with NATS
The Zen of High Performance Messaging with NATS
Simple, Secure, Scalable Messaging for the Cloud Native Era - AllThingsOpen 2...
NATS: Simple, Secure, and Scalable Messaging for the Cloud Native Era
OSCON: Building Cloud Native Apps with NATS
KubeCon NA 2019 Keynote | NATS - Past, Present, and the Future
NATS.io Meetup October - Community Update
Nats.io meetup october 2015 - Community Update
NATS for Modern Messaging and Microservices
Deploy Secure and Scalable Services Across Kubernetes Clusters with NATS
Writing Networking Clients in Go - GopherCon 2017 talk
NATS Connector Framework - Boulder Meetup
NATS: A Cloud Native Messaging System
NATS - A new nervous system for distributed cloud platforms
Using NATS for Control Flow in Distributed Systems
NATS & IoT
Simple Solutions for Complex Problems - Boulder Meetup
Simple Solutions for Complex Problems
Simple Solutions for Complex Problems
GoSF: Decoupling Services from IP networks with NATS

Recently uploaded (20)

PDF
Nekopoi APK 2025 free lastest update
PDF
Internet Downloader Manager (IDM) Crack 6.42 Build 41
PDF
Raksha Bandhan Grocery Pricing Trends in India 2025.pdf
PPTX
CHAPTER 2 - PM Management and IT Context
PDF
Navsoft: AI-Powered Business Solutions & Custom Software Development
PPTX
Online Work Permit System for Fast Permit Processing
PDF
PTS Company Brochure 2025 (1).pdf.......
PDF
Flood Susceptibility Mapping Using Image-Based 2D-CNN Deep Learnin. Overview ...
PPTX
history of c programming in notes for students .pptx
PPTX
Agentic AI Use Case- Contract Lifecycle Management (CLM).pptx
PPTX
Oracle E-Business Suite: A Comprehensive Guide for Modern Enterprises
PPTX
L1 - Introduction to python Backend.pptx
PDF
AI in Product Development-omnex systems
PDF
How Creative Agencies Leverage Project Management Software.pdf
PDF
System and Network Administration Chapter 2
PDF
Digital Strategies for Manufacturing Companies
PDF
Wondershare Filmora 15 Crack With Activation Key [2025
PDF
Understanding Forklifts - TECH EHS Solution
PPT
Introduction Database Management System for Course Database
PDF
Design an Analysis of Algorithms II-SECS-1021-03
Nekopoi APK 2025 free lastest update
Internet Downloader Manager (IDM) Crack 6.42 Build 41
Raksha Bandhan Grocery Pricing Trends in India 2025.pdf
CHAPTER 2 - PM Management and IT Context
Navsoft: AI-Powered Business Solutions & Custom Software Development
Online Work Permit System for Fast Permit Processing
PTS Company Brochure 2025 (1).pdf.......
Flood Susceptibility Mapping Using Image-Based 2D-CNN Deep Learnin. Overview ...
history of c programming in notes for students .pptx
Agentic AI Use Case- Contract Lifecycle Management (CLM).pptx
Oracle E-Business Suite: A Comprehensive Guide for Modern Enterprises
L1 - Introduction to python Backend.pptx
AI in Product Development-omnex systems
How Creative Agencies Leverage Project Management Software.pdf
System and Network Administration Chapter 2
Digital Strategies for Manufacturing Companies
Wondershare Filmora 15 Crack With Activation Key [2025
Understanding Forklifts - TECH EHS Solution
Introduction Database Management System for Course Database
Design an Analysis of Algorithms II-SECS-1021-03

NATS + Docker meetup talk Oct - 2016

  • 1. Simple and Scalable Microservices NATS and the Docker tooling + Waldemar Quevedo / @wallyqs Docker SF Meetup, Oct 2016
  • 2. 1 . 1 2 . 1 ABOUT Waldemar Quevedo / So ware Developer at in SF Development of the Apcera Platform Past: PaaS DevOps at Rakuten in Tokyo NATS client maintainer (Ruby, Python) @wallyqs Apcera
  • 3. 3 . 1 ABOUT THIS TALK What is NATS Features from NATS NATS + Docker
  • 4. 4 . 1 What is NATS?
  • 6. 4 . 3 NATS High Performance Messaging System Created by First written in in 2010 Originally built for Cloud Foundry Rewritten in in 2012 Better performance Open Source, MIT License Used by Apcera, Ericsson, HTC, GE, Baidu Derek Collison Ruby Go https://github.com/nats-io
  • 7. 4 . 4 NATS Design constrained to keep it as operationally simple and reliable as possible while still being both performant and scalable.
  • 8. 4 . 5 Acts as an always available dial-tone
  • 9. 4 . 6 It's Fast
  • 10. single byte message Around 10M messages/second
  • 11. 4 . 7 4 . 8 and Simple
  • 12. 4 . 9 DESIGN Concise feature set (pure PubSub!) No built-in persistence of messages No exactly-once-delivery promises either Those concerns are simplified away from NATS → NATS Streaming
  • 13. 4 . 10 DESIGN TCP/IP based Plain text protocol fire and forget at most once
  • 14. 4 . 11 Very simple protocol telnet demo.nats.io 4222 sub hello 1 +OK pub hello 5 world +OK MSG hello 1 5 world ping PONG nats.io/documentation/nats-protocol
  • 17. 4 . 14 GO nc, err := nats.Connect() // ... nc.Subscribe("hello", func(m *nats.Msg){ fmt.Printf("[Received] %s", m.Data) }) nc.Publish("hello", []byte("world"))
  • 18. 4 . 15 RUBY require 'nats/client' NATS.start do |nc| nc.subscribe("hello") do |msg| puts "[Received] #{msg}" end nc.publish("hello", "world") end
  • 19. 4 . 16 PYTHON (ASYNCIO) yield from nc.connect() @asyncio.coroutine def handler(msg): print("[Received] {data}".format( data=msg.data.decode())) # Coroutine based subscriber yield from nc.subscribe("foo", cb=handler) yield from nc.publish("foo", "bar")
  • 20. 4 . 17 NODE.JS var nats = require('nats').connect(); // Simple Publisher nats.publish('foo', 'Hello World!'); // Simple Subscriber nats.subscribe('foo', function(msg) { console.log('[Received] ' + msg); });
  • 21. 4 . 18 C natsConnection_Publish(nc,"foo",data,5); natsConnection_Subscribe(&sub,nc,"foo",onMsg, NULL); void onMsg(natsConnection *nc, natsSubscription *sub, natsMsg *msg, void *closure) { printf("[Received] %.*sn", natsMsg_GetData(msg)); // ... }
  • 22. 4 . 19 C# using (ISyncSubscription s = c.SubscribeSync("foo")) { for (int i = 0; i < 10; i++) { Msg m = s.NextMessage(); System.Console.WriteLine("[Received] " + m); } }
  • 23. 4 . 20 JAVA // Simple Publisher nc.publish("foo", "Hello World".getBytes()); // Simple Async Subscriber nc.subscribe("foo", m -> { System.out.println("[Received] %sn", new String(m.getData())); });
  • 24. Many more available! C C# Java Python NGINX Go Node.js Elixir Ruby PHP Erlang Rust Haskell Scala Perl ( italics → community contributed)
  • 25. 4 . 21 4 . 22 Great community!
  • 28. 4 . 24 Community contributed dashboards github.com/cmfatih/natsboard
  • 29. 4 . 25 Docker Hub activity from NATS users
  • 30. 4 . 26 Docker Hub activity from NATS users
  • 31. 4 . 27 Docker Store (Beta)
  • 32. 4 . 28 5 . 1 NATS Features
  • 33. 5 . 2 FEATURES Pure PubSub based Request/Reply Subject routing with wildcards Authorization Distribution queue groups for balancing Cluster mode for HA Auto discovery of topology /varzstyle monitoring Secure TLS connections with certificates
  • 34. 5 . 3 REQUEST/REPLY It is pure PubSub based using and by signaling in the subject: NATS unique identifiers limited interest SUB _INBOX.y1JxglDi76shQQIhPbTDme 2 UNSUB 2 1 PUB help _INBOX.y1JxglDi76shQQIhPbTDme 6 please tells the server to unsubscribe from subscription with sid=2 a er getting 1 message before sending a request on the helpsubject.
  • 35. 5 . 4 REQUEST/REPLY If another subscriber is connected and interested in the helpsubject, it will then receive a message with that inbox. SUB help 90 # Message received from server MSG help 90 _INBOX.y1JxglDi76shQQIhPbTDme 6 please # Use the inbox to reply back PUB _INBOX.y1JxglDi76shQQIhPbTDme 11 I can help!
  • 36. 5 . 5 REQUEST/REPLY Finally, original requestor will be receiving the message: SUB _INBOX.y1JxglDi76shQQIhPbTDme 2 UNSUB 2 1 PUB help _INBOX.y1JxglDi76shQQIhPbTDme 6 please MSG _INBOX.y1JxglDi76shQQIhPbTDme 2 11 I can help!
  • 37. 5 . 6 REQUEST/REPLY NATS clients libraries have helpers for generating the unique inboxes which act as ephemeral subscriptions: nats.NewInbox() // _INBOX.y1JxglDi76shQQIhPbTDme Used internally when making a Request: nc, _ := nats.Connect(nats.DefaultURL) t := 250*time.Millisecond // Request sets to AutoUnsubscribe after 1 response msg, err := nc.Request("help", []byte("please"), t) if err == nil { fmt.Println(string(msg.Data)) // => I can help! }
  • 38. REQUEST/REPLY → LOWEST LATENCY Result of publishing a request to all nodes with limited interest means we are getting the fastest reply back:
  • 39. 5 . 7 REQUEST/REPLY → LOWEST LATENCY Result of publishing a request to all nodes with limited interest means we are getting the fastest reply back:
  • 40. 5 . 85 . 9 SUBJECTS ROUTING Wildcards: * SUB foo.*.bar 90 PUB foo.hello.bar 2 hi MSG foo.hello.bar 90 2 hi e.g. subscribe to all requests being made on the demo site: telnet demo.nats.io 4222 INFO {"auth_required":false,"version":"0.9.4",...} SUB _INBOX.* 99 MSG _INBOX.y1JxglDi76shQQIhPbTDme 99 11 I can help!
  • 41. 5 . 10 SUBJECTS ROUTING Full wildcard: > SUB hello.> 90 PUB hello.world.again 2 hi MSG hello.world.again 90 2 hi e.g. subscribe to all subjects and see whole traffic going through the server: telnet demo.nats.io 4222 INFO {"auth_required":false,"version":"0.9.4",...} sub > 1 +OK
  • 42. 5 . 11 DISTRIBUTION QUEUES Balance work among nodes randomly
  • 43. 5 . 12 DISTRIBUTION QUEUES Balance work among nodes randomly
  • 44. 5 . 13 DISTRIBUTION QUEUES Balance work among nodes randomly
  • 45. 5 . 14 DISTRIBUTION QUEUES Service A workers subscribe to service.Aand create workersdistribution queue group for balancing the work. nc, _ := nats.Connect(nats.DefaultURL) // SUB service.A workers 1rn nc.QueueSubscribe("service.A", "workers", func(m *nats.Msg) { nc.Publish(m.Reply, []byte("hi!")) })
  • 46. 5 . 15 DISTRIBUTION QUEUES Note: NATS does not assume the audience!
  • 47. 5 . 16 DISTRIBUTION QUEUES All interested subscribers receive the message!
  • 48. 5 . 17 CLUSTERING Avoid SPOF on NATS by assembling a full mesh cluster
  • 49. 5 . 18 CLUSTERING Clients reconnect logic is triggered
  • 50. 5 . 19 CLUSTERING Connecting to a NATS cluster of 2 nodes explicitly srvs := "nats://10.240.0.1:4222,nats://10.240.0.2:4223" nc, _ := nats.Connect(srvs) NOTE: NATS servers have a forwarding limit of one hop. Each server will only forward a message that it has received from a client to all connected servers that expressed interest in the message's published subject. A message received from a route will only be distributed to local clients.
  • 51. 5 . 20 CLUSTERING Reconnect and disconnect handlers can be useful to trace connection failures. nc, err := nats.Connect(uri, nats.DisconnectHandler(func(nc *nats.Conn) { fmt.Printf("Got disconnected!n") }), nats.ReconnectHandler(func(nc *nats.Conn) { fmt.Printf("Got reconnected to %v!n", nc.ConnectedUrl()) }), nats.ClosedHandler(func(nc *nats.Conn) { fmt.Printf("Connection closed. Reason: %qn", nc.LastError()) }), )
  • 52. 5 . 21 CLUSTER AUTO DISCOVERY Since release, topology can be discovered dynamically by clients! v0.9.2
  • 53. We can start with a single node…
  • 54. 5 . 22 Then have new nodes join the cluster…
  • 55. 5 . 23 As new nodes join, server announces INFOto clients.
  • 56. 5 . 24 Clients auto reconfigure to be aware of new nodes.
  • 57. 5 . 25 Clients auto reconfigure to be aware of new nodes.
  • 58. 5 . 26 Now fully connected!
  • 59. 5 . 27 On failure, clients reconnect to an available node.
  • 60. 5 . 28 5 . 29 MONITORING style monitoring endpoint available for inspecting the internal state of the server. /varz Other available endpoints: - Info of clients connected to this server/connz - Subscriptions metrics/subsz - Cluster routes/routez
  • 61. 5 . 30 MONITORING: EXAMPLES Gathering connections metrics from demo: curl demo.nats.io:8222/varz | grep connections Result: "max_connections": 65536, "connections": 25, "total_connections": 12429,
  • 62. 5 . 31 MONITORING: EXAMPLES Gathering metrics regarding languages used when connecting to demo curl demo.nats.io:8222/connz?subsz=1 | grep lang | sort | uniq -c Result: 10 "lang": "go", 7 "lang": "node", 8 "lang": "python2",
  • 63. 5 . 32 MONITORING polls from these endpoints providing a terminal UInats-top
  • 64. 5 . 33 TLS Supported for client and route connections, and for monitoring. https_port: 6443 tls { cert_file: "./configs/certs/server-cert.pem" key_file: "./configs/certs/server-key.pem" ca_file: "./configs/certs/ca.pem" # Require client certificates verify: true }
  • 65. 5 . 34 CLUSTER TLS Securing route connections with TLS cluster { listen: 0.0.0.0:6222 tls { # Route cert cert_file: "./configs/certs/srva-cert.pem" # Private key key_file: "./configs/certs/srva-key.pem" # Optional certificate authority verifying routes # Required when we have self-signed CA, etc. ca_file: "./configs/certs/ca.pem" } }
  • 66. 5 . 35 SUBJECTS AUTHORIZATION PubSub on certain subjects can be disallowed in the server's configuration: authorization { admin = { publish = ">", subscribe = ">" } requestor = { publish = ["req.foo", "req.bar"] subscribe = "_INBOX.*" } users = [ {user: alice, password: foo, permissions: $admin} {user: bob, password: bar, permissions: $requestor} ] }
  • 67. 5 . 36 SUBJECTS AUTHORIZATION Clients are not allowed to publish on _SYS(reserved): PUB _SYS.foo 2 hi -ERR 'Permissions Violation for Publish to "_SYS.foo"'
  • 68. 6 . 1 NATS and the Docker tooling
  • 69. 6 . 2 THE NATS DOCKER IMAGE Small binary → Lightweight Docker image No deployment dependencies
  • 70. 6 . 3 2-STEP BUILD PROCESS
  • 71. 6 . 4 FIRST STEP: COMPILE github.com/nats-io/gnatsd/Dockerfile FROM golang:1.6.3 MAINTAINER Derek Collison <derek@apcera.com> COPY . /go/src/github.com/nats-io/gnatsd WORKDIR /go/src/github.com/nats-io/gnatsd RUN CGO_ENABLED=0 go install ...(elided) EXPOSE 4222 8222 ENTRYPOINT ["gnatsd"] CMD ["--help"]
  • 72. 6 . 5 SECOND STEP: FROM SCRATCH github.com/nats-io/nats-docker/Dockerfile FROM scratch COPY gnatsd /gnatsd COPY gnatsd.conf /gnatsd.conf EXPOSE 4222 6222 8222 ENTRYPOINT ["/gnatsd", "-c", "/gnatsd.conf"] CMD []
  • 73. 6 . 6 THE NATS DOCKER IMAGE By default it is exposing these ports: # Clients, Cluster and Monitoring ports EXPOSE 4222 6222 8222 - Clients will be connecting against this port4222 - Port used for the cluster routes6222 - HTTP Monitoring endpoint8222
  • 74. 6 . 7 USING NATS + DOCKER
  • 75. All examples can be found at github.com/wallyqs/nats-docker-examples
  • 76. 6 . 8 EXAMPLE: SINGLE NODE API Server which receives HTTP requests and communicates internally through NATS to a pool of workers.
  • 77. 6 . 96 . 10 EXAMPLE: CLUSTERED SETUP API Server which receives HTTP requests and communicates internally through NATS to a pool of workers.
  • 78. 6 . 11 LOCAL NATS CLUSTER VIA DOCKER COMPOSE Docker Compose tooling comes in handy here for doing development as it helps us in assembling NATS clusters locally. version: "2" networks: nats-network: {} services: nats-server-A: networks: ["nats-network"] image: "nats:0.9.4" entrypoint: "/gnatsd --routes nats://nats-server-B:6222,nats://nats-server-C:6222 --cluster nats://0.0.0.0:6222" nats-server-B: networks: ["nats-network"] image: "nats:0.9.4" entrypoint: "/gnatsd --routes nats://nats-server-A:6222,nats://nats-server-C:6222 --cluster nats://0.0.0.0:6222" nats-server-C: networks: ["nats-network"] image: "nats:0.9.4" entrypoint: "/gnatsd --routes nats://nats-server-A:6222,nats://nats-server-B:6222 --cluster nats://0.0.0.0:6222"
  • 79. NATS + Docker Compose Demo
  • 80. 6 . 12 6 . 13 DOCKER SWARM BASED NATS CLUSTER Auto discovery becomes helpful in this context, we can assemble one with the following commands. docker network create --driver overlay nats-cluster-example docker service create --network nats-cluster-example --name nats-A nats:0.9.4 -cluster nats://0.0.0.0:6222 docker service create --network nats-cluster-example --name nats-B nats:0.9.4 -routes nats://nats-A:6222 -cluster nats://0.0.0.0:6222 docker service create --network nats-cluster-example --name nats-C nats:0.9.4 -routes nats://nats-A:6222,nats://nats-B:6222 -cluster nats://0.0.0.0:6222
  • 81. 6 . 14 DOCKER SWARM BASED NATS CLUSTER Even easier: just use same configuration in all nodes. for node in A B C; do docker service create --network nats-cluster-example --name nats-$node nats:0.9.4 -routes nats://nats-A:6222 -cluster nats://0.0.0.0:6222 done Initial server becomes the seed server, ignoring route to self.
  • 82. NATS + Docker Swarm mode Demo
  • 83. 6 . 15 7 . 1 Summary
  • 84. NATS is a simple, fast and reliable solution for the internal communication of a distributed system. Docker flexible tooling is a good complement for building NATS based applications.
  • 85. 7 . 2 7 . 3 BONUS: NATS STREAMING NATS Streaming recently became an official image too! It is a layer on top of NATS totalling in ~10MB. Further info: github.com/nats-io/nats-streaming-server
  • 86. 8 . 1 THANKS! /github.com/nats-io @nats_io Play with the demo site! telnet demo.nats.io 4222