nats 简介
什么是nats:
NATS Server is a simple, high performance open source messaging system for cloud native applications, IoT messaging, and microservices architectures.
(nats 是cncf指定message system)
Built from the ground up to be cloud native, NATS is a mature, seven-year-old open source messaging technology that implements the publish/subscribe, request/reply and distributed queue patterns to help create a performant and secure method of InterProcess Communication (IPC). Simplicity, performance, scalability and security are the core tenets of NATS.
事实上官网对nats的文档支持很好,我写这篇文章不是想做文字的搬运工,而是写一些阅读官方文档之后的理解。
nats buffer & reliability
nats客户端,不论是subscriber还是publisher都会有内部的buffer,从而提高吞吐量。另一方面,nats-server内部是没有buffer的,即”fire and forget”。
publisher
只要bufio的buffer没有满,那么publish总是可以成功。想象一下如果publisher当前是offline的,它也可以发送成功,这是不是会影响服务的正确性?(例如因为,这个msg实际上并没有真正的被broker所接收)。
实际上,即使这个msg被nats server接收了,publisher依然无法保证msg会正确无误地被subscriber所接收(例如suscrbier可能离线而丢失了这个msg)。所以,publisher在nats里得到的保证仅仅是msg被正确地发送出去了。至于从buffer到nats-server,nats-server到subscriber,这一串传递是无法被保证的。这就是所谓的at most onece delivery:
At Most Once Delivery (NATS w/TCP reliability) - In the basic NATS platform, if a subscriber is not listening on the subject (no subject match), or is not active when the message is sent, the message is not received. NATS is a fire-and-forget messaging system. If you need higher levels of service, you can either use NATS Streaming, or build the additional reliability into your client(s) yourself.
而这里的缓存,一方面提高了系统的吞吐性,另一方在保证了当publisher连接的nats集群发生容灾的时候,依然可以一定程度上地publish,并且保证这些msg会被之后的主节点所正确处理(而无需监听disconnect事件去做一些复杂的错误处理)。
subscriber
subscriber的缓存同样是为了提高系统的吞吐量,同时它带来了使用者以下几方面的思考:
-
在nats中有slow consumer的概念,大概就是如果subscriber无法快速的consume掉当前缓存中的msg,那么可能是client本身将自己标记为slow consumer,断开和server的连接;要么是server发现这个subscriber无法即使响应它的ping请求而将其断开。这种行为其实是为了保护subscriber,防止它有更多的输入,好让它将当前pending的msg全部处理掉。这里,client自身判断自己是否是slow consumer就是由它的缓存使用情况来决定的。
-
在unsubscribe某个subject或者断开nats的连接时,默认情况下如果调用的是
Unsubscribe()
或者Close()
,它们都是仅处理完当前的msg之后就结束了,不会去管那些缓存中的msg。在新的nats client版本中新加了一个Drain()
的接口,它即可以用于unsubscribe,也可以用于close。具体的行为如下:
-
drain subscription:
- unsubscribe at server
- process known messages
- clean up
-
drain connection:
- drain subscription
- stop new messages from being published
- flush any remaining messages
- close
-
Comments