总结
1.NATS优缺点
NATS优点
NATS缺点
nats自己不
检测到slow consumer后,会清空消息
2.NATS的三种消息分发模式
Pub-Sub
作者注:这就是工作中常用的 发布client.publish() / 订阅client.subscribe()
可以采用通配符表达式的形式,订阅所有匹配的消息。
Request-Reply
作者注:这就是工作中常用的 请求client.request()
publisher和subscriber都要给replyTo属性赋值
为下图的Publisher,在发布消息msg1时,会同时带上一个replyTo的主题(一个UUID),并且订阅这个replyTo主题,
对应的订阅者收到之后,回复的Reply消息会以这个replyTo的主题发出,这样Publisher就能收到回复。
Publisher收到回复之后会自动取消replyTo的订阅,完成一次Request-Reply调用。
如果这里三个Subscriber都回复了,那么Nats只转发最早回复replyTo的消息,后面所回复的replyTo由于发起方Publisher已经取消订阅,不会再收到了。

Queue Groups
如果一个消息,有多个订阅者,那么会每个订阅者都收到并进行处理。
有时候我们想让一条消息只由一个订阅者处理,多个消费者之间可以实现负载均衡,这个时候可以使用Nats的Queue sub模式。
如下图,三条消息1,2,3会分发到三个Subscriber中,而不是每个Subscriber都收到1,2,3三条消息。值得注意的是,消息的分发是随机的,不支持按照固定规则分配。

关于NATS的Slow Consumer
1.Slow Consumer怎么识别
在client端里被识别
一旦client端识别出slow consumer, 会丢弃client端内存队列消息
在client创建connection时,就创建error handler
// Set the error handler when creating a connection. nc, err := nats.Connect("nats://localhost:4222", nats.ErrorHandler(natsErrHandler)) func natsErrHandler(nc *nats.Conn, sub *nats.Subscription, natsErr error) { fmt.Printf("error: %v\n", natsErr) if natsErr == nats.ErrSlowConsumer { pendingMsgs, _, err := sub.Pending() if err != nil { fmt.Printf("couldn't get pending messages: %v", err) return } fmt.Printf("Falling behind with %d pending messages on subject %q.\n", pendingMsgs, sub.Subject) // Log error, notify operations... } // check for other errors }
当slow consumer发生时,将会打印出类似的log:
error: nats: slow consumer, messages dropped Falling behind with 65536 pending messages on subject "foo".
在server端被识别
一旦server端识别出slow consumer, 会断掉和该client的connection,并丢弃server端内存队列消息
当slow consumer发生时,将会打印出类似的log:
[54083] 2017/09/28 14:45:18.001357 [INF] ::1:63283 - cid:7 - Slow Consumer Detected
2.Slow Consumer怎么处理
扩大queue subscriber成员 -- 使用于不依赖消息顺序
参考文献
http://wiki.htzq.htsc.com.cn/pages/viewpage.action?pageId=177762886