1、介紹:
NATS是一個開源、輕量級、高性能的分佈式消息中間件,實現了高可伸縮性和優雅的Publish/Subscribe模型,使用Golang語言開發。NATS的開發哲學認爲高質量的QoS應該在客戶端構建。故只建立了Request-Reply,不提供 1.持久化 2.事務處理 3.增強的交付模式 4.企業級隊列。
2、NATS消息傳遞模型
NATS支持各種消息傳遞模型,包括:
- 發佈訂閱(Publish Subscribe)
- 請求回覆(Request Reply)
- 隊列訂閱(Queue Subscribers )
2.1、發佈訂閱(Publish Subscribe)
NATS將publish/subscribe消息分發模型實現爲一對多通信,發佈者在Subject上發送消息,並且監聽該Subject在任何活動的訂閱者都會收到該消息
2.2、請求響應(Request Reply)
NATS支持兩種請求響應消息:點對點或多對多。點對點涉及最快或首先響應。在一對多的消息交換中,需要限制請求響應的限制。
在Request Reply過程中,發佈請求發佈帶有響應主題的消息,期望對該subject做出響應操作
隊列訂閱&分享工作(Queue Subscribers & Sharing Work)
NATS提供稱爲隊列訂閱的負載均衡功能,雖然名字爲queue(隊列)但是並不是我們所認爲的那樣。他的主要功能是將具有相同queue名字的subject進行負載均衡。使用隊列訂閱功能消息發佈者不需要做任何改動,消息接受者需要具有相同的對列名
3、NATS提供的功能
- 純粹的發佈訂閱模型(Pure pub-sub)
- 服務器集羣(Cluster mode server)
- 自動精簡訂閱者(Auto-pruning of subscribers)
- 基於文本協議(Text-based protocol)
- 多服務質量保證(Multiple qualities of service - QoS)
- 發佈訂閱(Publish Subscribe)
4、NATS Streaming介紹
- 增強消息協議(Enhanced message protocol)
- 消息/事件持久化(Message/event persistence)
- 至少一次數據傳輸(At-least-once-delivery)
- Publisher限速(Publisher rate limiting)
- Subscriber速率匹配(Rate matching/limiting per subscriber)
- 按主題重發消息(Historical message replay by subject)
- 持續訂閱(Durable subscriptions)
5、NATS與NATS Streaming
- 弄清楚NATS與NATS Streaming各自的職責,區別和他們之間的交互至關重要;簡單來說,NATS實現了基本的發佈/訂閱模型,NATS Streaming提供的則是更高級的特性,包括ACK,持久化等;
- 理解NATS和NATS Streaming的區別最重要的是,NATS Streaming並不是在NATS上功能的增強,它與NATS之間仍然通過Client進行交互,他們的部署是獨立的,NATS Streaming以類似於sidecar的形式服務於NATS
5.1、NATS重點關注
詳細介紹參考:https://www.nats.io/documentation/server/gnatsd-intro/
認證授權 :
- NATS提供基於Token和用戶名/密碼的兩種客戶端認證方式;
- 提供基本的針對主題訂閱和發佈的權限管理;
高可用集羣:NATS部署高可用集羣非常的簡單,只需要在各個實例的配置文件中添加如下配置即可;其中集羣可單獨設置認證方式;
cluster {
host: '0.0.0.0'
port: 7248
routes = [
nats-route://192.168.59.103:7244
nats-route://192.168.59.103:7246
]
}
自動斷開不健康的客戶端連接:
NATS Server和Client之間會維持PING-PONG檢查,發現已斷開或不健康的連接會主動斷開;
這是一種保證Server長時間高效運行的策略;
相對簡單的監控界面
通過以下啓動參數可以提供一個簡單的web監控界面,但是功能很簡陋,需要進一步改善;爲了彌補不足,提供nats-top工具查看更詳盡的服務器信息;
-m your_port
單個推送消息大小限制
NATS單個消息的大小限制爲1M,基本上是可以滿足一般的數據傳輸的;
5.2、NATS Streaming
5.2.1、介紹
參考地址:https://www.nats.io/documentation/streaming/nats-streaming-intro/
瞭解NATS Streaming主要關注它爲NATS Server提供新特性;主要關注的有以下幾點:
1).At-least-once-delivery & Durable subscriptions
至少一次投遞和持久化,對於在分佈式場景下保證數據的一致性非常有用;
2).Historical message replay by subject & 全局客戶端ID唯一
可以選擇任意歷史節點開始訂閱恢復訂閱
3).多樣化持久化支持
默認將消息保存在內存中,同時支持file,mysql兩種持久化支持;
5.2.2、場景分析
場景一 高效傳輸(不保證一致性)
其實在我們使用NATS的初期就是使用的這種模式,主要用於在各個模塊信息同步(比如,個人信息的同步),在時效性上和一致性上要求不高;這種場景只需要創建NATS Cluster即可;
場景二 保證最終一致性
一致性的保證主要是通過NATS Streaming提供的特性來完成,在微服務架構中,跨服務的調用鏈經常存在,如何保證在下游服務不可用或失敗的情況下業務數據的一致性要求,NATS Streaming 提供的ACK機制和至少一次傳遞的特性就非常重要;甚至是要避免在NATS集羣宕機恢復過程中可能的數據不一致情況的發生;舉例的話,典型的場景包括支付和關鍵業務狀態的更新;
5.2.3、實踐方案介紹
場景一
在這種場景下,NATS的角色更多是高效傳輸層(transport),完成數據的異步傳輸;因此,只需要部署NATS集羣即可,並不需要Streaming提供的高級特性;套用以下模板,創建多節點的NATS集羣即可;
集羣部署demo(以一個節點配置爲例)
# Client port
port: 4222
# HTTP monitoring port
monitor_port: 4223
# 用戶
authorization {
users = [
{user: <<用戶名1>>,password: <<密碼1>>}
]
timeout: 1
}
# This is for clustering multiple servers together.
cluster {
# 集羣接口
port: 4224
# 集羣鏈接認證
authorization {
user: <<用戶名2>>
password: <<密碼2>>
timeout: 0.75
}
# 集羣信息
routes = [
nats-route://<<用戶名2>>:<<密碼2>>@nats-1:4224
nats-route://<<用戶名2>>:<<密碼2>>@nats-2:4224
]
}
場景二
由於場景二需要Streaming相關特性支持,所以,需要部署Streaming集羣;同時,根據NATS與NATS Streaming 之間獨特的工作方式,我們完全可以在場景一中部署的NATS集羣的基礎上進行NATS Streaming 的部署;也就是說,NATS Streaming集羣仍然連接此NATS集羣;
集羣部署demo(以一個節點配置爲例)
# NATS Streaming specific configuration
streaming {
id: stan-cluster
store: file
dir: store
nats_server_url: "<<NATS集羣地址>>"
# 只需要指定集羣名和節點名,實現自定發現
cluster {
node_id: "stan-1"
peers: ["stan-2", "stan-3"]
}
}
Streaming的節點數建議爲奇數,Streaming Server通過Raft算法選出leader節點;
總結:NATS使用過程中最顯著的感受是輕量,高效以及部署方便(詳盡的配置介紹);同時由於它較好的分佈式特性,在使用過程中從未出現意外宕機或者數據異常丟失的情況;
參考資料: