nats的消息傳遞模型 @[toc] What is NATS nats是一個go語言開發的開源的、輕量、高性能的原生消息系統。nats消息由主題處理,不依賴於網路位置。它提供了應用程式或服務與底層物理網路之間的抽象層。數據被編碼並作為消息,由發佈者發送。消息由一個或多個訂閱者接收、解碼和處理。 N ...
目錄
- nats的消息傳遞模型
- What is NATS
- 主題式消息(Subject-Based Messaging)
- 發佈訂閱(Publish-Subscribe)
- 請求應答(Request-Reply)
- 隊列組
- Acknowledgements
nats的消息傳遞模型
@
What is NATS
nats是一個go語言開發的開源的、輕量、高性能的原生消息系統。nats消息由主題處理,不依賴於網路位置。它提供了應用程式或服務與底層物理網路之間的抽象層。數據被編碼並作為消息,由發佈者發送。消息由一個或多個訂閱者接收、解碼和處理。
NATS使程式可以很容易地跨不同的環境、語言、雲提供商和內部系統進行通信。客戶機通常通過單個URL連接到NATS系統,然後向主題訂閱或發佈消息。通過這種簡單的設計,NATS允許程式共用通用的消息處理代碼,隔離資源和相互依賴。
本文主要介紹介紹nats有哪些消息傳遞模型
主題式消息(Subject-Based Messaging)
從根本上說,NATS是關於發佈和監聽消息的。這兩者在很大程度上都依賴於消息的主題。簡單地說,subject就是一串字元,它們是發佈者和訂閱者可以用來查找彼此的名稱。
主題的層次結構
.
字元用於創建主題層次結構。例如,一個世界時鐘應用程式可能定義以下內容來邏輯地分組相關的主題:
time.us
time.us.east
time.us.east.atlanta
time.eu.east
time.eu.warsaw
通配符
NATS提供了兩個通配符,可以代替點分隔的主題中的一個或多個元素。訂閱者可以使用這些通配符偵聽多個主題,但發佈者將始終使用完全指定的主題,而不使用通配符。
匹配單個token
*
例如,如果一個應用程式想要監聽東部時區,他們可以訂閱time.*.east來匹配time.us.east和time.eu.east。
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-WSM6vGXO-1575368779753)(./1574919076868.png)]
匹配多個tokens
>
>
將匹配一個或多個tokens,並且只能出現在主題的末尾。例如,time.us.>
將匹配time.us.east
和time.us.east.atlanta
。而time.us.*
只會匹配time.us.east
,因為它不能匹配一個以上的token。
發佈訂閱(Publish-Subscribe)
NATS實現了一對多通信的發佈-訂閱消息分發模型。發佈者發送關於主題的消息,而監聽該主題的任何活動訂閱者將接收該消息。訂閱者還可以註冊對通配符主題感興趣的內容,通配符的工作原理有點像正則表達式(但只有一點點)。這種一對多的模式有時被稱為扇出(fan-out)。
example
pub
nc, _ := nats.Connect(nats.DefaultURL)
defer nc.Close()
nc.Publish("foo", []byte("Hello World!"))
sub
nc, _ := nats.Connect(nats.DefaultURL)
defer nc.Close()
nc.Subscribe("foo", func(m *nats.Msg) {
fmt.Printf("Received a message: %s\n", string(m.Data))
})
請求應答(Request-Reply)
請求-應答是現代分散式系統中的一種常見模式。發送請求時,應用程式要麼使用特定超時等待響應,要麼非同步接收響應。現代系統日益增加的複雜性需求,許多技術需要額外的組件來完成完整的特性集。
NATS通過其核心通信機制(發佈和訂閱)支持這種模式。請求在給定的主題上與應答主題一起發佈,應答者偵聽該主題並將響應發送到應答主題。應答主題通常是一個稱為_INBOX的主題,它將被動態地定向回請求者,而不考慮任何一方的位置。
NATS的能力甚至允許多個響應,其中第一個響應被利用,而系統有效地丟棄了附加的響應。這允許一個複雜的模式有多個響應器減少響應延遲和抖動。
example
nc, _ := nats.Connect(nats.DefaultURL)
defer nc.Close()
nc.Subscribe("foo", func(m *nats.Msg) {
nc.Publish(m.Reply, []byte("I will help you"))
})
reply, _ := nc.Request("foo", []byte("help"), 50*time.Millisecond)
fmt.Println(string(reply.Data))
隊列組
NATS提供了一個稱為分散式隊列的內置負載平衡特性。使用隊列訂閱者將在一組訂閱者之間平衡消息傳遞,這些訂閱者可用於提供應用程式容錯和大規模工作負載處理。
要創建隊列訂閱,只需要訂閱者註冊隊列名稱。具有相同隊列名稱的所有訂閱者組成隊列組。不需要任何配置。當註冊主題上的消息發佈時,將隨機選擇組中的一個成員來接收消息。儘管隊列組有多個訂閱者,但每個消息僅被一個訂閱者使用。
NATS的一個重要特性是隊列組是由應用程式及其隊列訂閱者定義的,而不是在伺服器配置上定義的。
隊列訂閱者是擴展服務的理想對象。向上擴展與運行另一個應用程式一樣簡單,向下擴展是使用一個信號終止應用程式,該信號將耗盡正在運行的請求。這種靈活性和缺少任何配置更改使NATS成為一種優秀的服務通信技術,可以與所有平臺技術一起工作。
example
nc, _ := nats.Connect(nats.DefaultURL)
defer nc.Close()
received := 0
nc.QueueSubscribe("foo", "worker_group", func(_ *nats.Msg) {
received++
})
Acknowledgements
在具有最多一次語義的系統中,有時會丟失消息。如果您的應用程式正在執行請求-應答,那麼它應該使用超時來處理任何網路或應用程式故障。在請求上設置超時並使用處理超時的代碼總是一個好主意。在發佈事件或數據流時,確保消息傳遞的一種方法是將其轉換為帶有確認消息(ACKs)概念的請求-應答。在NATS中,ACK可以是一個空消息,一個沒有有效負載的消息。
example
nc, _ := nats.Connect(nats.DefaultURL)
defer nc.Close()
nc.Subscribe("foo", func(m *nats.Msg) {
//nc.Publish(m.Reply, []byte("I will help you"))
m.Respond([]byte(""))
})
reply, _ := nc.Request("foo", []byte("help"), 50*time.Millisecond)
fmt.Println("ack:", string(reply.Data))