通过本文对关键模块核心源码解析,你可以了解NSQ是什么、基本框架及关键原理。
是什么
NSQ是一个基于Go语言的分布式实时消息平台,定位和Kafka和RocketMQ比较类似,由如下几个关键组件组成:
-
Nsqd:负责接收、排队、转发消息到客户端(核心)
-
Nsqlookupd:管理集群拓扑信息,维护Nsqd与topic的关系
-
Nsqadmin:一套Web用户界面,可实时查看和管理集群
NSQ架构图
其中:
-
Topic代表一种消息流,Channel是一个订阅了给定Topic的consumer逻辑分组。
-
单个Nsqd可以有多个Topic,每个Topic又可以有多个Channel。
-
Channel能够接收Topic所有消息的副本,从而实现了消息多播分发;
-
Channel上的每个消息被随机分发给它的订阅者,从而实现负载均衡
消息处理关键过程:
| 关键过程 | Nsqd收到消息 | 每个消息都会软拷贝到channels中 | channels会根据策略选择consumer投递消息 | 某个consumer收到消息 |
|---|---|---|---|---|
| eg1:A消息传递过程 | ||||
| eg2:B消息传递过程 |
框架
如上图所示,可以看出共有四个核心流程,每个核心流程用同一种颜色标识,每个核心流程由多个子操作构成。
| 流程 | 颜色标识 | 子操作 | 总结 |
|---|---|---|---|
| Nsqd启动流程 | 启动配置、启动监听 | ||
| 接受消息流程 | 消息会写入topic和channel中 | ||
| 消息转发流程 | 有一套client和Nsqd的建连及通信机制来高效支持msg的转发。 | ||
| 消息超时重试流程 | 通过特定扫描算法,保证高效低延迟进行重试或者延迟msg的处理。 |
原理
Nsqd如何优雅启动?
svc框架
wg框架
流程流程
Nsqd如何优雅退出?
消息是如何传递的?
第一步:接受HTTP消息,并将消息写入topic
第二步: 传递二:从topic取出传递到channel
** 第三步:建立TCP连接,consumer消费消息**
nsq与consumer交互流程图
消息如何保证至少投递成功一次?
采用等待定时器触发扫描而非不断轮询的方法避免了函数持续执行影响性能。
各MQ对比
| 类型 | NSQ | Kafka | Rocketmq |
|---|---|---|---|
| 消息吞吐量 | 高(十万级别) | 高(十万级别) | 中(万级别) |
| 消息可靠性 | 低(基于重试+本地文件backend) | 中等(基于副本机制保证) | 较高(基于事务保证) |
| 延时队列 | 支持 | 不支持 | 支持 |
| 支持重试 | 支持 | 不支持(不支持ack方式重试,只能server本身去重试) | 支持 |
| 资源成本 | 低(无replication机制需要维护controller,基本无额外损耗) | 中 | 中 |
| 写入性能 | 高 | 中 | 低 |
| 读写延迟 | 低 | 中 | 中 |
| 有序性 | 无法保证 | 局部有序 | 局部有序 |
| 消息投递方式 | push | pull | push+pull |
| 适用场景 | 大规模数据处理、实时流处理,对实时性要求高,可接受部分丢失的场景。 | 大规模数据处理、实时流处理,如可靠性要求高的日志场景。 | 大规模数据处理,实时处理,如可靠性要求高的实时业务场景。 |
思考
-
每种MQ都有其适用的业务场景,应根据业务场景的特点和不同的发展阶段去灵活选型。
-
NSQ作为一种用基于Go语言的分布式实时消息平台,整体代码架构设计非常优雅和巧妙,如启动\退出机制、消息可靠传递机制等值得学习和思考,另外类似redis过期机制的probabilistic思想,对于提升系统性能的也有非常大的参考意义,整体来说NSQ作为源码学习收益匪浅。