Go-Nsq资料整理和学习笔记

写在前面:

NSQ版本 : v1.2.0
在源码层面,完整阅读了一个GO-Lang实际的项目-NSQ,目标是让自己从学习、熟悉Go语法,进阶到深入理解GO,理解实现工程中GO的使用和组织。现把这大半个月阅读的文章和学习笔记做一些整理。

一. NSQ官网(nsq.io)

这个没啥好说的,官方文档是最权威的.逐页看就是,后来发现一个中文的:

中文文档-0.3.5

其他介绍参考文档
//www.greatytc.com/p/c47e0350bb2e
https://www.cnblogs.com/li-peng/category/1537661.html
https://segmentfault.com/a/1190000012362544
http://blog.rayxxzhang.com/index.html
http://luodw.cc/2017/04/14/nsqd/
https://www.cnblogs.com/li-peng/p/11435083.html


二. NSQ依赖

NSQ已经改成go modules来管理包.


module github.com/nsqio/nsq

require (
    github.com/BurntSushi/toml v0.3.1
    github.com/bitly/go-hostpool v0.0.0-20171023180738-a3a6125de932
    github.com/bitly/timer_metrics v0.0.0-20170606164300-b1c65ca7ae62
    github.com/blang/semver v3.5.1+incompatible
    github.com/bmizerany/perks v0.0.0-20141205001514-d9a9656a3a4b
    github.com/davecgh/go-spew v1.1.1 // indirect
    github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db
    github.com/judwhite/go-svc v1.0.0
    github.com/julienschmidt/httprouter v1.2.0
    github.com/mreiferson/go-options v0.0.0-20190302015348-0c63f026bcd6
    github.com/nsqio/go-diskqueue v0.0.0-20180306152900-74cfbc9de839
    github.com/nsqio/go-nsq v1.0.7
    github.com/pmezard/go-difflib v1.0.0 // indirect
    github.com/stretchr/testify v1.2.2 // indirect
    golang.org/x/sys v0.0.0-20181221143128-b4a75ba826a6 // indirect
)

可以看出基本大部分都是自己的依赖(其中nsqio和bilty部分),都是一些小的工具包.
唯一需要注意的是httprouter,nsq用它来装饰处理http请求.

package 简要说明
go-difflib python迁移的对比包
go-diskqueue 官方提供的文件记录包-用于在channel满的时候,作为backendQueue保存到文件中
go-hostpool 把主机信息池化
go-nsq NSQ官方提供的客户端实现
go-options 读取命令行配置工具
go-spew 格式化打印
go-svc 用于包装为系统服务(会识别环境)
http-router 轻量级http请求路由
perks 产生图标的工具包
semver 解析版本字符串的工具(如1.0.3-beta)
snappy 压缩算法包
x/sys GO官方扩展包
timer_metrics 计时测量
toml nsq使用toml文件格式作为配置持久化

三. Go-nsq (V1.0.7)

  • 首先要理解go-nsq作为官方提供的客户端,怎么使用,先堆一堆参考文档:

https://nicksors.cc/2018/08/15/%E6%B6%88%E6%81%AF%E9%98%9F%E5%88%97%E4%B9%8B%E3%80%8A02-NSQ%E5%AE%9E%E8%B7%B5%E7%AF%87%E3%80%8B.html
https://cloud.tencent.com/developer/article/1070860
https://segmentfault.com/a/1190000009194607
https://lihaoquan.me/2016/6/20/using-nsq.html
https://juejin.im/post/5d3e3a44f265da1bae39439a
https://www.cnblogs.com/li-peng/p/11435083.html

  • 其次是看源码,代码不多.我理解核心还是搞懂Conn,Delegate,Consumer,Producer之间的关系.默认的Consumer和Producer都实现了ConnDelegate接口,用来把连接conn上的事件传导给具体的
    Consumer和Producer去完成.

Delegate使得它们之间的关系解耦,避免了Conn和Consumer双向引用.

  • 测试代码:
    1. Config_test.go | Go语言可以很方便用数组形式构造测试案例
    2. Producer_test.go | 测试生产者
    3. Consumer_test.go | 测试消费者

四. nsq-internal

nsq-internal是几个实现共用的一些工具包

package 简要说明
app 包含FloatArray和StringArray,用在解析命令参数
auth Authorization结构,用在权限控制(本次阅读忽略)
clusterinfo 用来外呼http请求,获取信息
dirlock 锁定目录(windows无效)
httpapi 带截止时间的http请求封装(主要和go-nsq中的不同)
lg 日志工具
pqueue 以Item为元素的优先级队列,其中Item.value是个空接口,用在diskBackend中.奇怪的是InflightQueue是用Message实现的一套.
protocol 用来表明自己能处理的tcp协议报文.(nsqd和nsqlookupd都有自己的实现)
quanltile 统计用的火焰图数据
statsd 登记统计信息的服务器调用简单包装
stringy nsq用的几个字符串函数工具包
test nsq对测试的工具包,其中FakeNetConn可以伪装为一个连接
util WaitGroupWrapper把普通的函数(无参数,无返回值)同步调用包装成异步调用
version 表明版本号(目前1.2.1)
writers BoundaryBufferedWriter和SpreadWriter两种实现

五. nsq-apps

