Slide 1

Slide 1 text

FAST MESSAGING WITH GO AND NATS

Slide 2

Slide 2 text

About me: Federico Paolinelli Lead developer @ List @fedepaol github.com/fedepaol [email protected] 2

Slide 3

Slide 3 text

WHY MESSAGING 3

Slide 4

Slide 4 text

Good points of messaging ▷ Decoupling ▷ Scaling ▷ Event sourcing ▷ Reactive paradigms 4

Slide 5

Slide 5 text

50 SHADES OF MESSAGING 5

Slide 6

Slide 6 text

6

Slide 7

Slide 7 text

What to look for ▷ Messaging patterns ▷ Durability of the messages ▷ Ordering guarantees ▷ Routing capabilities ▷ Dev / Ops experience ▷ Performance ▷ Auth / authz 7

Slide 8

Slide 8 text

What makes a good communication system? 8

Slide 9

Slide 9 text

Enterprise service Buses 9

Slide 10

Slide 10 text

“ We've seen many products and approaches that stress putting significant smarts into the communication mechanism itself [..] The microservice community favours an alternative approach: smart endpoints and dumb pipes 10 Martin Fowler

Slide 11

Slide 11 text

NATS: Dumb but not dumber 11

Slide 12

Slide 12 text

The protocol PUB Publish a message to a subject, with optional reply subject SUB Subscribe to a subject (or subject wildcard) MSG Delivers a message payload to a subscriber UNSUB Unsubscribe (or auto-unsubscribe) from subject 12

Slide 13

Slide 13 text

Subscription Wildcards ▷ foo.bar ▷ foo.bar.baz ▷ foo.* ▷ foo.> ▷ foo.*.baz 13

Slide 14

Slide 14 text

The server 14

Slide 15

Slide 15 text

The server ▷ Single go executable ▷ Full mesh of servers ▷ Gossip based autodiscovery 15 gnatsd -p 4222 -cluster nats://localhost:4248 gnatsd -p 5222 -routes nats://localhost:4248

Slide 16

Slide 16 text

16 Nats Server 1 Nats Server 2 Nats Server 3 Client 1 PUB HI.ALL HELLO Client 2 MSG HI.ALL HELLO Full Mesh of servers

Slide 17

Slide 17 text

Guarantees ▷ at most once ▷ messages ordered per publisher 17

Slide 18

Slide 18 text

18 Always up Dialtone

Slide 19

Slide 19 text

What can I do with it? 19

Slide 20

Slide 20 text

Publish Subscribe! 20 Nats Server 2 Client 1 PUB HI.ALL HELLO Client 2 MSG HI.ALL HELLO

Slide 21

Slide 21 text

Queueing 21 Nats Server 2 Client 1 PUB HI.ALL HELLO Client 2 MSG HI.ALL HELLO Client 2 PUB HI.ALL HELLO1 MSG HI.ALL HELLO1

Slide 22

Slide 22 text

Request - Reply 22 Nats Server 2 Client 1 PUB HI.ALL REPLY_HERE HELLO ? Client 2 MSG HI.ALL HELLO? Client 2 MSG HI.ALL HELLO? MSG REPLY_HERE GOLAB! MSG REPLY_HERE GOLAB!

Slide 23

Slide 23 text

Using nats with go 23

Slide 24

Slide 24 text

The Go client ▷ Knows about all the nodes of the mesh ▷ Reconnects gracefully ▷ Buffers the messages to be sent (up to 8MB) ▷ Buffers the messages to be consumed (65k / 65Kb) 24

Slide 25

Slide 25 text

