前言

在上一篇文章中,我們說到了異步消息通訊,下面這篇文章呢,大部分內(nèi)容是翻譯來自于這篇微軟的文章,所以其內(nèi)容還是具有一定的理論指導(dǎo)意義的。

當(dāng)我們跨多個微服務(wù)進(jìn)行內(nèi)部通訊的時候,異步消息和事件驅(qū)動至關(guān)重要。我們可能需要在不同的邊界上下文中進(jìn)行域模型的更新。
我們舉個例子,比如 eShop 這個項目中,Ording 服務(wù)在下單的時候要和 Catelog 服務(wù)進(jìn)行通訊進(jìn)行庫存的扣減操作,這個時候我們就需要一種方式來做這個事情,并且能夠在發(fā)生故障的時候也能正常工作,也就說需要進(jìn)行基于異步消息和最終一致性的通訊方式。

當(dāng)使用基于消息的通訊方式的時候,進(jìn)程中是采用的異步的方式通訊的??蛻舳讼蚰硞€服務(wù)發(fā)送消息,如果這個消息需要回復(fù),那么另一個服務(wù)會向客戶端發(fā)送一個不同的消息,并且客戶端會認(rèn)為該消息不會立即被接收到,并且不存在響應(yīng),這就是一種基于消息的通訊方式。

消息由標(biāo)題(name 或者 title)和內(nèi)容(Body)共同構(gòu)成。消息通常會通過一些異步協(xié)議進(jìn)行發(fā)送(如AMQP,kafka協(xié)議)。

異步消息通訊有兩種:一種是單接收者(端到端),另外一種是多接收者(廣播)。

如果有同學(xué)對消息隊列比較了解的話,這就是消息隊列的兩種典型使用方式。

基于消息的單接收者

單接收者也就是說是點到點的通訊,將消息使用隊列等方式從一點發(fā)送的另外一點,并且該消息僅會被處理(消費)一次。這中間一個特殊情況就是,當(dāng)隊列在嘗試從故障中恢復(fù)時候,有可能會多次發(fā)送相同的消息,客戶端必須實現(xiàn)冪等性以便能夠處理相同的消息一次。

單接收器消息通訊的方式適用于將異步命令從一個微服務(wù)發(fā)送到另一個微服務(wù)。如下圖:

一旦開始使用了基于消息的通訊,你應(yīng)該避免將基于消息的通訊和同步的HTTP通訊混合起來。

大數(shù)據(jù)培訓(xùn),云培訓(xùn),數(shù)據(jù)挖掘培訓(xùn),云計算培訓(xùn),高端軟件開發(fā)培訓(xùn),項目經(jīng)理培訓(xùn)

注意:當(dāng)command來到客戶端應(yīng)用程序時候,它們可以實現(xiàn)為HTTP的同步命令。當(dāng)你需要更高的可擴(kuò)展性或者你業(yè)務(wù)流程中已經(jīng)使用了基于消息的方式時,那么你就應(yīng)該使用基于消息的通訊方式。

基于消息的多接收者

多接收者是消息通訊中一種更加靈活的方式,你可能還需要使用 發(fā)布/訂閱 這種機(jī)制,以便于接收來自發(fā)送方或者其他微服務(wù)或者外部應(yīng)用程序的消息。 這樣,將來可以添加更多的其他消費者用戶,而無需修改發(fā)送方的服務(wù)代碼。

當(dāng)你使用發(fā)布/訂閱這種通訊方式的時候,在發(fā)送端和訂閱端你也許會用到事件總線的接口。

異步事件驅(qū)動通訊

