nats 是一種高性能、輕量級的分佈式消息系統,專為雲原生架構設計。以簡單性、高性能、低延遲聞名,適用於構建分佈式系統和微服務架構。
NATS的核心特性
簡單易用:
NATS的設計理念之一是保持簡單,無需複雜的配置和管理。NATS 使用簡單的主題(subjects)來實現消息的發佈和訂閲。
高性能:
NATS優化了內存管理和網絡性能,處理消息高吞吐量、低延遲。在快速響應系統中表現極出色。支持每秒百萬級消息傳輸。
高可擴展性:
NATS支持橫向擴展,能夠通過增加節點來增加系統的容量,並且具備較強的容錯能力。即使一個節點出現故障,其他節點仍然可以繼續工作,確保系統的高可用性。
支持多種傳輸協議:
除了標準的 TCP 連接外,NATS 還支持 WebSocket 和 HTTP/2 協議。這為應用提供了靈活的選擇,特別是在需要 Web 集成或者不同協議支持時。
強大的消息路由:
NATS支持多個發佈者和訂閲者的消息路由。消息可以通過主題(subjects)進行分類,訂閲者訂閲特定主題,發佈者向這些主題發佈消息,從而實現靈活的消息分發和消費。
容錯和高可用性:
NATS採用集羣和複製機制,確保系統在節點故障時依然能保證消息的傳遞和高可用性。通過集羣模式,NATS 可以在多個實例之間共享消息負載,並自動恢復服務。
支持持久化(可選) :
雖然NATS本身是一個內存為主的消息隊列,通過JetStream擴展,提供消息持久化的選項,支持將消息存儲在磁盤上,適用於需要可靠消息傳遞的場景。
安全性:
NATS支持 TLS 加密、認證和授權,確保消息傳遞過程中的數據安全。此外,它還可以與外部的身份驗證系統進行集成,確保只有經過授權的用户能夠訪問系統。
隊列組模式:
NATS支持隊列組模式,允許多個訂閲者共享消息負載,確保每個消息只被組中的一個消費者處理
監控與可觀測性:
監控工具集成:NATS 提供了豐富的監控功能,可以與 Prometheus 等監控工具集成,實時監控系統狀態和性能指標。
系統消息與事件:NATS 會發布系統消息(如客户端連接事件、服務器狀態等),可以用於構建監控和異常檢測工具。
NATS 的底層實現
訂閲表:
NATS 使用訂閲表(Subscription Table)來管理客户端的訂閲關係:
Subject Subscription:將客户端訂閲的主題映射到對應的訂閲者列表。
Queue Group:在隊列組模式下,訂閲表會將同一隊列組的訂閲者視為一個邏輯單元,消息只會分發給隊列組中的一個訂閲者。
訂閲表是一個hash字典,key是主題,value是訂閲者的列表。
消息數據結構:
NATS 的消息(Msg)是其核心數據結構,包含以下部分:
Subject:消息的主題,用於標識消息的類型或目標。
Reply:可選的回覆主題,用於請求-響應模式。
Payload:消息的實際負載,最大大小由 max_payload 參數限制。
Headers:可選的消息頭,用於攜帶元數據。
內存和緩存:
NATS 使用內存來緩存消息和訂閲信息,以提高性能:
Pending Messages:未確認的消息緩存在內存中,直到被確認或超時。
Max Pending:通過 max_pending 參數限制每個連接的緩存大小,防止內存佔用過高。
集羣和分佈式存儲:
在集羣模式下,NATS 使用以下機制來管理分佈式存儲:
Leader Election:通過 Raft 協議選舉流的領導者,確保數據一致性。
Replication:數據在集羣節點間進行復制,以提高可用性和容錯能力。
消息路徑追蹤:
NATS 提供消息路徑追蹤功能,用於監控消息的傳輸路徑和延遲。這一功能通過消息頭和日誌記錄實現。
消息傳遞的基本流程
1. 在 NATS 中,消息傳遞主要涉及以下三個角色:
發佈者(Publisher):向 NATS 服務器發送消息的客户端。
訂閲者(Subscriber):從 NATS 服務器接收消息的客户端。
NATS 服務器(Broker):負責消息的接收、存儲和分發。
2. 消息傳遞的步驟
訂閲者訂閲主題:
訂閲者向 NATS 服務器發送 SUB 命令,指定要監聽的主題(Subject)。
NATS 服務器將訂閲者的信息存儲在訂閲表中,以便後續分發消息。
發佈者發佈消息:
發佈者向 NATS 服務器發送 PUB 命令,指定目標主題和消息負載。
NATS 服務器接收消息,並將其存儲在內存中(或持久化存儲中,如果啓用了 JetStream)。
服務器分發消息:
NATS 服務器根據訂閲表查找所有訂閲了該主題的訂閲者。
將消息分發給每個訂閲者。
訂閲者接收消息:
訂閲者通過 MSG 命令從 NATS 服務器接收消息。
訂閲者處理消息後,確認消息已接收(如果是持久化消息,如 JetStream)。
消息傳遞的關鍵機制
1. 主題(Subject)
NATS 使用主題來組織消息。
主題是簡單的字符串,例如 test.subject 或 events.*。
NATS 支持通配符(* 和 >):
*:匹配單級主題,例如 events.* 匹配 events.order。
>:匹配多級主題,例如 events.> 匹配 events.order.created。
2. 訂閲表(Subscription Table)
NATS 服務器維護一個訂閲表,記錄每個主題的訂閲者信息。
當訂閲者訂閲一個主題時,服務器會將訂閲者添加到該主題的訂閲列表中。
當發佈者發佈消息時,服務器會根據訂閲表查找訂閲者,並將消息分發給他們。
3. 消息分發
NATS 支持兩種主要的消息分發模式:
發佈-訂閲模式(Pub/Sub):
每條消息會被分發給所有訂閲了該主題的訂閲者。
隊列組模式(Queue Groups):
多個訂閲者可以加入同一個隊列組,每條消息只會被隊列組中的一個訂閲者接收。
4. 消息確認(Acknowledge)
在普通 Pub/Sub 模式下,消息確認是可選的。
在 JetStream 中,消息確認是強制的。訂閲者需要顯式確認消息已處理,否則服務器會重試發送。
消息傳遞的性能優化
NATS 的消息傳遞機制設計得非常高效,主要體現在以下方面:
內存緩存:
NATS 服務器將消息緩存在內存中,以實現快速分發。
通過 max_pending 參數限制每個連接的緩存大小,防止內存佔用過高。
異步處理:
NATS 服務器和客户端都支持異步消息處理,減少延遲。
輕量級協議:
NATS 使用簡單的文本協議,減少解析開銷。
負載均衡:
在隊列組模式下,消息會被隨機分發給隊列組中的一個訂閲者,實現負載均衡。
消息傳遞的可靠性
NATS 提供了多種機制來確保消息傳遞的可靠性:
持久化存儲(JetStream):
如果啓用了 JetStream,消息會被持久化存儲到磁盤,防止消息丟失。
支持消息重放和持久化訂閲。
消息確認(Acknowledge):
訂閲者處理完消息後,需要向服務器發送確認(Ack)。
如果消息未確認,服務器會重試發送。
集羣和冗餘:
NATS 支持集羣模式,通過 Raft 協議實現數據的複製和一致性。
在集羣中,消息會被複制到多個節點,提高容錯能力。