首頁>Club>
8
回覆列表
  • 1 # 使用者5724249294638

    它的作用是,每當使用feign呼叫遠端介面時,都會在請求頭中新增上事務上下文資訊

    每執行一步,都會即時記錄相應事務狀態,比如執行confirm方法,這時候如果confim執行失敗了,由於相應的事務狀態沒有更新,後端的定時器會不斷查詢失敗的事務,持續呼叫該方法。

  • 2 # 香香33619


    這一篇不想談論Hmily原始碼的技術實現,而是想在過了一遍hmily的實現後把hmily的工作思路單獨地整理出來再進行一次總結。看看能不能進一步有所得。


    以hmily-demo-springcloud為例,它的實現思路如下。


    Hmily事務工作流程

    首先它是基於切面程式設計來實現分散式事務的操作,及透過日誌記錄TCC事務的資訊以保證最終一致性。

    前端發起的一個請求,第一次進入一個@Hmily註解的函式的時候,就進入Hmily的事務管理了。

    這時會進入切面方法,生成一個日誌例項(HmilyTransaction例項)。日誌例項裡面儲存了所有後續需要操作的資訊,比如流轉狀態,執行函式資訊等等,並在後續的操作中會根據需要加入新的資訊。

    日誌例項 有一個執行狀態,一開始時是PRE_TRY(開始執行try),並會透過一個併發佇列非同步儲存到資料庫中。順便說一句,每個微服務都有一個日誌表,儲存著對應的日誌。

    關於非同步儲存要多說一句,hmily在設計的時候把許多操作,尤其是對日誌表的刪改查操作都改用非同步操作的方式,這也是hmily如此高效的一個原因,值得重點分析。

    剛才說到日誌例項被非同步儲存到資料庫的日誌表中了,而另一邊就開始執行我們的業務函式。

    如果函式內部再呼叫的函式仍有@Hmily註解,這時候切面裡面不做其他任何操作。

    如果呼叫的函式有@Hmily註解且是RPC函式,也就是呼叫其他微服務的代理介面,這時候會把事務id(transId 是事務唯一的,一個分散式事務id只有一個,且被用於日誌主鍵),及當前的角色狀態一起作為請求頭的引數。

    被呼叫的微服務接收到請求後,如果執行到帶有@Hmily的函式,會根據傳遞過來的transId 的事務資訊生成又一個事務日誌資訊,狀態為PRE_TRY(開始執行try),並非同步儲存到資料庫中對應該微服務的日誌表中。

    接著繼續執行該微服務的主體方法

    如果該微服務又呼叫了其它微服務,則同第7步到第12步。

    如果執行成功,修改 事務日誌的流轉狀態為TRYING(TRY階段完成),如果失敗了則刪除日誌丟擲異常。

    現在回到第一個微服務,如果呼叫成功,會把該rpc介面資訊儲存到日誌資訊裡面。

    如果還有呼叫其他微服務,則同第7步到13步。

    如果所有的執行都沒問題,這時候會把日誌的狀態改為TRYING(TRY階段完成),然後發起非同步任務執行confirm操作。

    confirm操作裡會把狀態改為CONFIRMING(“confirm階段”),並非同步儲存到資料庫中,然後透過反射儲存在日誌裡面的confirmMethod方法,及呼叫rpc介面,將執行confirm的命令傳送給對應的微服務。

    其它微服務接收到confirm訊息後,會根據該微服務的事務日誌中儲存的confirmMethod集合,一一執行,或再把該命令傳送給被呼叫的下一層微服務,重複17步驟。

    如果各個微服務在執行confirmMethod時,有失敗的案例,會將失敗的confirmMethod重新儲存到對應的事務日誌中,然後隔一定時間透過定時再次執行confirmMethod。直到一一成功或超過重試次數發出資訊給維護人員處理。confirmMethod失敗後的定時執行的這一步各個微服務已經是各自為政了,不用再自上而下的從第一個微服務發起任務。

    cancel方法同16步到18步。它的觸發條件是,只要在try階段裡有哪個try出問題了,異常會層層丟擲到最上層,後面的try都不執行。而前面執行過的try資訊或呼叫過的rpc介面資訊都會儲存在事務日誌中間。後面只要同confirm階段一樣,根據這些資訊執行cancelMethod方法或對RPC介面發起cancel請求

  • 3 # 使用者3946378225166

    它以零侵入以及快速整合方式能夠方便的被業務進行整合。


    在效能上,日誌儲存非同步(可選)以及使用非同步執行的方式,不損耗業務方法方法。


    之前是由我個人開發,目前由我在京東數科已經重新啟動,未來將會是金融場景的分散式事務解決方案。

  • 中秋節和大豐收的關聯?
  • 冬雪能比喻成什麼人?