首頁  >  文章  >  後端開發  >  【DTM】PHP協程客戶端v0.1 beta版本發布囉!

【DTM】PHP協程客戶端v0.1 beta版本發布囉!

藏色散人
藏色散人轉載
2022-02-15 15:19:484314瀏覽

好消息! 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 做了更易用的功能支援。 【推薦:PHP影片教學

關於DTM

DTM 是一款基於Go 語言實作的開源分散式交易管理器,提供跨語言,跨儲存引擎組合事務的強大功能。 DTM 優雅的解決了冪等、空補償、懸掛等分散式事務難題,也提供了簡單易用、高效能、易水平擴展的分散式事務解決方案。

亮點

  • 極易上手
    • 零配置啟動服務,提供非常簡單的HTTP 接口,大幅降低上手分散式事務的難度
  • 跨語言
    • 可適合多語言堆疊的公司使用。方便 Go、Python、PHP、NodeJs、Ruby、C# 等各類語言使用。
  • 使用簡單
    • 開發者不再擔心懸掛、空補償、冪等各類問題,首創子事務屏障技術代為處理
  • 易部署、易擴展
    • 僅依賴MySQL/Redis,部署簡單,易叢集化,易水平擴展
  • 多種分散式事務協議支援
    • TCC、SAGA、XA、二階段訊息,一站式解決多種分散式交易問題

對比

在非Java 語言下,暫未看到除DTM 之外的成熟的分散式事務管理器,因此這裡將DTM 和Java 中最成熟的開源專案Seata 做對比:

##支援語言DTM 可輕鬆接入一門新語言。儲存引擎異常處理## 手動處理#SAGA交易#二階段訊息##✓ ✓✓ 建議使用XA✓HTTP、gRPCDTM 從2021-06-04 發佈0.1版本,發展快速##

從上面對比的特性來看,DTM 在許多方面都具備很大的優勢。如果考慮多語言支援、多儲存引擎支持,那麼DTM 毫無疑問是您的首選.

#安裝

#透過Composer 可以非常方便的安裝dtm-client

composer require dtm/dtm-client
  • 使用時別忘了啟動DTM Server 哦

#設定

設定檔

如果您是在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 模式

TCC 模式是一種非常流行的柔性事務解決方案,由Try-Confirm-Cancel 三個單字的首字母縮寫分別組成TCC 的概念,最早是由Pat Helland 於2007 年發表的一篇名為《Life beyond Distributed Transactions:an Apostate's Opinion》的論文中提出。

TCC 的3 個階段

Try 階段:嘗試執行,完成所有業務檢查(一致性), 預留必須業務資源(準隔離性)
Confirm 階段:如果所有分支的Try 都成功了,則走到Confirm 階段。 Confirm 真正執行業務,不作任何業務檢查,只使用 Try 階段預留的業務資源
Cancel 階段:如果所有分支的 Try 有一個失敗了,則走到 Cancel 階段。 Cancel 釋放 Try 階段預留的業務資源。

如果我們要進行一個類似銀行跨行轉帳的業務,轉出(TransOut)和轉入(TransIn)分別在不同的微服務裡,一個成功完成的TCC 事務典型的時序圖如下:

【DTM】PHP協程客戶端v0.1 beta版本發布囉!

程式碼範例

以下展示在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: &#39;/tcc&#39;)]
class TccController
{

    protected string $serviceUri = &#39;http://127.0.0.1:9501&#39;;

    #[Inject]
    protected TCC $tcc;

