業務流程的新實現:微服務和事件編排

banq發表於2017-09-06
本文介紹如何在微服務架構透過事件編排實現業務流程的無限靈活實現,克服了以往SOA中ESB匯流排的中央治理的侷限。

關鍵詞:
1.在微服務架構中,遇到長時間執行並跨越多個微服務邊界呼叫的流程並不少見。

2.具有相應編排功能的、基於事件的架構是一種越來越常見的方式,可以減少耦合。

3.這個想法的核心是:所有的微伺服器可以訂閱與其業務相關的其他服務發生的事件。這可以使用非同步訊息傳遞或者作為REST服務來完成。

4.該文章作者探索了他們稱之為“事件命令轉換(banq注:Saga模式)”的模式,避免了傳統SOA的中央控制器。

5. 為了實現業務流程功能,您可以利用現有的輕量級狀態機和工作流引擎。將這些引擎嵌入到您的微服務中,避免傳統SOA的中央工具或中央治理。

原文大意:

假設我們想設計一個微服務架構來實現一些相當複雜的“端到端”用例,比如基於網路零售商的訂單履行流程。顯然,這將涉及多個微服務的呼叫。因此,我們必須處理跨越單個微服務邊界的業務流程。但這種跨服務流會遭遇一些挑戰。在本文中,我們將介紹“事件命令轉換”這個有用的模式,介紹如何解決實現跨越微服務流程的複雜性,同時不要引入任何中央控制器。

首先,我們必須提出一個初步的微服務環境,並定義微服務的範圍及其範圍。我們的目標是最大程度地減少各種服務之間的耦合,並使其獨立部署。透過這樣做,我們希望最大化團隊的自主權; 對於每個微服務,應該有一個專門職能的團隊照顧它。由於這對我們尤為重要,因此我們決定採用更粗略的方法,並設計一些圍繞業務功能構建的獨立服務。這就產生了以下微服務:

1.付款服務 - 團隊負責處理與“錢”有關的一切事宜
2.庫存服務 - 團隊負責照料庫存物品
3.裝運服務 - 團隊負責“向客戶移動東西”

網路商店本身可能會包含更多的微服務,例如搜尋,目錄等。當我們專注於訂單履行時,我們只對一個網上商店相關服務感興趣,允許客戶下訂單。


長時間流程

我們必須考慮整體順序執行的一個重要特徵:這是一個長期執行的流程。關於“長期執行”一詞,我們的意思是說,直到訂單處理完成後,可能需要幾分鐘,幾個小時甚至幾周的時間。

請考慮以下示例:每當信用卡在付款期間被拒絕時,客戶有一週時間提供新的付款明細。這意味著訂單可能需要等待一個星期。本文將針對這種長期執行的實現方法進行更詳細地討論。

事件協作

我們不討論這篇文章中的溝通模式的利弊,而是決定在服務之間引入以事件為中心的溝通模式來解決我們的問題。

事件協作理念的核心是:所有的微伺服器都會在事件相關的事件發生時釋出事件。其他服務可以訂閱該事件並進行某些操作,透過事件協作,服務之間的高度解耦成為預設設計。此外,實現我們在微服務架構中尋找的那種分散資料管理變得容易和自然。

這一概念在“ 領域驅動設計”(Domain Driven Design)中得到了很好的理解,該系統目前正在加速微服務流程和一般互動分散式系統的“新常態”。

請注意,事件協作可以透過非同步訊息傳遞實現,但也可以透過其他方式實現。微服務可以釋出其事件的REST流。

事件命令轉換

我們的訂單履行是從訂單下達事件開始,然後是客戶付款。支付服務成功完成了收款,然後我們將貨物託運,並送達客戶。

事件的定義:通知您有關發生的相關事實以及某些其他服務可能感興趣。

在我們的示例中,支付服務監聽結帳服務中的“訂單下達Order Placed ”事件。事件命令轉換模式是確保負責做出業務決策的元件(現在需要付款)將事件(Order Placed)轉換為命令(Retrieve Payment實現支付)。該命令可以傳送到接收事件的支付服務。


編排與編排 - 業務流程的權力治理

端到端的流程邏輯是分散管理,職責是分散的,避免上帝式的服務中央控制就需要認真對待團隊的職責和自主權的問題。對訂單實現端到端的職責分散意味著“付款”就是一個黑盒子。您只負責要求執行其工作(檢索付款)並等待其完成:收到付款即可,不需要關心其具體怎麼做。

比如前面提到的業務需求,只要信用卡被拒絕,客戶就有一週時間提供新的付款明細。我們也就可能在訂單服務中實現這樣的邏輯,但只有當付款服務提供的命令是非常細粒度的才有這種可能。如果支付小組認真對待自己的業務能力和相關職責,那麼這樣做可能需要一段時間,它需要確定收取付款的職責(banq注:說白了,需要更多人機互動說明這個環節很重要,工作人員需要反覆確認核實,這些都是認真負責的意思,端到端流程這種分散方式便於人工介入)。

在高度分散的組織中,端到端訂單服務將盡可能精簡,因為其端到端流程的大多數方面將由專門從事自身業務能力的其他服務機構自主管理。付款服務是這個原則的一個例子:付款團隊有責任實施收取付款所需的一切。

