DTM Java SDK 2.1.4釋出,支援springcloud

葉東富發表於2022-05-30

https://github.com/dtm-labs/dtm 是一款變革性的分散式事務框架,提供了傻瓜式的使用方式,極大的降低了分散式事務的使用門檻,改變了“能不用分散式事務就不用”的行業現狀,優雅的解決了服務間的資料一致性問題。

特性

  • 支援多種語言:支援Go、Java、PHP、C#、Python、Nodejs 各種語言的SDK
  • 支援多種事務模式:SAGA、TCC、XA、二階段訊息(本地訊息表,事務訊息)
  • 支援多種資料庫事務:Mysql、Redis、MongoDB、Postgres、TDSQL等
  • 支援多種儲存引擎:Mysql(常用)、Redis(高效能)、MongoDB(規劃中)
  • 支援多種微服務架構:go-zero、go-kratos/kratos、polarismesh/polaris
  • 支援高可用,易水平擴充套件

Java SDK 新版的主要改進

  1. 支援spring cloud微服務系列元件
  2. 引入可插拔的微服務註冊中心相關依賴,使用者可以根據實際情況引入不同的plugin
  3. 優化了整體包結構

感謝 https://github.com/horseLk 的貢獻,這次版本更新,主要由他完成

dtmcli-java新版實現

github倉庫地址:https://github.com/dtm-labs/d...

專案結構

|--dtmcli-java-parent # parent module
   |--dtmcli-common # dtmcli common module
   |--dtmcli-core # dtmcli core module
   |--dtmcli-java # dtmcli java client
   |--dtmcli-springcloud # dtmcli springcloud client
   |--*-plugin # dtmcli plugin

image.png

dtmcli-java新版快速開始

dtmcli-java新版本提供了多種不同的實現方式,在對原有Java客戶端儘可能相容的基礎上進行了改進優化並對微服務進行了支援。新版本的java客戶端提供了多種靈活的實現,可以根據業務場景進行選擇。

使用範例

使用HTTP介面開啟一個自動生成gid的TCC事務

DtmClient dtmClient;

// 根據dtmsvr自動生成gid
dtmClient.tccGlobalTransaction(new DtmConsumer<Tcc>() {
    @Override
    public void accept(Tcc tcc) throws Exception {
        String svc = "http://127.0.0.1:8888";
        Response outResponse = tcc.callBranch( "", svc + "/TransOutTry", svc + "/TransOutConfirm",
                                              svc + "/TransOutCancel");
      
        Response inResponse = tcc.callBranch("", svc + "/TransInTry", svc + "/TransInConfirm",
                                             svc + "/TransInCancel");
    }
});

// 使用自定義的gid
dtmClient.tccGlobalTransaction("custom_gid_123456", new DtmConsumer<Tcc>() {
    @Override
    public void accept(Tcc tcc) throws Exception {
        String svc = "http://127.0.0.1:8888";
        Response outResponse = tcc.callBranch( "", svc + "/TransOutTry", svc + "/TransOutConfirm",
                                              svc + "/TransOutCancel");
      
        Response inResponse = tcc.callBranch("", svc + "/TransInTry", svc + "/TransInConfirm",
                                             svc + "/TransInCancel");
    }
});

使用微服務介面開啟一個TCC事務

DtmClient dtmClient;

// 根據dtmsvr自動生成gid
dtmClient.tccGlobalTransaction(new DtmConsumer<Tcc>() {
    @Override
    public void accept(Tcc tcc) throws Exception {
        String appName = "serviceName";
        tcc.callBranch(new HashMap<>(), new ServiceMessage(appName, "/TransOutTry"),
                new ServiceMessage(appName, "/TransOutConfirm"), new ServiceMessage(appName, "/TransOutCancel"));

        tcc.callBranch(new HashMap<>(), new ServiceMessage(appName, "/TransInTry"),
                new ServiceMessage(appName, "/TransInConfirm"), new ServiceMessage(appName, "/TransInCancel"));

    }
});

// 使用自定義的gid
dtmClient.tccGlobalTransaction("custom_gid_123456", new DtmConsumer<Tcc>() {
    @Override
    public void accept(Tcc tcc) throws Exception {
        String appName = "serviceName";
        tcc.callBranch(new HashMap<>(), new ServiceMessage(appName, "/TransOutTry"),
                new ServiceMessage(appName, "/TransOutConfirm"), new ServiceMessage(appName, "/TransOutCancel"));

        tcc.callBranch(new HashMap<>(), new ServiceMessage(appName, "/TransInTry"),
                new ServiceMessage(appName, "/TransInConfirm"), new ServiceMessage(appName, "/TransInCancel"));

    }
});

使用HTTP介面開啟一個SAGA事務

DtmClient dtmClient;
String svc = "127.0.0.1:8888";

// 從dtmsvr獲取gid
Saga saga = dtmClient
    .newSaga()
    .add(svc + "/TransOut", svc + "/TransOutCompensate", "")
    .add(svc + "/TransIn", svc + "/TransInCompensate", "")
    .enableWaitResult()
    .submit();

