天天看點

Go nsq實踐

NSQ

NSQ是Go語言編寫的一個開源的實時分布式記憶體消息隊列,其性能十分優異。 NSQ的優勢有以下優勢:

  1. NSQ提倡分布式和分散的拓撲,沒有單點故障,支援容錯和高可用性,并提供可靠的消息傳遞保證
  2. NSQ支援橫向擴充,沒有任何集中式代理。
  3. NSQ易于配置和部署,并且内置了管理界面。

與其他mq的比較:

Go nsq實踐

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工作模式

Go 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

可以并且通常會連接配接多個用戶端。假設所有連接配接的用戶端都處于準備接收消息的狀态,則每條消息将被傳遞到随機用戶端。例如:

Go nsq實踐

總而言之,消息是從

topic -> channel

(每個channel接收該topic的所有消息的副本)多點傳播的,但是從

channel -> consumers

均勻分布(每個消費者接收該channel的一部分消息)。

nsqlookupd,nsqd與用戶端中消費者和生産者的關系

消費者

消費者有兩種方式與nsqd建立連接配接

  • 消費者直連nsqd,這是最簡單的方式,缺點是nsqd服務無法實作動态伸縮了。
  • 消費者通過http查詢nsqlookupd擷取該nsqlookupd上所有nsqd的連接配接位址,然後再分别和這些nsqd建立連接配接(官方推薦的做法),但是用戶端會不停的向nsqlookupd查詢最新的nsqd位址目錄

    還是看圖更直接些 ,官方的消費者模型:

Go nsq實踐

生産者

生産者必須直連nsqd去投遞message。

這裡有一個問題就是如果生産者所連接配接的nsqd挂了,那麼message就會投遞失敗,是以在用戶端必須自己實作相應的備用方案。

安裝

官方下載下傳頁面根據自己的平台下載下傳并解壓即可。

相關操作:

 1.在一個shell裡面啟動nsqlookupd

1

$ nsqlookupd

 2.在另一個shell裡面啟動nsqd

$ nsqd --lookupd-tcp-address=127.0.0.1:4160

 

 3.在另一個shell裡面啟動nsqadmin

$ nsqadmin --lookupd-http-address=127.0.0.1:4161

 4.釋出初始消息

$ curl -d 

'hello world 1'

'http://127.0.0.1:4151/pub?topic=test'

  

 5.在另外一個shell裡面啟動nsq_to_file,消費消息,并存入本地檔案

$ nsq_to_file --topic=test --output-dir=/tmp --lookupd-http-address=127.0.0.1:4161

 6.發更多消息到nsqd

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'

Docker叢集部署及實踐