在談論業務流程的實施時,這是一個重要的考慮因素和一個常見的誤解:並不一定意味著您需要將整個流程設計成一個整體,讓一箇中央協調者執行它,就像傳統的SOA和BPM一樣。

如果認為分拆傳統的集中流程設計到端到端的流程邏輯會增加系統的複雜性,那麼您可能是正確的。而且需要首先引入微服務架構:單體架構通常更容易,但是當系統發展並且不能再由單個團隊處理時,它們將達到極限。

總結我們迄今為止所討論的內容:編舞是微觀服務架構的基本模式。我們建議遵循這種模式作為一個重要的經驗法則。但是,當涉及業務流程時,不要建立純粹的事件鏈,而是實現分散的流程邏輯,並改用事件命令轉換模式。負責決定行動的微服務也應負責將事件轉換為命令。

流程邏輯實現

我們來看看長時間執行的流程邏輯的實現。長時間執行的流程需要儲存狀態,簡單的方法是將訂單狀態儲存為某些實體的一部分,例如程式碼片段1所示。

public class OrderStatus {
  boolean paymentReceived = false;
  boolean goodsFetched = false;
  boolean goodsShipped = false;
}
<p class="indent">


或者你可能會使用你最喜歡的Actor演員框架。我們在這裡討論基本選項。所有這些都在一定程度上起作用,但是一旦開始實施長時間執行所需的狀態,通常您會面臨額外的需求:您如何實現等待七天?如何處理錯誤和重試?你如何評估訂單的週期時間?在哪種情況下,由於缺少付款而取消訂單?如果我在處理線上某處有一些訂單,我該如何更改流程?

這可能導致大量編碼,最終導致閉關造車的框架。在受影響的專案上工作的團隊也投入了大量的努力。所以我們可以看看一個不同的方法:利用現有的框架。在本文中,我們使用Camunda開源引擎來說明具體的程式碼示例。我們來看看Code Snippet 2。

engine.getRepositoryService().createDeployment()
  .addModelInstance(Bpmn.createExecutableProcess("order")
    .startEvent()
      .serviceTask().name("Retrieve payment").camundaClass(RetrievePaymentAdapter.class)
      .serviceTask().name("Fetch goods").camundaClass(FetchGoodsAdapter.class)
      .serviceTask().name("Ship goods").camundaClass(ShipGoodsAdapter.class)
    .endEvent().camundaExecutionListenerClass("end", GoodsShippedAdapter.class)
  .done()
).deploy();
<p class="indent">


引擎現在執行這個流程的例項,跟蹤他們的狀態,並以持續的方式來緩解災難或長時間的等待。介面卡邏輯如程式碼片段3所示:

public class RetrievePaymentAdapter implements JavaDelegate {
  public void execute(ExecutionContext ctx) throws Exception {
    // Prepare payload for the outgoing command
    publishCommand("RetrievePayment", payload);
    addEventSubscription("PaymentReceived", ctx);
  }
}
<p class="indent">



(banq注:省去介紹Camunda作為工作流引擎和視覺化開發方式兩個部分)

處理複雜流程要求

眾所周知,魔鬼在細節上。微服務只能實現“ 最終一致性 ”(柔性事務機制,不同於J他的2PC剛性事務機制),抓住一些報錯並觸發補償機制。Camunda引擎的補償機制知道過去成功執行哪些活動,並自動執行定義的補償活動,這很好地實現了所謂的Saga模式。

請注意,邏輯仍然存在於(可能非常精簡)的微服務(訂單服務)中,而總體流程的其他部分將由負責這些部件的團隊維護。不需要任何中央控制器 - 流程邏輯是分散式的。

為什麼傳統BPM產品不是微服務的菜?

提供長時間執行服務所需的流程邏輯功能的現有工具通常被稱為工作流或BPM引擎。然而,在“舊的SOA”中,業務流程管理(BPM)會出現錯誤,特別是在開發人員中,這種錯誤導致聲譽不佳。他們認為,他們獲得了一個僵化的,整體的,不利於開發者的且昂貴的工具,迫使他們遵循一些模型驅動的、專有的、所謂零程式碼的方法。一些BPM供應商真的提供了在微服務領域無法使用的平臺。

克服誤解的一個重要方面是認真考慮詞語含義。我們在這裡提供的流程不一定是“業務流程”,這些流程也可能是涉及人機互動的“工作流程”。(傳統的BPM產品不適合人機互動頻繁的流程)

本文的訂單履行示例。您可以在GitHub上找到原始碼。

微服務和事件驅動架構能很自然地配合在一起。事件編排能夠實現分散資料管理,最大限度減少耦合。

原文:Know the Flow! Microservices and Event Choreographies

banq總結: 傳統SOA是基於單體整體系統抽象出流程,但是這種流程編排不利於深度靈活的流程定製,而基於微服務的端到端訂閱方式,只要關注前置事件發生即可(類似二叉樹只要實現父子關係就可以一樣),如果改變關注物件,當前微服務也可以迅速重啟進而改變流程。

相關文章