Go nsq实践
NSQ
NSQ是Go语言编写的一个开源的实时分布式内存消息队列,其性能十分优异。 NSQ的优势有以下优势:
- NSQ提倡分布式和分散的拓扑,没有单点故障,支持容错和高可用性,并提供可靠的消息交付保证
- NSQ支持横向扩展,没有任何集中式代理。
- NSQ易于配置和部署,并且内置了管理界面。
与其他mq的比较:
NSQ 是由四个重要组件构成:
- nsqd :一个负责接收、排队、转发消息到客户端的守护进程
- nsqlookupd :管理拓扑信息并提供最终一致性的发现服务的守护进程
- nsqadmin :一套 Web 用户界面,可实时查看集群的统计数据和执行各种各样的管理任务
- utilities :常见基础功能、数据流处理工具,如 nsq_stat、nsq_tail、nsq_to_file、nsq_to_http、nsq_to_nsq、to_nsq
NSQ 的主要特点如下:
- 具有分布式且无单点故障的拓扑结构 支持水平扩展,在无中断情况下能够无缝地添加集群节点
- 低延迟的消息推送,参见官方提供的性能说明文档
- 具有组合式的负载均衡和多播形式的消息路由
- 既擅长处理面向流(高吞吐量)的工作负载,也擅长处理面向 Job 的(低吞吐量)工作负载
- 消息数据既可以存储于内存中,也可以存储在磁盘中
- 实现了生产者、消费者自动发现和消费者自动连接生产者,参见 nsqlookupd
- 支持安全传输层协议(TLS),从而确保了消息传递的安全性
- 具有与数据格式无关的消息结构,支持 JSON、Protocol Buffers、MsgPacek 等消息格式
- 非常易于部署(几乎没有依赖)和配置(所有参数都可以通过命令行进行配置)
- 使用了简单的 TCP 协议且具有多种语言的客户端功能库
- 具有用于信息统计、管理员操作和实现生产者等的 HTTP 接口
- 为实时检测集成了统计数据收集器 StatsD
- 具有强大的集群管理界面,参见 nsqadmin
为了达到高效的分布式消息服务,NSQ 实现了合理、智能的权衡,从而使得其能够完全适用于生产环境中,具体内容如下:
- 支持消息内存队列的大小设置,默认完全持久化(值为 0),消息即可持久到磁盘也可以保存在内存中
- 保证消息至少传递一次, 以确保消息可以最终成功发送
- 收到的消息是无序的, 实现了松散订购
- 发现服务 nsqlookupd 具有最终一致性, 消息最终能够找到所有 Topic 生产者
官方和第三方还为 NSQ 开发了众多客户端功能库,如官方提供的基于 HTTP 的 nsqd 、Go 客户端 go-nsq 、Python 客户端 pynsq 、基于 Node.js 的 JavaScript 客户端 nsqjs 、异步 C 客户端 libnsq 、Java 客户端 nsq-java 以及基于各种语言的众多第三方客户端功能库。更多客户端功能库, 请读者点击这里查看。
NSQ架构
NSQ工作模式
Topic和Channel
每个nsqd实例旨在一次处理多个数据流。这些数据流称为“topics”
,一个topic
具有1个或多个“channels”
。每个channel
都会收到topic
所有消息的副本,实际上下游的服务是通过对应的channel
来消费topic
消息。
topic
和channel
不是预先配置的。topic
在首次使用时创建,方法是将其发布到指定topic
,或者订阅指定topic
上的channel
。channel
是通过订阅指定的channel
在第一次使用时创建的。
topic
和channel
都相互独立地缓冲数据,防止缓慢的消费者导致其他chennel
的积压(同样适用于topic
级别)。
channel
可以并且通常会连接多个客户端。假设所有连接的客户端都处于准备接收消息的状态,则每条消息将被传递到随机客户端。例如:
总而言之,消息是从topic -> channel
(每个channel接收该topic的所有消息的副本)多播的,但是从channel -> consumers
均匀分布(每个消费者接收该channel的一部分消息)。
nsqlookupd,nsqd与客户端中消费者和生产者的关系
消费者
消费者有两种方式与nsqd建立连接
- 消费者直连nsqd,这是最简单的方式,缺点是nsqd服务无法实现动态伸缩了。
- 消费者通过http查询nsqlookupd获取该nsqlookupd上所有nsqd的连接地址,然后再分别和这些nsqd建立连接(官方推荐的做法),但是客户端会不停的向nsqlookupd查询最新的nsqd地址目录
还是看图更直接些 ,官方的消费者模型:
生产者
生产者必须直连nsqd去投递message。
这里有一个问题就是如果生产者所连接的nsqd挂了,那么message就会投递失败,所以在客户端必须自己实现相应的备用方案。
安装
官方下载页面根据自己的平台下载并解压即可。
相关操作:
1.在一个shell里面启动nsqlookupd
1
|
$ nsqlookupd |
2.在另一个shell里面启动nsqd
1
|
$ nsqd --lookupd-tcp-address=127.0.0.1:4160 |
3.在另一个shell里面启动nsqadmin
1
|
$ nsqadmin --lookupd-http-address=127.0.0.1:4161 |
4.发布初始消息
1
|
$ curl -d 'hello world 1' 'http://127.0.0.1:4151/pub?topic=test' |
5.在另外一个shell里面启动nsq_to_file,消费消息,并存入本地文件
1
|
$ nsq_to_file --topic=test --output-dir=/tmp --lookupd-http-address=127.0.0.1:4161 |
6.发更多消息到nsqd
1
2
|
$ curl -d 'hello world 2' 'http://127.0.0.1:4151/pub?topic=test' $ curl -d 'hello world 3' 'http://127.0.0.1:4151/pub?topic=test' |
7.打开web浏览器验证工作是否正常 http://127.0.0.1:4171/若要查看nsqadmin
UI和见统计信息。另外,检查日志文件的内容(test.*.log
)写信给/tmp
.