Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Fast messaging with Nats and Go

Federico Paolinelli
October 23, 2018
1.1k

Fast messaging with Nats and Go

Quick intro about Nats messaging system

Federico Paolinelli

October 23, 2018
Tweet

Transcript

  1. 6

  2. What to look for ▷ Messaging patterns ▷ Durability of

    the messages ▷ Ordering guarantees ▷ Routing capabilities ▷ Dev / Ops experience ▷ Performance ▷ Auth / authz 7
  3. “ 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
  4. 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
  5. 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
  6. 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
  7. 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
  8. 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!
  9. 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
  10. 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
  11. 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!") })
  12. The Go client ▷ Connection lifecycle callbacks ▷ Sync /

    async api ▷ Type safe encoders ▷ Context based requests 27
  13. 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
  14. Other features ▷ TLS support ▷ Monitoring endpoints ▷ Authorization

    scheme ▷ Configuration reload ▷ Authentication ▷ K8s operator ▷ Prometheus exporter 37
  15. 39

  16. Features ▷ At least once guarantee ▷ Messages encoded with

    protobuf ▷ Durable subscriptions ▷ Queue groups ▷ Message Replay (date/time, offset, seqnum) 40
  17. Features ▷ SQL, File or memory storage ▷ Partitioning ▷

    Clustering ▷ Active / Passive ▷ No wildcarding 41
  18. LiftBridge ▷ A nats streaming alternative ▷ github.com/liftbridge-io/liftbridge ▷ Promises

    some features missing from nats streaming ▷ Can work together with Nats 43