The Go client: pub/sub 25 nc, _ := nats.Connect(nats.DefaultURL) nc.Publish("foo", []byte("Hello World")) nc.Subscribe("foo", func(m *nats.Msg) { // handle the message }) nc.Flush() // chan subscribe ch := make(chan *nats.Msg, 64) sub, err := nc.ChanSubscribe("foo", ch) msg := <- ch

Slide 26

Slide 26 text

The Go client: request 26 // Requests var response string err := c.Request("help", "help me", &response, 10*time.Millisecond) if err != nil { fmt.Printf("Request failed: %v\n", err) } // Replying c.Subscribe("help", func(subj, reply string, msg string) { c.Publish(reply, "I can help!") }) // Queue group reply nc.QueueSubscribe("help", "workers", func(msg *Msg) { c.Publish(msg.Reply, "I can help!") })

Slide 27

Slide 27 text

The Go client ▷ Connection lifecycle callbacks ▷ Sync / async api ▷ Type safe encoders ▷ Context based requests 27

Slide 28

Slide 28 text

“ Simplicity is complicated but the clarity is worth the fight. 28 Rob Pike

Slide 29

Slide 29 text

An example 29 Nats Server Source PUB SENSORS.TEMP 0, 1, 2

Slide 30

Slide 30 text

An example 30 Nats Server Source Client

Slide 31

Slide 31 text

An example 31 Nats Server Source Client REQ SENSORS.CURRENT SUB SENSORS.TEMP

Slide 32

Slide 32 text

An example 32 Nats Server Source Client REQ SENSORS.CURRENT PUB SENSORS.CURRENT 2

Slide 33

Slide 33 text

An example 33 Nats Server Source Client PUB SENSORS.TEMP 3, 4, 5...

Slide 34

Slide 34 text

Is it fast? 34

Slide 35

Slide 35 text

Nats benchmarking tool 35 go run ./nats-bench.go -ms 16 -np 1 -ns 5 -n 1000000 foo Starting benchmark [msgs=1000000, msgsize=16, pubs=1, subs=5] NATS Pub/Sub stats: 8,729,005 msgs/sec ~ 133.19 MB/sec Pub stats: 1,457,683 msgs/sec ~ 22.24 MB/sec Sub stats: 7,276,675 msgs/sec ~ 111.03 MB/sec [1] 1,456,749 msgs/sec ~ 22.23 MB/sec (1000000 msgs) [2] 1,455,785 msgs/sec ~ 22.21 MB/sec (1000000 msgs) [3] 1,455,848 msgs/sec ~ 22.21 MB/sec (1000000 msgs) [4] 1,455,864 msgs/sec ~ 22.21 MB/sec (1000000 msgs) [5] 1,455,335 msgs/sec ~ 22.21 MB/sec (1000000 msgs) min 1,455,335 | avg 1,455,916 | max 1,456,749 | stddev 459 msgs

Slide 36

Slide 36 text

Bravenewgeek benchmarks 36 Source : https://bravenewgeek.com/benchmarking-message-queue-latency/

Slide 37

Slide 37 text

Other features ▷ TLS support ▷ Monitoring endpoints ▷ Authorization scheme ▷ Configuration reload ▷ Authentication ▷ K8s operator ▷ Prometheus exporter 37

Slide 38

Slide 38 text

Nats streaming (codename stan) 38

Slide 39

Slide 39 text

39

Slide 40

Slide 40 text

Features ▷ At least once guarantee ▷ Messages encoded with protobuf ▷ Durable subscriptions ▷ Queue groups ▷ Message Replay (date/time, offset, seqnum) 40

Slide 41

Slide 41 text

Features ▷ SQL, File or memory storage ▷ Partitioning ▷ Clustering ▷ Active / Passive ▷ No wildcarding 41

Slide 42

Slide 42 text

Something to keep an eye on 42

Slide 43

Slide 43 text

LiftBridge ▷ A nats streaming alternative ▷ github.com/liftbridge-io/liftbridge ▷ Promises some features missing from nats streaming ▷ Can work together with Nats 43

Slide 44

Slide 44 text

Just give it a try! 44

Slide 45

Slide 45 text

Thanks! Any questions? This slides: goo.gl/fJY6rw @fedepaol [email protected] 45