设计实现
topics和channels不需要提前创建。Topics会在第一次发布或者订阅的时候创建,channels则会在第一次订阅的时候创建。
topics和channels都是单独保存各自的数据,防止一些比较慢的消费者造成消息积压。
如果一个channel由多个consumer连接,那么消息会随机选择一个client进行消息传递。如下图所示:
简单总结下,msg 由topics多播到channel,并且交由channel分发给consumer。
NSQ 使用 nsqlookupd
去做服务发现,consumer可以通过其去找到nsqd
的地址和其上的topic。具体到底层实现,``nsqd和
nsqlookupd之间维持着长连接,并且
nsqd`会定期上报其状态。
nsq和其他mq设计不太一样的是,它的nsq和nsqlookupd
都是独立的进程,nsq
之间是相互不通信的。
单点故障消除
nsq设计上使得客户端连接所有的提供其需要topic的producer。这中间没有中间件,没有message broker,也就没有单点故障。
这边可能存在的问题
- 网络拥堵
- 消息抢占?
可靠性保证
nsq提供的保证是 at least once。
具体的实现如下:
- nsq将消息发送出去,并将该消息缓存在本地
- client收到消息,需要回复FIN(finish)或者REQ(re-queue)。如果nsq超时没有收到消息,则执行REQ操作。
这个方案可能存在的问题是 nsq crash,导致所有缓存的消息丢失。其官方给的一个解决方案是,启一个冗余nsq在其他集群上,然后进行消息收发。因为client有幂等保证,所以我们不担心消息重复消费。
效率保证
QA
如果每个channel单独保存一份数据的话,会不会太过冗余
Topics and channels all buffer data independently of each other, preventing a slow consumer from causing a backlog for other channels (the same applies at the topic level).