golang消息系統nats的消息傳遞模型介紹

nats的消息傳遞模型


What is NATS

nats是一個go語言開發的開源的、輕量、高性能的原生消息系統。nats消息由主題處理,不依賴於網絡位置。它提供了應用程序或服務與底層物理網絡之間的抽象層。數據被編碼並作爲消息,由發佈者發送。消息由一個或多個訂閱者接收、解碼和處理。
NATS使程序可以很容易地跨不同的環境、語言、雲提供商和內部系統進行通信。客戶機通常通過單個URL連接到NATS系統,然後向主題訂閱或發佈消息。通過這種簡單的設計,NATS允許程序共享通用的消息處理代碼,隔離資源和相互依賴。

本文主要介紹介紹nats有哪些消息傳遞模型

主題式消息(Subject-Based Messaging)

從根本上說,NATS是關於發佈和監聽消息的。這兩者在很大程度上都依賴於消息的主題。簡單地說,subject就是一串字符,它們是發佈者和訂閱者可以用來查找彼此的名稱。

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-yt2mjzAJ-1575368779752)(./1574918652719.png)]

主題的層次結構

.字符用於創建主題層次結構。例如,一個世界時鐘應用程序可能定義以下內容來邏輯地分組相關的主題:

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.easttime.us.east.atlanta。而time.us.*只會匹配time.us.east,因爲它不能匹配一個以上的token。
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-t8CBTghh-1575368779754)(./1574919625783.png)]

發佈訂閱(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可以是一個空消息,一個沒有有效負載的消息。
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-FUPbpdQq-1575368779756)(./1575005488679.png)]

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))
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章