NATS消息队列主要有三种模型:发布/订阅模型、请求/响应模型、队列模型,在项目使用时一定要根据业务类型选择对应的模型,以下是三种模型的介绍:
发布/订阅模型:
特点:
- 订阅者没有返回是否收到给发布者
- 一个订阅者可以订阅多个发布者
- 消息是会到达所有订阅者处,订阅者根据 filter 丢掉自己不需要的消息(filter 是在订阅端起作用的)
- 每个订阅者都会接收到每条消息的一个副本
- 基于推送 push,其中消息自动地向订阅者广播,它们无须请求或轮询主题来获得新消息,发布/订阅模式内部,有多种不同类型的订阅者。
- 非持久订阅者是临时订阅类型,它们只是在主动侦听主题时才接收消息。
- 持久订阅者将接收到发布的每条消息的一个副本,即便在发布消息,它们处于"离线"状态时也是如此。
- 另外还有动态持久订阅者和受管的持久订阅者等类型。
优点:
- 降低了模块间的耦合度:发布者与订阅者松散地耦合,并且不需要知道对方的存在。相关操作都集中在 Publisher 中。
- 可扩展性强:系统复杂后,可以把消息订阅和分发机制单独作为一个模块来实现,增加新特性以满足需求
缺点:
- 发布者不知道订阅者是否收到发布的消息
- 订阅者不知道自己是否收到了发布者发出的所有消息
- 发送者不能获知订阅者的执行情况
- 没人知道订阅者何时开始收到消息
请求/响应模型:
NATS支持两种请求-响应消息通信:P2P(点对点)和 O2M(一对多)。P2P 最快、响应也最先。而对于O2M,需要设置请求者可以接收到的响应数量界限。
在 请求-响应 的消息交换,发布请求操作会发布一个带预期响应的消息到Reply主题。 请求创建了一个收件箱,并在收件箱执行调用,并进行响应和返回。
队列模型:
NATS支持P2P消息通信的队列。要创建一个消息队列,订阅者需注册一个队列名。所有的订阅者用同一个队列名,形成一个队列组。当消息发送到主题后,队列组会自动选择一个成员接收消息。尽管队列组有多个订阅者,但每条消息只能被组中的一个订阅者接收。
队列的订阅者可以是异步的,这意味着消息句柄以回调方式处理交付的消息。异步队列订阅者必须建立处理消息的逻辑。
队列模型一般常用语数据队列使用,例如:采集从网页上采集的数据经过处理直接写入到该队列,接收端一方可以起多个线程同时读取其中的一个队列,其中某些数据被一个线程消费了,其他线程就看不到了,这种方式为了解决采集量巨大的情况下,后端服务可以动态调整并发数来消费这些数据。说白了就一点,上游生产数据太快,下游消费可能处理不过来,中间进行缓冲,下游就可以根据实际情况进行动态调整达到动态平衡。
使用场景:
- 无人球场异常问题通知处理
- web端,收银机端的通知,比如支付成功,费用刷新,订单结果通知等异步通知
- 模块之间的信息同步,比如添加了一个场馆/商品,要更新相应的库存什么的。
- 订单处理,这个最复杂,订单处理流程化,进消息队列是最简单的方法。比如说,一个订单,是不是应该享受优惠,或者低免,这个订单处理流程。包括我们应用日志系统,有消息队列之后,都简单很多。
- 消息推送,如订单成功后发送异步通知等
- 订单支付回调,使用websocket
官方使用案列:
Go client: https://github.com/nats-io/go-nats
Node.js client: https://github.com/nats-io/node-nats
Ruby client: https://github.com/nats-io/ruby-nats
Java client: https://github.com/nats-io/jnats
C client: https://github.com/nats-io/cnats
C# client: https://github.com/nats-io/csnats
Nginx C client: https://github.com/nats-io/nginx-nats
websocket: https://github.com/isobit/websocket-nats