// 自定義gid
Saga saga = dtmClient
    .newSaga("custom_gid_123456")
    .add(svc + "/TransOut", svc + "/TransOutCompensate", "")
    .add(svc + "/TransIn", svc + "/TransInCompensate", "")
    .enableWaitResult()
    .submit();

使用微服務介面開啟一個SAGA事務

DtmClient dtmClient;
String serviceName = "serviceName";

// 從dtmsvr獲取gid
Saga saga = dtmClient
    .newSaga()
    .add(new ServiceMessage(serviceName, "/TransOut"), new ServiceMessage(serviceName, "/TransOutCompensate"), "")
    .add(new ServiceMessage(serviceName, "/TransIn"), new ServiceMessage(serviceName, "/TransInCompensate"), "")
    .enableWaitResult()
    .submit();

// 自定義gid
Saga saga = dtmClient
    .newSaga("custom_gid_123456")
    .add(new ServiceMessage(serviceName, "/TransOut"), new ServiceMessage(serviceName, "/TransOutCompensate"), "")
    .add(new ServiceMessage(serviceName, "/TransIn"), new ServiceMessage(serviceName, "/TransInCompensate"), "")
    .enableWaitResult()
    .submit();

如何獲取DtmClient物件

spring-cloud客戶端

DtmClient物件已經注入到容器中,只需要在你需要使用的類中通過@Autowired註解引入即可.

@Autowired
private DtmClient dtmClient;

dtmcli-java客戶端

直連dtmsvr

只需要將dtmsvr的服務地址傳給建構函式即可。

DtmClient dtmClient = new DtmClient("127.0.0.1:36789");

當然如你想講直連的地址設定到配置檔案中,只需要新增一個命名為dtm-conf.properties的配置檔案,配置檔案格式如下:

# dtmsvr地址
dtm.ipport=121.4.131.37:36789
使用服務發現

如果您使用了服務發現並且現有支援的springcloud版本不相容您專案的版本您可以使用dtmcli-java版本,只需要新增一個命名為dtm-conf.properties的配置檔案,配置檔案格式如下:

# 服務中心地址
serverAddr=127.0.0.1:8848
# 服務中心登入username
username=nacos
# 服務中心登入密碼
password=nacos
# namespace
namespace=c3dc917d-906a-429d-90a9-85012b41014e
# dtmsvr註冊到服務中心的服務名
dtm.service.name=dtmService
# 服務中心型別
dtm.service.registryType=nacos

注意:我們對一個配置檔案有兩種不同的配置方式,如果同時使用了兩種,會優先選擇直連方式。

pom引入dtmcli java客戶端

springboot version >= 2.6.0

# dtmcli依賴
<dependency>
  <groupId>io.github.dtm-labs</groupId>
  <artifactId>dtmcli-springcloud</artifactId>
  <version>2.1.4.2</version>
</dependency>
# 使用的服務中心外掛,如果您的專案中已經引入了相關依賴,則可以忽略
<dependency>
  <groupId>io.github.dtm-labs</groupId>
  <artifactId>nacos-plugin</artifactId>
  <version>2.1.4.2</version>
</dependency>

2.4.0 <= springboot version < 2.6.0

# dtmcli依賴
<dependency>
  <groupId>io.github.dtm-labs</groupId>
  <artifactId>dtmcli-springcloud</artifactId>
  <version>2.1.4.1</version>
</dependency>
# 使用的服務中心外掛,如果您的專案中已經引入了相關依賴,則可以忽略
<dependency>
  <groupId>io.github.dtm-labs</groupId>
  <artifactId>nacos-plugin</artifactId>
  <version>2.1.4.1</version>
</dependency>

其他情況

# dtmcli依賴
<dependency>
  <groupId>io.github.dtm-labs</groupId>
  <artifactId>dtmcli-java</artifactId>
  <version>2.1.4</version>
</dependency>

# 如果有需要也可以引入相應的服務中心外掛

dtmcli-java新版快速擴充

目前,dtmcli-java已經支援了部分開源通訊服務框架和服務中心框架,後續會針對大家的訴求儘可能支援更多的通訊服務框架和服務中心框架。但是如果你的專案使用的公司內部的通訊服務框並且想接入dtmsvr您需要完成簡單的操作就可以適配您的框架了。

新版客戶端提供了IDtmServerStub介面用於擴充不同的通訊框架,只需要使用你們專案中使用的通訊服務框架實現IDtmServerStub介面,並使用其構造一個DtmClient客戶端即可使用。考慮到需要使用自研框架的專案一般不使用開源的springcloud,並且為了防止您的框架和springcloud不相容引起問題,此建構函式僅在dtmcli-java版本中可以使用。

public DtmClient(IDtmServerStub dtmServerStub) {
    this.dtmServerStub = dtmServerStub;
}

示例程式碼

dtm-springcloud示例程式碼

https://github.com/dtm-labs/dtmcli-java-spring-sample

dtm-java使用到spring專案中

https://github.com/dtm-labs/dtmcli-java-sample

基於配置的dtmcli-java使用

https://github.com/horseLk/dtmcli-java-sample-with-conf

相關文章