好訊息!DTM 分散式事務管理器 PHP 協程使用者端 v0.1 beta 版本釋出!!!
→ github.com/dtm-php/dtm-client
dtm/dtm-client 是分散式事務管理器 DTM 的 PHP 使用者端,已支援 TCC模式、Saga、二階段訊息模式的分散式事務模式,並分別實現了與 DTM Server 以 HTTP 協定或 gRPC 協定通訊,該使用者端可安全執行於 PHP-FPM 和 Swoole 協程環境中,更是對 Hyperf 做了更加易用的功能支援。【推薦:】
DTM 是一款基於 Go 語言實現的開源分散式事務管理器,提供跨語言,跨儲存引擎組合事務的強大功能。DTM 優雅的解決了冪等、空補償、懸掛等分散式事務難題,也提供了簡單易用、高效能、易水平擴充套件的分散式事務解決方案。
在非 Java 語言下,暫未看到除 DTM 之外的成熟的分散式事務管理器,因此這裡將 DTM 和 Java 中最成熟的開源專案 Seata 做對比:
特性 | DTM | SEATA | 備註 |
---|---|---|---|
支援語言 | Go、C#、Java、Python、PHP… | Java | DTM 可輕鬆接入一門新語言 |
儲存引擎 | 支援資料庫、Redis、Mongo等 | 資料庫 | |
例外處理 | 子事務屏障自動處理 | 手動處理 | DTM 解決了冪等、懸掛、空補償 |
SAGA事務 | 極簡易用 | 複雜狀態機 | |
二階段訊息 | ✓ | ✗ | 最簡訊息最終一致性架構 |
TCC事務 | ✓ | ✓ | |
XA事務 | ✓ | ✓ | |
AT事務 | 建議使用XA | ✓ | AT 與 XA類似,但有髒回滾 |
單服務多資料來源 | ✓ | ✗ | |
通訊協定 | HTTP、gRPC | Dubbo等協定 | DTM對雲原生更加友好 |
star數量 | DTM 從 2021-06-04 釋出 0.1版本,發展飛快 |
從上面對比的特性來看,DTM 在許多方面都具備很大的優勢。如果考慮多語言支援、多儲存引擎支援,那麼 DTM 毫無疑問是您的首選.
通過 Composer 可以非常方便的安裝 dtm-client
composer require dtm/dtm-client
如果您是在 Hyperf 框架中使用,在安裝元件後,可通過下面的 vendor:publish
命令一件釋出組態檔於 ./config/autoload/dtm.php
php bin/hyperf.php vendor:publish dtm/dtm-client
如果您是在非 Hyperf 框架中使用,可複製 ./vendor/dtm/dtm-client/publish/dtm.php
檔案到對應的設定目錄中。
use DtmClient\Constants\Protocol; use DtmClient\Constants\DbType; return [ // 使用者端與 DTM Server 通訊的協定,支援 Protocol::HTTP 和 Protocol::GRPC 兩種 'protocol' => Protocol::HTTP, // DTM Server 的地址 'server' => '127.0.0.1', // DTM Server 的埠 'port' => [ 'http' => 36789, 'grpc' => 36790, ], // 子事務屏障設定 'barrier' => [ // DB 模式下的子事務屏障設定 'db' => [ 'type' => DbType::MySQL ], // Redis 模式下的子事務屏障設定 'redis' => [ // 子事務屏障記錄的超時時間 'expire_seconds' => 7 * 86400, ], // 非 Hyperf 框架下應用子事務屏障的類 'apply' => [], ], // HTTP 協定下 Guzzle 使用者端的通用設定 'guzzle' => [ 'options' => [], ], ];
在使用之前,需要設定 DtmClient\Middleware\DtmMiddleware
中介軟體作為 Server 的全域性中介軟體,該中介軟體支援 PSR-15 規範,可適用於各個支援該規範的的框架。
在 Hyperf 中的中介軟體設定可參考 Hyperf檔案 - 中介軟體 一章。
dtm-client 的使用非常簡單,我們提供了一個範例專案 dtm-php/dtm-sample 來幫助大家更好的理解和偵錯。
在使用該元件之前,也強烈建議您先閱讀 DTM 官方檔案,以做更詳細的瞭解。
TCC 模式是一種非常流行的柔性事務解決方案,由 Try-Confirm-Cancel 三個單詞的首字母縮寫分別組成 TCC 的概念,最早是由 Pat Helland 於 2007 年發表的一篇名為《Life beyond Distributed Transactions:an Apostate’s Opinion》的論文中提出。
Try 階段:嘗試執行,完成所有業務檢查(一致性), 預留必須業務資源(準隔離性)
Confirm 階段:如果所有分支的 Try 都成功了,則走到 Confirm 階段。Confirm 真正執行業務,不作任何業務檢查,只使用 Try 階段預留的業務資源
Cancel 階段:如果所有分支的 Try 有一個失敗了,則走到 Cancel 階段。Cancel 釋放 Try 階段預留的業務資源。
如果我們要進行一個類似於銀行跨行轉賬的業務,轉出(TransOut)和轉入(TransIn)分別在不同的微服務裡,一個成功完成的 TCC 事務典型的時序圖如下:
以下展示在 Hyperf 框架中的使用方法,其它框架類似
<?php namespace App\Controller; use DtmClient\TCC; use DtmClient\TransContext; use Hyperf\Di\Annotation\Inject; use Hyperf\HttpServer\Annotation\Controller; use Hyperf\HttpServer\Annotation\GetMapping; use Throwable; #[Controller(prefix: '/tcc')] class TccController { protected string $serviceUri = 'http://127.0.0.1:9501'; #[Inject] protected TCC $tcc; #[GetMapping(path: 'successCase')] public function successCase() { try { $this->tcc->globalTransaction(function (TCC $tcc) { // 建立子事務 A 的呼叫資料 $tcc->callBranch( // 呼叫 Try 方法的引數 ['amount' => 30], // Try 方法的 URL $this->serviceUri . '/tcc/transA/try', // Confirm 方法的 URL $this->serviceUri . '/tcc/transA/confirm', // Cancel 方法的 URL $this->serviceUri . '/tcc/transA/cancel' ); // 建立子事務 B 的呼叫資料,以此類推 $tcc->callBranch( ['amount' => 30], $this->serviceUri . '/tcc/transB/try', $this->serviceUri . '/tcc/transB/confirm', $this->serviceUri . '/tcc/transB/cancel' ); }); } catch (Throwable $e) { var_dump($e->getMessage(), $e->getTraceAsString()); } // 通過 TransContext::getGid() 獲得 全域性事務ID 並返回 return TransContext::getGid(); } }
Saga 模式是分散式事務領域最有名氣的解決方案之一,也非常流行於各大系統中,最初出現在 1987 年 由 Hector Garcaa-Molrna & Kenneth Salem 發表的論文 SAGAS 裡。
Saga 是一種最終一致性事務,也是一種柔性事務,又被叫做 長時間執行的事務(Long-running-transaction),Saga 是由一系列的本地事務構成。每一個本地事務在更新完資料庫之後,會發布一條訊息或者一個事件來觸發 Saga 全域性事務中的下一個本地事務的執行。如果一個本地事務因為某些業務規則無法滿足而失敗,Saga 會執行在這個失敗的事務之前成功提交的所有事務的補償操作。所以 Saga 模式在對比 TCC 模式時,因缺少了資源預留的步驟,往往在實現回滾邏輯時會變得更麻煩。
比如我們要進行一個類似於銀行跨行轉賬的業務,將 A 賬戶中的 30 元轉到 B 賬戶,根據 Saga 事務的原理,我們將整個全域性事務,拆分為以下服務:
整個事務的邏輯是:
執行轉出成功 => 執行轉入成功 => 全域性事務完成
如果在中間發生錯誤,例如轉入 B 賬戶發生錯誤,則會呼叫已執行分支的補償操作,即:
執行轉出成功 => 執行轉入失敗 => 執行轉入補償成功 => 執行轉出補償成功 => 全域性事務回滾完成
下面是一個成功完成的 SAGA 事務典型的時序圖:
以下展示在 Hyperf 框架中的使用方法,其它框架類似
namespace App\Controller; use DtmClient\Saga; use DtmClient\TransContext; use Hyperf\Di\Annotation\Inject; use Hyperf\HttpServer\Annotation\Controller; use Hyperf\HttpServer\Annotation\GetMapping; #[Controller(prefix: '/saga')] class SagaController { protected string $serviceUri = 'http://127.0.0.1:9501'; #[Inject] protected Saga $saga; #[GetMapping(path: 'successCase')] public function successCase(): string { $payload = ['amount' => 50]; // 初始化 Saga 事務 $this->saga->init(); // 增加轉出子事務 $this->saga->add( $this->serviceUri . '/saga/transOut', $this->serviceUri . '/saga/transOutCompensate', $payload ); // 增加轉入子事務 $this->saga->add( $this->serviceUri . '/saga/transIn', $this->serviceUri . '/saga/transInCompensate', $payload ); // 提交 Saga 事務 $this->saga->submit(); // 通過 TransContext::getGid() 獲得 全域性事務ID 並返回 return TransContext::getGid(); } }
以上就是【DTM】PHP協程使用者端v0.1 beta版本釋出啦!的詳細內容,更多請關注TW511.COM其它相關文章!