Fork me on GitHub

版权声明 本站原创文章 由 萌叔 发表
转载请注明 萌叔 | https://vearne.cc

1.引言

nsq的架构简单,代码清晰。对于自主造轮子,实现消息队列、消息推送系统、IM都是非常好的参考。
本文将以图表的形式来说明消息在nsdd中的流转。

2.消息流转

image_1dmnogtti1cfud831ii1nho9jp.png-231.4kB

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. 其它有趣的小细节

image_1dmnpfn451eg391sb7lm9um8116.png-120.6kB

比较有意思的是,nsq官方推荐,nsqd随着发布者一起部署。

发布者不必去发现其他的nsqd节点,他们总是可以向本地实例发布消息。

  • 实际上解放了producer,而甩锅给了consumer,如果某个Topic 假定叫topic1。如果topic1位于多个nsqd,consumer需要通过nsqlookupd获知所有拥topic1的nsqd的地址,然后需要在多个nsqd上订阅topic1
    这里的nsqlookupd相当于是注册中心。

  • 如果某个nsqd宕机,由于nsqd没有副本,消息可能会丢失


打赏作者

微信支付码

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注