【編者按】服務(wù)編排是微服務(wù)設(shè)置的一個重要方面。本文在利用 ActiveMQ 虛擬話題來實現(xiàn)這一目標(biāo)的同時,還會提供實用性指導(dǎo)。文章系國內(nèi) ITOM 管理平臺 OneAPM 編譯呈現(xiàn)。
目前傻唾,微服務(wù)使用已十分普遍,利用服務(wù)編排(而不是服務(wù)編制)來進(jìn)行微服務(wù)互動的想法也很常見承耿。本文將講述如何通過 ActiveMQ 虛擬話題來設(shè)置服務(wù)編排和基于服務(wù)互動的可擴(kuò)展事件冠骄。
服務(wù)互動類型
服務(wù)互動類型主要有兩種:同步和異步。
在同步互動中加袋,服務(wù)使用者會發(fā)出請求凛辣,然后在操作完成、收取回復(fù)前阻止其他活動運行职烧,HTTP 協(xié)議就是一個很好的同步互動例子扁誓。通常情況下,這種互動與請求-回復(fù)互動類型蚀之、 HTTP 協(xié)議都是相關(guān)的(當(dāng)然蝗敢,也可以利用異步請求或消息傳遞來登記、請求回調(diào)函數(shù)的結(jié)果足删,不過這種做法不太常見)寿谴。
在異步互動中,服務(wù)使用者發(fā)出的請求不用在操作完成后才可以運行失受。一旦請求確認(rèn)被收到讶泰,服務(wù)使用者就可以接著做其他的活動。這種類型支持互動溝通采用發(fā)布-訂閱模式拂到,例如:不需要服務(wù)使用者調(diào)用其他服務(wù)操作痪署,只需要生產(chǎn)者提出事件,等待感興趣的使用者做出反應(yīng)即可兄旬。
除了這些技術(shù)層面的考慮惠桃,還應(yīng)該注意考量服務(wù)互動的其他層面:耦合和責(zé)任。
如果服務(wù) A 要和服務(wù) B 互動辖试,是要服務(wù) A 來調(diào)用服務(wù) B(編制),還是讓服務(wù) B 去訂閱正確的時間(編排)呢劈狐?
在服務(wù)編制中需要有一個中心實體(即例子中的服務(wù) A)罐孝,去了解被調(diào)用的其他服務(wù)。利用編排方法肥缔,可以將這個責(zé)任分配給個體服務(wù)莲兢,由它們來負(fù)責(zé)訂閱“有意思的”事件。
如果想要了解更多關(guān)于本話題的內(nèi)容,請查閱 Building Microservices改艇。接下來收班,本文將集中討論如何使用消息傳遞實現(xiàn)服務(wù)編排。
通過消息傳遞進(jìn)行服務(wù)編制
服務(wù)編制是通過隊列實現(xiàn)消息傳遞的谒兄。隊列能夠在競爭使用者模式下實現(xiàn)負(fù)載均衡摔桦,并且確保消息和使用者一一對應(yīng)。
假設(shè)存在一個與“郵件服務(wù)”互動的“客服服務(wù)”承疲,最簡單的實現(xiàn)方法就是使用一個允許“客戶服務(wù)”給“郵件隊列”發(fā)送消息的隊列邻耕。如果“客戶服務(wù)”需要跟“忠誠值服務(wù)”互動,“客戶服務(wù)”就要給“忠誠值服務(wù)”再發(fā)一條消息燕鸽。這種辦法下兄世,“客戶服務(wù)”需要了解“郵件服務(wù)”和“忠誠值服務(wù)”這兩者,并且把正確的消息發(fā)給對應(yīng)的隊列啊研。簡而言之御滩,整個互動過程都是由“客戶服務(wù)”編制的。
使用隊列的一個好處就是它可以輕松擴(kuò)展使用者党远,并開啟多個“忠誠值服務(wù)”和“郵件服務(wù)”削解,從而將負(fù)載均衡地分布于不同的使用者間。
通過消息傳遞進(jìn)行服務(wù)編排
使用服務(wù)編排方式時麸锉,“客戶服務(wù)”卻不需要了解“忠誠值服務(wù)”和“郵件服務(wù)”钠绍。因為“客戶服務(wù)”只要對“客戶話題”發(fā)出一個事件,“忠誠值服務(wù)”和“郵件服務(wù)”就會去了解客戶事件協(xié)議花沉,并訂閱正確的話題——話題的發(fā)布-訂閱語意會確保每個事件同時被分發(fā)給兩個訂閱者柳爽。
擴(kuò)展服務(wù)編排
話題執(zhí)行發(fā)布-訂閱,而不是競爭使用碱屁,這使得使用者的擴(kuò)展變得更加困難磷脯。如果(橫向)擴(kuò)展“忠誠值服務(wù)”并在兩個實例中進(jìn)行試驗,可以發(fā)現(xiàn)它們會收到同樣的事件娩脾,這樣擴(kuò)展的話并沒有什么益處(除非服務(wù)是等冪的)赵誓。
ActiveMQ 虛擬話題解決方案
因此需要一種融合了話題和隊列的綜合形式,充分發(fā)揮這兩個功能:既能夠利用“客戶服務(wù)”的發(fā)布-訂閱來發(fā)布事件柿赊,確保所有服務(wù)都能收到該事件俩功;也可以通過競爭的使用者,使個體服務(wù)實例實現(xiàn)負(fù)載均衡并進(jìn)行擴(kuò)展碰声。
實現(xiàn)該形式的方法有很多诡蜓,可以利用 Camel 和 ActiveMQ :
第一個方法就是用一個簡單的 Camel 路由來吸收“客戶話題”事件,并把它們同時發(fā)送給“忠誠值隊列”和“郵件隊列”胰挑。這是很容易實現(xiàn)的蔓罚,不過每當(dāng)有新服務(wù)對“客戶服務(wù)”事件感興趣時都需要重新更新 Camel 路由非剃。而且抱慌,如果在代理之外單獨運行 Camel 路由蜀铲,把消息從某一話題轉(zhuǎn)入到其事先設(shè)定好的隊列中去铝量,就會帶來不必要的網(wǎng)絡(luò)開銷。
上述方法的一個改進(jìn)方案茬末,就是在 ActiveMQ 代理流程中使用 ActiveMQ Camel plugin 來運行 Camel 路由厂榛。這樣的話,雖然仍需要在訂閱者發(fā)生變更時更新 Camel 路由团南,但是路由是在代理過程中發(fā)生的噪沙,因此不會產(chǎn)生網(wǎng)絡(luò)開銷。
不過還有更好的方案吐根,就是將訂閱該話題的隊列 W/O 全部進(jìn)行編碼正歼,但是要借用 ActiveMQ 虛擬話題的聲明法(這也是撰寫本文的主要原因)。
ActiveMQ 虛擬話題是將訂閱隊列發(fā)布到話題中的方法拷橘,通過一個簡單的命名慣例——所要做的就是確定話題或隊列的命名慣例局义,無論是自定義的還是默認(rèn)的都可以。
舉個例子:
可以先創(chuàng)建一個與 VirtualTopic.> 表達(dá)式相匹配的話題名冗疮,如 VirtualTopic.CustomerTopic,
然后讓“忠誠度服務(wù)”調(diào)用 Consumer.LoyaltyPoint.VirtualTopic.CustomerTopic 隊列萄唇,
那么消息代理就會將 VirtualTopic.CustomerTopic 話題中的所有事件都轉(zhuǎn)發(fā)給
Consumer.LoyaltyPoint.VirtualTopic.CustomerTopic 隊列。然后可以通過開啟多個服務(wù)實例來擴(kuò)展忠誠度服務(wù)术幔,所有實例都從 Consumer.LoyaltyPoint.VirtualTopic.CustomerTopic 隊列中調(diào)用另萤。
同樣的,之后再用同樣的命名慣例為郵件服務(wù)創(chuàng)建隊列:Consumer.Email.VirtualTopic.CustomerTopic诅挑,這個功能允許用戶以特定方式來簡單命名話題和隊列四敞,并且無需編碼就能訂閱。
結(jié)論
以上所述只是最近出版的著作 Camel Design Patterns 里介紹的多種模式之一拔妥。正因為經(jīng)常將Camel 與 ActiveMQ 一起使用忿危,書中也就收錄了一些 ActiveMQ 模式內(nèi)容。
另外没龙,用編排擴(kuò)展微服務(wù)還可以通過事件驅(qū)動來實現(xiàn)铺厨,這里就是一篇介紹這種方法的推薦文章。
本文系 OneAPM 工程師編譯整理硬纤。OneAPM 能為您提供端到端的 Java 應(yīng)用性能解決方案解滓,我們支持所有常見的 Java 框架及應(yīng)用服務(wù)器,助您快速發(fā)現(xiàn)系統(tǒng)瓶頸筝家,定位異常根本原因伐蒂。分鐘級部署,即刻體驗肛鹏,Java 監(jiān)控從來沒有如此簡單逸邦。想閱讀更多技術(shù)文章,請訪問 OneAPM 官方技術(shù)博客在扰。
本文轉(zhuǎn)自 OneAPM 官方博客
原文地址:https://dzone.com/articles/scalable-microservices-through-messaging