玩转NSQ(2)-消息流转
版权声明 本站原创文章 由 萌叔 发表
转载请注明 萌叔 | https://vearne.cc
1.引言
nsq的架构简单,代码清晰。对于自主造轮子,实现消息队列、消息推送系统、IM都是非常好的参考。
本文将以图表的形式来说明消息在nsdd中的流转。
2.消息流转
2.1 重要的数据结构
Topic
/ Channel
/ Client
都是nsqd中的数据结构。
- 数据会从
Topic
复制到Channel1和Channel2 Client
是 consumer在nsqd内部的表征- 每个
Client
最多只能订阅一个Channel
- 它们内部都有一组queue
memoryMsgChan chan *Message // 位于内存
backend BackendQueue //当memoryMsgChan写满,则默认写入磁盘
- 每个producer都有1个读协程,负责把producer发送的消息写入
Topic
- 多个
Client
可以订阅同一个Channel
。即一个Channel
,多个消费者,谁抢到算谁的。 - 每一个
Topic
都对应1个协程Topic.messagePump负责从Topic复制数据到Channel
- NSQD.queueScanLoop会控制一组协程NSQD.queueScanWorker(动态大小的协程池) 从
Channel
(所有topic的Channels)中复制数据到Client
中, 之所以是协程池,我觉得可能跟Channel中的消息有延迟发送,且有重入队列的有关操作 - 每一个
Client
对应着一个协程protocolV2.messagePump,负责通过TCP连接把数据发送给consumer
3. 其它有趣的小细节
比较有意思的是,nsq官方推荐,nsqd随着发布者一起部署。
发布者不必去发现其他的nsqd节点,他们总是可以向本地实例发布消息。
- 实际上解放了producer,而甩锅给了consumer,如果某个
Topic
假定叫topic1。如果topic1位于多个nsqd,consumer需要通过nsqlookupd获知所有拥topic1的nsqd的地址,然后需要在多个nsqd上订阅topic1
这里的nsqlookupd相当于是注册中心。 -
如果某个nsqd宕机,由于nsqd没有副本,消息可能会丢失