這篇文章主要講解了“PHP協(xié)程客戶端v0.1 beta版本有哪些新特性”,文中的講解內(nèi)容簡(jiǎn)單清晰,易于學(xué)習(xí)與理解,下面請(qǐng)大家跟著小編的思路慢慢深入,一起來(lái)研究和學(xué)習(xí)“PHP協(xié)程客戶端v0.1 beta版本有哪些新特性”吧!
創(chuàng)新互聯(lián)的團(tuán)隊(duì)成員不追求數(shù)量、追求質(zhì)量。我們經(jīng)驗(yàn)豐富并且專業(yè),我們之間合作時(shí)就好像一個(gè)人,協(xié)同一致毫無(wú)保留。創(chuàng)新互聯(lián)珍視想法,同時(shí)也看重過(guò)程轉(zhuǎn)化帶來(lái)的沖擊力和影響力,在我們眼中,任何細(xì)節(jié)都不容小覷。一直致力于為企業(yè)提供從國(guó)際域名空間、網(wǎng)站策劃、網(wǎng)站設(shè)計(jì)、購(gòu)物商城網(wǎng)站建設(shè)、網(wǎng)站推廣、網(wǎng)站優(yōu)化到為企業(yè)提供個(gè)性化軟件開(kāi)發(fā)等基于互聯(lián)網(wǎng)的全面整合營(yíng)銷(xiāo)服務(wù)。
dtm/dtm-client 是分布式事務(wù)管理器 DTM 的 PHP 客戶端,已支持 TCC模式、Saga、二階段消息模式的分布式事務(wù)模式,并分別實(shí)現(xiàn)了與 DTM Server 以 HTTP 協(xié)議或 gRPC 協(xié)議通訊,該客戶端可安全運(yùn)行于 PHP-FPM 和 Swoole 協(xié)程環(huán)境中,更是對(duì) Hyperf 做了更加易用的功能支持。
DTM 是一款基于 Go 語(yǔ)言實(shí)現(xiàn)的開(kāi)源分布式事務(wù)管理器,提供跨語(yǔ)言,跨存儲(chǔ)引擎組合事務(wù)的強(qiáng)大功能。DTM 優(yōu)雅的解決了冪等、空補(bǔ)償、懸掛等分布式事務(wù)難題,也提供了簡(jiǎn)單易用、高性能、易水平擴(kuò)展的分布式事務(wù)解決方案。
極易上手
零配置啟動(dòng)服務(wù),提供非常簡(jiǎn)單的 HTTP 接口,極大降低上手分布式事務(wù)的難度
跨語(yǔ)言
可適合多語(yǔ)言棧的公司使用。方便 Go、Python、PHP、NodeJs、Ruby、C# 等各類(lèi)語(yǔ)言使用。
使用簡(jiǎn)單
開(kāi)發(fā)者不再擔(dān)心懸掛、空補(bǔ)償、冪等各類(lèi)問(wèn)題,首創(chuàng)子事務(wù)屏障技術(shù)代為處理
易部署、易擴(kuò)展
僅依賴 MySQL/redis,部署簡(jiǎn)單,易集群化,易水平擴(kuò)展
多種分布式事務(wù)協(xié)議支持
TCC、SAGA、XA、二階段消息,一站式解決多種分布式事務(wù)問(wèn)題
在非 Java 語(yǔ)言下,暫未看到除 DTM 之外的成熟的分布式事務(wù)管理器,因此這里將 DTM 和 Java 中最成熟的開(kāi)源項(xiàng)目 Seata 做對(duì)比:
特性 | DTM | SEATA | 備注 |
---|---|---|---|
支持語(yǔ)言 | Go、C#、Java、Python、PHP… | Java | DTM 可輕松接入一門(mén)新語(yǔ)言 |
存儲(chǔ)引擎 | 支持?jǐn)?shù)據(jù)庫(kù)、Redis、Mongo等 | 數(shù)據(jù)庫(kù) | |
異常處理 | 子事務(wù)屏障自動(dòng)處理 | 手動(dòng)處理 | DTM 解決了冪等、懸掛、空補(bǔ)償 |
SAGA事務(wù) | 極簡(jiǎn)易用 | 復(fù)雜狀態(tài)機(jī) | |
二階段消息 | ? | ? | 最簡(jiǎn)消息最終一致性架構(gòu) |
TCC事務(wù) | ? | ? | |
XA事務(wù) | ? | ? | |
AT事務(wù) | 建議使用XA | ? | AT 與 XA類(lèi)似,但有臟回滾 |
單服務(wù)多數(shù)據(jù)源 | ? | ? | |
通信協(xié)議 | HTTP、gRPC | Dubbo等協(xié)議 | DTM對(duì)云原生更加友好 |
star數(shù)量 | DTM 從 2021-06-04 發(fā)布 0.1版本,發(fā)展飛快 |
從上面對(duì)比的特性來(lái)看,DTM 在許多方面都具備很大的優(yōu)勢(shì)。如果考慮多語(yǔ)言支持、多存儲(chǔ)引擎支持,那么 DTM 毫無(wú)疑問(wèn)是您的首選.
通過(guò) Composer 可以非常方便的安裝 dtm-client
composer require dtm/dtm-client
使用時(shí)別忘了啟動(dòng) DTM Server 哦
如果您是在 Hyperf 框架中使用,在安裝組件后,可通過(guò)下面的 vendor:publish
命令一件發(fā)布配置文件于 ./config/autoload/dtm.php
php bin/hyperf.php vendor:publish dtm/dtm-client
如果您是在非 Hyperf 框架中使用,可復(fù)制 ./vendor/dtm/dtm-client/publish/dtm.php
文件到對(duì)應(yīng)的配置目錄中。
use DtmClient\Constants\Protocol; use DtmClient\Constants\DbType; return [ // 客戶端與 DTM Server 通訊的協(xié)議,支持 Protocol::HTTP 和 Protocol::GRPC 兩種 'protocol' => Protocol::HTTP, // DTM Server 的地址 'server' => '127.0.0.1', // DTM Server 的端口 'port' => [ 'http' => 36789, 'grpc' => 36790, ], // 子事務(wù)屏障配置 'barrier' => [ // DB 模式下的子事務(wù)屏障配置 'db' => [ 'type' => DbType::MySQL ], // Redis 模式下的子事務(wù)屏障配置 'redis' => [ // 子事務(wù)屏障記錄的超時(shí)時(shí)間 'expire_seconds' => 7 * 86400, ], // 非 Hyperf 框架下應(yīng)用子事務(wù)屏障的類(lèi) 'apply' => [], ], // HTTP 協(xié)議下 Guzzle 客戶端的通用配置 'guzzle' => [ 'options' => [], ], ];
在使用之前,需要配置 DtmClient\Middleware\DtmMiddleware
中間件作為 Server 的全局中間件,該中間件支持 PSR-15 規(guī)范,可適用于各個(gè)支持該規(guī)范的的框架。
在 Hyperf 中的中間件配置可參考 Hyperf文檔 - 中間件 一章。
dtm-client 的使用非常簡(jiǎn)單,我們提供了一個(gè)示例項(xiàng)目 dtm-php/dtm-sample 來(lái)幫助大家更好的理解和調(diào)試。
在使用該組件之前,也強(qiáng)烈建議您先閱讀 DTM 官方文檔,以做更詳細(xì)的了解。
TCC 模式是一種非常流行的柔性事務(wù)解決方案,由 Try-Confirm-Cancel 三個(gè)單詞的首字母縮寫(xiě)分別組成 TCC 的概念,最早是由 Pat Helland 于 2007 年發(fā)表的一篇名為《Life beyond Distributed Transactions:an Apostate’s Opinion》的論文中提出。
Try 階段:嘗試執(zhí)行,完成所有業(yè)務(wù)檢查(一致性), 預(yù)留必須業(yè)務(wù)資源(準(zhǔn)隔離性)
Confirm 階段:如果所有分支的 Try 都成功了,則走到 Confirm 階段。Confirm 真正執(zhí)行業(yè)務(wù),不作任何業(yè)務(wù)檢查,只使用 Try 階段預(yù)留的業(yè)務(wù)資源
Cancel 階段:如果所有分支的 Try 有一個(gè)失敗了,則走到 Cancel 階段。Cancel 釋放 Try 階段預(yù)留的業(yè)務(wù)資源。
如果我們要進(jìn)行一個(gè)類(lèi)似于銀行跨行轉(zhuǎn)賬的業(yè)務(wù),轉(zhuǎn)出(TransOut)和轉(zhuǎn)入(TransIn)分別在不同的微服務(wù)里,一個(gè)成功完成的 TCC 事務(wù)典型的時(shí)序圖如下:
以下展示在 Hyperf 框架中的使用方法,其它框架類(lèi)似
tcc->globalTransaction(function (TCC $tcc) { // 創(chuàng)建子事務(wù) A 的調(diào)用數(shù)據(jù) $tcc->callBranch( // 調(diào)用 Try 方法的參數(shù) ['amount' => 30], // Try 方法的 URL $this->serviceUri . '/tcc/transA/try', // Confirm 方法的 URL $this->serviceUri . '/tcc/transA/confirm', // Cancel 方法的 URL $this->serviceUri . '/tcc/transA/cancel' ); // 創(chuàng)建子事務(wù) B 的調(diào)用數(shù)據(jù),以此類(lèi)推 $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()); } // 通過(guò) TransContext::getGid() 獲得 全局事務(wù)ID 并返回 return TransContext::getGid(); } }
Saga 模式是分布式事務(wù)領(lǐng)域最有名氣的解決方案之一,也非常流行于各大系統(tǒng)中,最初出現(xiàn)在 1987 年 由 Hector Garcaa-Molrna & Kenneth Salem 發(fā)表的論文 SAGAS 里。
Saga 是一種最終一致性事務(wù),也是一種柔性事務(wù),又被叫做 長(zhǎng)時(shí)間運(yùn)行的事務(wù)(Long-running-transaction),Saga 是由一系列的本地事務(wù)構(gòu)成。每一個(gè)本地事務(wù)在更新完數(shù)據(jù)庫(kù)之后,會(huì)發(fā)布一條消息或者一個(gè)事件來(lái)觸發(fā) Saga 全局事務(wù)中的下一個(gè)本地事務(wù)的執(zhí)行。如果一個(gè)本地事務(wù)因?yàn)槟承I(yè)務(wù)規(guī)則無(wú)法滿足而失敗,Saga 會(huì)執(zhí)行在這個(gè)失敗的事務(wù)之前成功提交的所有事務(wù)的補(bǔ)償操作。所以 Saga 模式在對(duì)比 TCC 模式時(shí),因缺少了資源預(yù)留的步驟,往往在實(shí)現(xiàn)回滾邏輯時(shí)會(huì)變得更麻煩。
比如我們要進(jìn)行一個(gè)類(lèi)似于銀行跨行轉(zhuǎn)賬的業(yè)務(wù),將 A 賬戶中的 30 元轉(zhuǎn)到 B 賬戶,根據(jù) Saga 事務(wù)的原理,我們將整個(gè)全局事務(wù),拆分為以下服務(wù):
轉(zhuǎn)出(TransOut)服務(wù),這里將會(huì)進(jìn)行操作 A 賬戶扣減 30 元
轉(zhuǎn)出補(bǔ)償(TransOutCompensate)服務(wù),回滾上面的轉(zhuǎn)出操作,即 A 賬戶增加 30 元
轉(zhuǎn)入(TransIn)服務(wù),這里將會(huì)進(jìn)行 B 賬戶增加 30 元
轉(zhuǎn)出補(bǔ)償(TransInCompensate)服務(wù),回滾上面的轉(zhuǎn)入操作,即 B 賬戶減少 30 元
整個(gè)事務(wù)的邏輯是:
執(zhí)行轉(zhuǎn)出成功 => 執(zhí)行轉(zhuǎn)入成功 => 全局事務(wù)完成
如果在中間發(fā)生錯(cuò)誤,例如轉(zhuǎn)入 B 賬戶發(fā)生錯(cuò)誤,則會(huì)調(diào)用已執(zhí)行分支的補(bǔ)償操作,即:
執(zhí)行轉(zhuǎn)出成功 => 執(zhí)行轉(zhuǎn)入失敗 => 執(zhí)行轉(zhuǎn)入補(bǔ)償成功 => 執(zhí)行轉(zhuǎn)出補(bǔ)償成功 => 全局事務(wù)回滾完成
下面是一個(gè)成功完成的 SAGA 事務(wù)典型的時(shí)序圖:
以下展示在 Hyperf 框架中的使用方法,其它框架類(lèi)似
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 事務(wù) $this->saga->init(); // 增加轉(zhuǎn)出子事務(wù) $this->saga->add( $this->serviceUri . '/saga/transOut', $this->serviceUri . '/saga/transOutCompensate', $payload ); // 增加轉(zhuǎn)入子事務(wù) $this->saga->add( $this->serviceUri . '/saga/transIn', $this->serviceUri . '/saga/transInCompensate', $payload ); // 提交 Saga 事務(wù) $this->saga->submit(); // 通過(guò) TransContext::getGid() 獲得 全局事務(wù)ID 并返回 return TransContext::getGid(); } }
感謝各位的閱讀,以上就是“PHP協(xié)程客戶端v0.1 beta版本有哪些新特性”的內(nèi)容了,經(jīng)過(guò)本文的學(xué)習(xí)后,相信大家對(duì)PHP協(xié)程客戶端v0.1 beta版本有哪些新特性這一問(wèn)題有了更深刻的體會(huì),具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是創(chuàng)新互聯(lián),小編將為大家推送更多相關(guān)知識(shí)點(diǎn)的文章,歡迎關(guān)注!