    #[GetMapping(path: &#39;successCase&#39;)]
    public function successCase()
    {
        try {

            $this->tcc->globalTransaction(function (TCC $tcc) {
                // 创建子事务 A 的调用数据
                $tcc->callBranch(
                    // 调用 Try 方法的参数
                    [&#39;amount&#39; => 30],
                    // Try 方法的 URL
                    $this->serviceUri . &#39;/tcc/transA/try&#39;,
                    // Confirm 方法的 URL
                    $this->serviceUri . &#39;/tcc/transA/confirm&#39;,
                    // Cancel 方法的 URL
                    $this->serviceUri . &#39;/tcc/transA/cancel&#39;
                );
                // 创建子事务 B 的调用数据,以此类推
                $tcc->callBranch(
                    [&#39;amount&#39; => 30],
                    $this->serviceUri . &#39;/tcc/transB/try&#39;,
                    $this->serviceUri . &#39;/tcc/transB/confirm&#39;,
                    $this->serviceUri . &#39;/tcc/transB/cancel&#39;
                );
            });
        } catch (Throwable $e) {
            var_dump($e->getMessage(), $e->getTraceAsString());
        }
        // 通过 TransContext::getGid() 获得 全局事务ID 并返回
        return TransContext::getGid();
    }
}

Saga模式

Saga 模式是分散式事務領域最有名氣的解決方案之一,也非常流行於各大系統中,最初出現在1987 年由Hector Garcaa-Molrna & Kenneth Salem 發表的論文SAGAS 裡。

Saga 是一種最終一致性事務,也是一種柔性事務,又被稱為 長時間運行的事務(Long-running-transaction),Saga 是由一系列的本地事務構成。每一個本地事務在更新完資料庫之後,會發布一則訊息或一個事件來觸發 Saga 全域事務中的下一個本地事務的執行。如果一個本地事務因為某些業務規則無法滿足而失敗,Saga 會執行在這個失敗的事務之前成功提交的所有事務的補償操作。所以 Saga 模式在比較 TCC 模式時,因缺少了資源預留的步驟,往往在實作回滾邏輯時會變得更麻煩。

Saga 子事務分割

#例如我們要進行一個類似銀行跨行轉帳的業務,將A 帳戶中的30 元轉到B 帳戶,根據Saga事務的原理,我們將整個全域事務,拆分為以下服務:

  • 轉出(TransOut)服務,這裡將會進行操作A 帳戶扣減30 元
  • 轉出補償(TransOutCompensate)服務,回滾上面的轉出操作,即A 帳戶增加30 元
  • 轉入(TransIn)服務,這裡將會進行B  帳戶增加30 元
  • 轉出補償(TransInCompensate)服務,回滾上面的轉入操作,即B 帳戶減少30 元

整個事務的邏輯是:

執行轉出成功=> 執行轉入成功=> 全域事務完成

如果在中間發生錯誤,例如轉入B 帳戶發生錯誤,則會呼叫已執行分支的補償操作,即:

執行轉出成功=> 執行轉入失敗=> 執行轉入補償成功=> 執行轉出補償成功=> 全域事務回滾完成

下面是一個成功完成的SAGA 事務典型的時序圖:

【DTM】PHP協程客戶端v0.1 beta版本發布囉!

代码示例

以下展示在 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: &#39;/saga&#39;)]
class SagaController
{

    protected string $serviceUri = &#39;http://127.0.0.1:9501&#39;;

    #[Inject]
    protected Saga $saga;

    #[GetMapping(path: &#39;successCase&#39;)]
    public function successCase(): string
    {
        $payload = [&#39;amount&#39; => 50];
        // 初始化 Saga 事务
        $this->saga->init();
        // 增加转出子事务
        $this->saga->add(
            $this->serviceUri . &#39;/saga/transOut&#39;, 
            $this->serviceUri . &#39;/saga/transOutCompensate&#39;, 
            $payload
        );
        // 增加转入子事务
        $this->saga->add(
            $this->serviceUri . &#39;/saga/transIn&#39;, 
            $this->serviceUri . &#39;/saga/transInCompensate&#39;, 
            $payload
        );
        // 提交 Saga 事务
        $this->saga->submit();
        // 通过 TransContext::getGid() 获得 全局事务ID 并返回
        return TransContext::getGid();
    }
}
特性 DTM SEATA #備註
Go、C#、Java、Python、PHP… Java
支援資料庫、Redis、Mongo等 資料庫
# 子交易屏障會自動處理 DTM 解決了冪等、懸掛、空補償
##極簡易用 複雜狀態機
最簡訊息最終一致性架構 TCC交易

XA交易

#AT交易
AT 與XA類似,但有髒回滾 單一服務多資料來源

#通訊協定
Dubbo等協定 DTM對雲端原生更友善 star數量
github starsgithub stars

以上是【DTM】PHP協程客戶端v0.1 beta版本發布囉!的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:learnku.com。如有侵權,請聯絡admin@php.cn刪除