微服务中的异步消息通讯
前言
在上一篇文章中,我們說到了異步消息通訊,下面這篇文章呢,大部分內(nèi)容是翻譯來自于這篇微軟的文章,所以其內(nèi)容還是具有一定的理論指導(dǎo)意義的。
當(dāng)我們跨多個(gè)微服務(wù)進(jìn)行內(nèi)部通訊的時(shí)候,異步消息和事件驅(qū)動(dòng)至關(guān)重要。我們可能需要在不同的邊界上下文中進(jìn)行域模型的更新。
我們舉個(gè)例子,比如 eShop 這個(gè)項(xiàng)目中,Ording 服務(wù)在下單的時(shí)候要和 Catelog 服務(wù)進(jìn)行通訊進(jìn)行庫存的扣減操作,這個(gè)時(shí)候我們就需要一種方式來做這個(gè)事情,并且能夠在發(fā)生故障的時(shí)候也能正常工作,也就說需要進(jìn)行基于異步消息和最終一致性的通訊方式。
當(dāng)使用基于消息的通訊方式的時(shí)候,進(jìn)程中是采用的異步的方式通訊的。客戶端向某個(gè)服務(wù)發(fā)送消息,如果這個(gè)消息需要回復(fù),那么另一個(gè)服務(wù)會(huì)向客戶端發(fā)送一個(gè)不同的消息,并且客戶端會(huì)認(rèn)為該消息不會(huì)立即被接收到,并且不存在響應(yīng),這就是一種基于消息的通訊方式。
消息由標(biāo)題(name 或者 title)和內(nèi)容(Body)共同構(gòu)成。消息通常會(huì)通過一些異步協(xié)議進(jìn)行發(fā)送(如AMQP,kafka協(xié)議)。
異步消息通訊有兩種:一種是單接收者(端到端),另外一種是多接收者(廣播)。
如果有同學(xué)對消息隊(duì)列比較了解的話,這就是消息隊(duì)列的兩種典型使用方式。
基于消息的單接收者
單接收者也就是說是點(diǎn)到點(diǎn)的通訊,將消息使用隊(duì)列等方式從一點(diǎn)發(fā)送的另外一點(diǎn),并且該消息僅會(huì)被處理(消費(fèi))一次。這中間一個(gè)特殊情況就是,當(dāng)隊(duì)列在嘗試從故障中恢復(fù)時(shí)候,有可能會(huì)多次發(fā)送相同的消息,客戶端必須實(shí)現(xiàn)冪等性以便能夠處理相同的消息一次。
單接收器消息通訊的方式適用于將異步命令從一個(gè)微服務(wù)發(fā)送到另一個(gè)微服務(wù)。如下圖:
一旦開始使用了基于消息的通訊,你應(yīng)該避免將基于消息的通訊和同步的HTTP通訊混合起來。
注意:當(dāng)command來到客戶端應(yīng)用程序時(shí)候,它們可以實(shí)現(xiàn)為HTTP的同步命令。當(dāng)你需要更高的可擴(kuò)展性或者你業(yè)務(wù)流程中已經(jīng)使用了基于消息的方式時(shí),那么你就應(yīng)該使用基于消息的通訊方式。
基于消息的多接收者
多接收者是消息通訊中一種更加靈活的方式,你可能還需要使用 發(fā)布/訂閱 這種機(jī)制,以便于接收來自發(fā)送方或者其他微服務(wù)或者外部應(yīng)用程序的消息。 這樣,將來可以添加更多的其他消費(fèi)者用戶,而無需修改發(fā)送方的服務(wù)代碼。
當(dāng)你使用發(fā)布/訂閱這種通訊方式的時(shí)候,在發(fā)送端和訂閱端你也許會(huì)用到事件總線的接口。
異步事件驅(qū)動(dòng)通訊
當(dāng)使用異步事件驅(qū)動(dòng)通信時(shí), 一個(gè)微服務(wù)當(dāng)域模型發(fā)生更新時(shí),會(huì)發(fā)布一個(gè)集成事件,然后另外一個(gè)微服務(wù)可能需要關(guān)注這個(gè)事件,比如 eShop 中,當(dāng) product catelog 微服務(wù)發(fā)生一個(gè)價(jià)格變動(dòng)的時(shí)候。另外的微服務(wù)需要訂閱這個(gè)事件,這樣就可以以異步的方式來接收這個(gè)事件。然后當(dāng)事件觸發(fā)的時(shí)候,訂閱端就可以更新自己的 Domain Model,從而集成發(fā)送端的事件。 事件總線(Event Bus)可以設(shè)計(jì)為一個(gè)抽象類或接口,集成API 訂閱或取消訂閱事件和發(fā)布事件。事件總線還可以有一個(gè)或多個(gè)實(shí)現(xiàn)基于任何進(jìn)程間消息傳遞代理,像一個(gè)消息隊(duì)列或服務(wù)總線支持異步通信和發(fā)布/訂閱模型。
如果事件驅(qū)動(dòng)中集成了最終一致性,那么用戶應(yīng)該清楚這種行為,客戶端用戶及其業(yè)務(wù)必須顯式地?fù)肀ё罱K一致性并且意識到在許多情況下這種業(yè)務(wù)沒有任何問題。
你可以跨越多個(gè)微服務(wù)來集成事件驅(qū)動(dòng),這些服務(wù)之間擁有最終一致性。 一個(gè)最終一致性的“事務(wù)”可能是由多個(gè)分布式的事件操作組成的一個(gè)集合。在每一個(gè)事件中,相關(guān)的微服務(wù)都在更新自己的領(lǐng)域?qū)嶓w并且發(fā)布另外一個(gè)需要集成的事件到Eventbus中。
很重要的一點(diǎn)是 , 你可能需要多個(gè)微服務(wù)訂閱一個(gè)事件。因此, 您可以使用基于事件驅(qū)動(dòng)的發(fā)布/訂閱消息模式的消息通訊, 如下圖所示。這種發(fā)布/訂閱的機(jī)制不是微服務(wù)獨(dú)有的。它類似于DDD中邊界上下文之間的通訊方式, 或者類似于CQRS架構(gòu)中的從寫庫更新數(shù)據(jù)到讀庫的這種模式。它最終的目標(biāo)是在整個(gè)分布式系統(tǒng)多個(gè)數(shù)據(jù)源之間的保持最終一致性。
你將實(shí)現(xiàn)基于消息的事件驅(qū)動(dòng)通信協(xié)議。AMQP可以幫助實(shí)現(xiàn)可靠的排隊(duì)通信。
當(dāng)您使用事件總線時(shí),您可能希望使用的是抽象級別的東西(如Eventbus interface),它使用類似于 RabbitMQ 或服務(wù)總線(如Azure Service Bus及 Topic)來作為底層,然后提供相關(guān)API。或者,您可能希望使用更高級別的服務(wù)總線,如NServiceBus,MassTransit或Brighter來作為Eventbus和發(fā)布/訂閱系統(tǒng)。
關(guān)于生產(chǎn)環(huán)境中的消息通訊技術(shù)
在消息通訊技術(shù)中,實(shí)現(xiàn)抽象級別的事件總線是存在不同的級別的。例如,像RabbitMQ 和Azure Event Bus這樣的產(chǎn)品比其他產(chǎn)品(如NServiceBus,MassTransit或Brighter)級別就更低一些,NServiceBus這些他們可能基于底層的這些之上,當(dāng)然后者也更加的重量級。
但是很多時(shí)候,我們可能學(xué)習(xí)這些重量級的東西需要花費(fèi)很多的成本,而且我們也用不到那么重量級的東西,正如在eShopOnContainers示例中所做的那樣,在Docker容器上運(yùn)行的RabbitMQ之上的簡單實(shí)現(xiàn)可能就足夠了。
但是,在生產(chǎn)系統(tǒng)中對于需要可擴(kuò)展性的關(guān)鍵型任務(wù),您可能需要進(jìn)行評估一下。 為了使分布式應(yīng)用程序開發(fā)更容易的并且提供高級抽象的功能,我們建議您評估其他商業(yè)和開源的服務(wù)總線,如NServiceBus,MassTransit和Bright。當(dāng)然,您可以在像RabbitMQ和Docker這樣的低級技術(shù)的基礎(chǔ)上構(gòu)建自己的服務(wù)總線功能。但是,這種工作對于企業(yè)應(yīng)用來說可能花費(fèi)的太多。
異步消息解決方案
到這里,我們會(huì)發(fā)現(xiàn),我們真的是太需要這么樣一個(gè)組件來幫助我們實(shí)現(xiàn)這些東西了,既能提供高抽象級別的API幫助我們簡化操作,又能輕量級并且容易學(xué)習(xí)和集成到項(xiàng)目中,并且能夠幫助我們解決分布式事務(wù)中的一致性問題,如果是開源免費(fèi)的,那就更好了。
然后,重點(diǎn)來了~
請期待下一篇,異步消息,分布式事務(wù)解決方案:(保密臉\^_\^)...
相關(guān)文章:
開篇有益-解析微軟微服務(wù)架構(gòu)eShopOnContainers(一)
Identity Service - 解析微軟微服務(wù)架構(gòu)eShopOnContainers(二)
Catalog Service - 解析微軟微服務(wù)架構(gòu)eShopOnContainers(三)
EventBus In eShop -- 解析微軟微服務(wù)架構(gòu)eShopOnContainers(四)
原文地址:http://www.cnblogs.com/savorboard/p/microservice-eventbus.html
.NET社區(qū)新聞,深度好文,微信中搜索dotNET跨平臺或掃描二維碼關(guān)注
總結(jié)
以上是生活随笔為你收集整理的微服务中的异步消息通讯的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: .NET Core 事件总线,分布式事务
- 下一篇: 我眼中的ASP.NET Core之微服务