當(dāng)使用異步事件驅(qū)動通信時, 一個微服務(wù)當(dāng)域模型發(fā)生更新時,會發(fā)布一個集成事件,然后另外一個微服務(wù)可能需要關(guān)注這個事件,比如 eShop 中,當(dāng) product catelog 微服務(wù)發(fā)生一個價格變動的時候。另外的微服務(wù)需要訂閱這個事件,這樣就可以以異步的方式來接收這個事件。然后當(dāng)事件觸發(fā)的時候,訂閱端就可以更新自己的 Domain Model,從而集成發(fā)送端的事件。 事件總線(Event Bus)可以設(shè)計為一個抽象類或接口,集成API 訂閱或取消訂閱事件和發(fā)布事件。事件總線還可以有一個或多個實現(xiàn)基于任何進(jìn)程間消息傳遞代理,像一個消息隊列或服務(wù)總線支持異步通信和發(fā)布/訂閱模型。

如果事件驅(qū)動中集成了最終一致性,那么用戶應(yīng)該清楚這種行為,客戶端用戶及其業(yè)務(wù)必須顯式地?fù)肀ё罱K一致性并且意識到在許多情況下這種業(yè)務(wù)沒有任何問題。

你可以跨越多個微服務(wù)來集成事件驅(qū)動,這些服務(wù)之間擁有最終一致性。 一個最終一致性的“事務(wù)”可能是由多個分布式的事件操作組成的一個集合。在每一個事件中,相關(guān)的微服務(wù)都在更新自己的領(lǐng)域?qū)嶓w并且發(fā)布另外一個需要集成的事件到Eventbus中。

很重要的一點是 , 你可能需要多個微服務(wù)訂閱一個事件。因此, 您可以使用基于事件驅(qū)動的發(fā)布/訂閱消息模式的消息通訊, 如下圖所示。這種發(fā)布/訂閱的機(jī)制不是微服務(wù)獨有的。它類似于DDD中邊界上下文之間的通訊方式, 或者類似于CQRS架構(gòu)中的從寫庫更新數(shù)據(jù)到讀庫的這種模式。它最終的目標(biāo)是在整個分布式系統(tǒng)多個數(shù)據(jù)源之間的保持最終一致性。

大數(shù)據(jù)培訓(xùn),云培訓(xùn),數(shù)據(jù)挖掘培訓(xùn),云計算培訓(xùn),高端軟件開發(fā)培訓(xùn),項目經(jīng)理培訓(xùn)

你將實現(xiàn)基于消息的事件驅(qū)動通信協(xié)議。AMQP可以幫助實現(xiàn)可靠的排隊通信。

當(dāng)您使用事件總線時,您可能希望使用的是抽象級別的東西(如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ù)中,實現(xiàn)抽象級別的事件總線是存在不同的級別的。例如,像RabbitMQ 和Azure Event Bus這樣的產(chǎn)品比其他產(chǎn)品(如NServiceBus,MassTransit或Brighter)級別就更低一些,NServiceBus這些他們可能基于底層的這些之上,當(dāng)然后者也更加的重量級。

但是很多時候,我們可能學(xué)習(xí)這些重量級的東西需要花費很多的成本,而且我們也用不到那么重量級的東西,正如在eShopOnContainers示例中所做的那樣,在Docker容器上運(yùn)行的RabbitMQ之上的簡單實現(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ā)現(xiàn),我們真的是太需要這么樣一個組件來幫助我們實現(xiàn)這些東西了,既能提供高抽象級別的API幫助我們簡化操作,又能輕量級并且容易學(xué)習(xí)和集成到項目中,并且能夠幫助我們解決分布式事務(wù)中的一致性問題,如果是開源免費的,那就更好了。

然后,重點來了~

請期待下一篇,異步消息,分布式事務(wù)解決方案:(保密臉\^_\^)...

你可以關(guān)注一下博主,會第一時間收到通知哦~ 放心不會太久。


本文地址:http://www.cnblogs.com/savorboard/p/microservice-eventbus.html
作者博客:Savorboard
歡迎轉(zhuǎn)載,請在明顯位置給出出處及鏈接

http://www.cnblogs.com/savorboard/p/microservice-eventbus.html