由nsq提供的可执行程序的源码,除了nsqd、nsqlookup、nsqadmin这几个服务端封装外,基本都是用go-nsq(客户端)实现特定功能的命令行工具。

package 简要说明
nsq_stat 使用http_api实现对特定的topic,channel的监控(打印控制台)
nsq_tail 订阅消费特定Topic消息,实现对特定的channel监控(打印控制台)
nsq_to_file 订阅消费特Channel消息,记录到文件
nsq_to_http 把Nsq消息通过http发出
nsq_to_nsq 桥接Nsq消息-转发
to_nsq 读取文件中message,发送到nsqd中

六. nsq-nsqd

NSQD是整个消息中间件的核心,所幸很多人都分析了,这里不需要再累述,看代码的同时,结合牛人的文章即可:

NSQ源码分析之概述(不错)
http://luodw.cc/2016/12/08/nsq01/
http://luodw.cc/2016/12/13/nsqlookupd/
http://luodw.cc/2017/04/14/nsqd/
nsq源码分析
https://www.cnblogs.com/hlxs/p/11445103.html
nsq源码学习
https://segmentfault.com/a/1190000012362544
NSQ源码剖析之nsqd(不错)
http://shanks.leanote.com/post/NSQ%E6%BA%90%E7%A0%81%E5%89%96%E6%9E%90%E4%B9%8BNSQD
nsq源码阅读(nsqd)(不错)
http://sksun.com.cn/2018/06/13/nsq%E6%BA%90%E7%A0%81%E9%98%85%E8%AF%BB-nsqd/
http://sksun.com.cn/2018/06/12/nsq%E6%BA%90%E7%A0%81%E9%98%85%E8%AF%BB-nsqlookupd/

  • 结构:
    NSQ结构是多层次的,NSQD有个topicMap,记录所有的Topic;topic有个channelMap,记录所有的Channel,Channel有个clients,记录所有的消费者.这些结构都有一个ctx指针,指向NSQD自身.

  • 启动:
    先启动TcpServer,HttpServer,处理报文
    再启动queueScanLoop(动态调整queueScanWorker的数目,处理in-flight和deffered queue的消息),lookupLoop(和nsqlookupd服务器连接),statsdLoop(和stasd服务器连接)

  • 消息处理:
    略,上面文章讲太多了..

  • 代码阅读中一些疑问:

  1. Topic创建时机?
    在Publish时,如果不存在,会自动创建.

  2. Channel创建时机?
    在Sub是,如果不存在,会自动创建.

  3. deferredMessages与inFlightMessages
    Channel内部维护2个队列,infight表示正在和client交互(等到client返回FIN才删除,保证消息至少被接收一次),deferred表示可以提前给nsqd发送message,等到时间到才合法.

  4. BackendQueue与ephemeral
    如果声明为ephemera,则如果消息超过infight队列长度,就会被丢弃.而BackendQueue可以用go-diskqueue包提供的方法保存到文件中.

  5. 消息有序性?
    NSQ不保证,可能无序(requeue机制,多节点机制)

  6. 丢消息?
    如果异常退出,infightMsg可能会丢

  7. RDY意义:
    RDY是订阅方告知NSQD服务器自身处理能力的方法,这样避免服务器快速给客户端发消息,客户端处理不过来的情况(Rx中背压)


七. nsq-nsqlookupd

与nsqd类似,nsqlookupd通过TCP和Http两种方式向外提供服务.

  1. RegistrationDB
    登记nsq信息的内存DB,使用registrationMap,ProducerMap两层MAP,并且实现了add,remove,find,这些操作,便于上层进行调用.
  2. lookup_protocol_v1
    提供tcp服务,只有Ping,Identify,Register,Unregister四个方法,也就是说,只有nsqd才会使用tcp和nsqlookupd连接通讯.(Category有topic和channel,client三种)
  3. http
    提供http服务,消费者使用nsqlookupd提供的方法感知,而producer是需要直连nsqd的.
    提供了"/topic/create","/topic/delete"这种,不是给nsqd用的,是给go-nsq客户端或者nqadmin手工删除topic用的.

八. nsq-nsqadmin

admin相对比较简单(go部分),通过notify构造AdminAction向外主动POST,或者通过http向外提供服务.而且,它本身并不存储任何数据,需要时,都是使用httpServer中的client向nslookupd或者nsqd查询(类似于gateway).这里用了internal/clusterinfo,先调用nslookupd,不行就直接请求nsqd(需要遍历所有的nsqd,为了效率,还是搭建nslookupd吧).
前端页面部分用了backdone+jquery+gulp.未看...

九. 其他

  1. bench目录: 用python写的批量测试用例
  2. 有赞nsq (https://github.com/youzan/nsq)
    发现有赞Fork了一个分支,并做了改进,有机会再细看一下...

How we redesign the NSQ-Smart Client

How we redesigned the NSQ - NSQ重塑之详细设计
视频观看

How we redesigned the NSQ - 其他特性及未来计划

有赞NSQ多集群多机房设计

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,185评论 6 503
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,652评论 3 393
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,524评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,339评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,387评论 6 391
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,287评论 1 301
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,130评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,985评论 0 275
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,420评论 1 313
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,617评论 3 334
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,779评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,477评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,088评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,716评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,857评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,876评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,700评论 2 354