消息队列NSQ源码解析

259 阅读3分钟

通过本文对关键模块核心源码解析,你可以了解NSQ是什么、基本框架及关键原理。

是什么

NSQ是一个基于Go语言的分布式实时消息平台,定位和Kafka和RocketMQ比较类似,由如下几个关键组件组成:

  • Nsqd:负责接收、排队、转发消息到客户端(核心)

  • Nsqlookupd:管理集群拓扑信息,维护Nsqd与topic的关系

  • Nsqadmin:一套Web用户界面,可实时查看和管理集群

image

NSQ架构图

其中:

  • Topic代表一种消息流,Channel是一个订阅了给定Topic的consumer逻辑分组。

  • 单个Nsqd可以有多个Topic,每个Topic又可以有多个Channel。

  • Channel能够接收Topic所有消息的副本,从而实现了消息多播分发;

  • Channel上的每个消息被随机分发给它的订阅者,从而实现负载均衡

消息处理关键过程:

关键过程Nsqd收到消息每个消息都会软拷贝到channels中channels会根据策略选择consumer投递消息某个consumer收到消息
eg1:A消息传递过程imageimageimageimage
eg2:B消息传递过程imageimageimageimage

框架

image

如上图所示,可以看出共有四个核心流程,每个核心流程用同一种颜色标识,每个核心流程由多个子操作构成。

流程颜色标识子操作总结
Nsqd启动流程image
启动配置、启动监听
接受消息流程image
消息会写入topic和channel中
消息转发流程image
有一套client和Nsqd的建连及通信机制来高效支持msg的转发。
消息超时重试流程image
通过特定扫描算法,保证高效低延迟进行重试或者延迟msg的处理。

原理

Nsqd如何优雅启动?

svc框架

image

image

image

image

wg框架

image

image

流程流程

image

Nsqd如何优雅退出?

image

image

消息是如何传递的?

第一步:接受HTTP消息,并将消息写入topic

image

image

第二步: 传递二:从topic取出传递到channel

image

image

** 第三步:建立TCP连接,consumer消费消息**

image

image

image

image

nsq与consumer交互流程图

image

消息如何保证至少投递成功一次?

image

采用等待定时器触发扫描而非不断轮询的方法避免了函数持续执行影响性能。

image

image

image

image

各MQ对比

类型NSQKafkaRocketmq
消息吞吐量高(十万级别)高(十万级别)中(万级别)
消息可靠性低(基于重试+本地文件backend)中等(基于副本机制保证)较高(基于事务保证)
延时队列支持不支持支持
支持重试支持不支持(不支持ack方式重试,只能server本身去重试)支持
资源成本低(无replication机制需要维护controller,基本无额外损耗)
写入性能
读写延迟
有序性无法保证局部有序局部有序
消息投递方式pushpullpush+pull
适用场景大规模数据处理、实时流处理,对实时性要求高,可接受部分丢失的场景。大规模数据处理、实时流处理,如可靠性要求高的日志场景。大规模数据处理,实时处理,如可靠性要求高的实时业务场景。

思考

  1. 每种MQ都有其适用的业务场景,应根据业务场景的特点和不同的发展阶段去灵活选型。

  2. NSQ作为一种用基于Go语言的分布式实时消息平台,整体代码架构设计非常优雅和巧妙,如启动\退出机制、消息可靠传递机制等值得学习和思考,另外类似redis过期机制的probabilistic思想,对于提升系统性能的也有非常大的参考意义,整体来说NSQ作为源码学习收益匪浅。