微服務擴充套件新途徑:Messaging

OneAPM官方技術部落格發表於2016-06-27

【編者按】服務編排是微服務設定的一個重要方面。本文在利用 ActiveMQ 虛擬話題來實現這一目標的同時,還會提供實用性指導。文章系國內 ITOM 管理平臺 OneAPM 編譯呈現。

目前,微服務使用已十分普遍,利用服務編排(而不是服務編制)來進行微服務互動的想法也很常見。本文將講述如何通過 ActiveMQ 虛擬話題來設定服務編排和基於服務互動的可擴充套件事件。

服務互動型別

服務互動型別主要有兩種:同步和非同步。

在同步互動中,服務使用者會發出請求,然後在操作完成、收取回復前阻止其他活動執行,HTTP 協議就是一個很好的同步互動例子。通常情況下,這種互動與請求-回覆互動型別、 HTTP 協議都是相關的(當然,也可以利用非同步請求或訊息傳遞來登記、請求回撥函式的結果,不過這種做法不太常見)。

在非同步互動中,服務使用者發出的請求不用在操作完成後才可以執行。一旦請求確認被收到,服務使用者就可以接著做其他的活動。這種型別支援互動溝通採用釋出-訂閱模式,例如:不需要服務使用者呼叫其他服務操作,只需要生產者提出事件,等待感興趣的使用者做出反應即可。

除了這些技術層面的考慮,還應該注意考量服務互動的其他層面:耦合和責任。

如果服務 A 要和服務 B 互動,是要服務 A 來呼叫服務 B(編制),還是讓服務 B 去訂閱正確的時間(編排)呢?

在服務編制中需要有一箇中心實體(即例子中的服務 A),去了解被呼叫的其他服務。利用編排方法,可以將這個責任分配給個體服務,由它們來負責訂閱“有意思的”事件。

如果想要了解更多關於本話題的內容,請查閱 Building Microservices。接下來,本文將集中討論如何使用訊息傳遞實現服務編排。

通過訊息傳遞進行服務編制

服務編制是通過佇列實現訊息傳遞的。佇列能夠在競爭使用者模式下實現負載均衡,並且確保訊息和使用者一一對應。

假設存在一個與“郵件服務”互動的“客服服務”,最簡單的實現方法就是使用一個允許“客戶服務”給“郵件佇列”傳送訊息的佇列。如果“客戶服務”需要跟“忠誠值服務”互動,“客戶服務”就要給“忠誠值服務”再發一條訊息。這種辦法下,“客戶服務”需要了解“郵件服務”和“忠誠值服務”這兩者,並且把正確的訊息發給對應的佇列。簡而言之,整個互動過程都是由“客戶服務”編制的。

使用佇列的一個好處就是它可以輕鬆擴充套件使用者,並開啟多個“忠誠值服務”和“郵件服務”,從而將負載均衡地分佈於不同的使用者間。

通過訊息傳遞進行服務編排

使用服務編排方式時,“客戶服務”卻不需要了解“忠誠值服務”和“郵件服務”。因為“客戶服務”只要對“客戶話題”發出一個事件,“忠誠值服務”和“郵件服務”就會去了解客戶事件協議,並訂閱正確的話題——話題的釋出-訂閱語意會確保每個事件同時被分發給兩個訂閱者。

擴充套件服務編排

話題執行釋出-訂閱,而不是競爭使用,這使得使用者的擴充套件變得更加困難。如果(橫向)擴充套件“忠誠值服務”並在兩個例項中進行試驗,可以發現它們會收到同樣的事件,這樣擴充套件的話並沒有什麼益處(除非服務是等冪的)。

ActiveMQ 虛擬話題解決方案

因此需要一種融合了話題和佇列的綜合形式,充分發揮這兩個功能:既能夠利用“客戶服務”的釋出-訂閱來發布事件,確保所有服務都能收到該事件;也可以通過競爭的使用者,使個體服務例項實現負載均衡並進行擴充套件。

實現該形式的方法有很多,可以利用 Camel 和 ActiveMQ :

  • 第一個方法就是用一個簡單的 Camel 路由來吸收“客戶話題”事件,並把它們同時傳送給“忠誠值佇列”和“郵件佇列”。這是很容易實現的,不過每當有新服務對“客戶服務”事件感興趣時都需要重新更新 Camel 路由。而且,如果在代理之外單獨執行 Camel 路由,把訊息從某一話題轉入到其事先設定好的佇列中去,就會帶來不必要的網路開銷。

  • 上述方法的一個改進方案,就是在 ActiveMQ 代理流程中使用 ActiveMQ Camel plugin 來執行 Camel 路由。這樣的話,雖然仍需要在訂閱者發生變更時更新 Camel 路由,但是路由是在代理過程中發生的,因此不會產生網路開銷。

  • 不過還有更好的方案,就是將訂閱該話題的佇列 W/O 全部進行編碼,但是要借用 ActiveMQ 虛擬話題的宣告法(這也是撰寫本文的主要原因)。

ActiveMQ 虛擬話題是將訂閱佇列釋出到話題中的方法,通過一個簡單的命名慣例——所要做的就是確定話題或佇列的命名慣例,無論是自定義的還是預設的都可以。

舉個例子:

  • 可以先建立一個與 VirtualTopic.> 表示式相匹配的話題名,如 VirtualTopic.CustomerTopic,

  • 然後讓“忠誠度服務”呼叫 Consumer.LoyaltyPoint.VirtualTopic.CustomerTopic 佇列,

  • 那麼訊息代理就會將 VirtualTopic.CustomerTopic 話題中的所有事件都轉發給
    Consumer.LoyaltyPoint.VirtualTopic.CustomerTopic 佇列。

  • 然後可以通過開啟多個服務例項來擴充套件忠誠度服務,所有例項都從 Consumer.LoyaltyPoint.VirtualTopic.CustomerTopic 佇列中呼叫。

  • 同樣的,之後再用同樣的命名慣例為郵件服務建立佇列:Consumer.Email.VirtualTopic.CustomerTopic,這個功能允許使用者以特定方式來簡單命名話題和佇列,並且無需編碼就能訂閱。

結論

以上所述只是最近出版的著作 Camel Design Patterns 裡介紹的多種模式之一。正因為經常將Camel 與 ActiveMQ 一起使用,書中也就收錄了一些 ActiveMQ 模式內容。

另外,用編排擴充套件微服務還可以通過事件驅動來實現,這裡就是一篇介紹這種方法的推薦文章。

本文系 OneAPM 工程師編譯整理。OneAPM 能為您提供端到端的 Java 應用效能解決方案,我們支援所有常見的 Java 框架及應用伺服器,助您快速發現系統瓶頸,定位異常根本原因。分鐘級部署,即刻體驗,Java 監控從來沒有如此簡單。想閱讀更多技術文章,請訪問 OneAPM 官方技術部落格

本文轉自 OneAPM 官方部落格

原文地址:https://dzone.com/articles/scalable-microservices-through-messaging

相關文章