2.3 非侵入模式接入
2.3.6 Dubbo ServiceComb 接入 DTM 样例指南
本章节介绍Dubbo ServiceComb框架下DTM使用的demo,使得Dubbo ServiceComb 框架下的项目可以通过非侵入模式快速接入DTM。
Dubbo ServiceComb样例中使用Dubbo ServiceComb框架,样例流程如图2-2所示。
● 组成:bankA服务、bankB服务、bankCenter(金融中心)服务。
@DTMTxBegin(appName = "noninvasive-transfer-dubbo-servicecomb") public String transfer(int id, int money, int errRate) {
LOGGER.info("Bank-center start invoke bankA and bankB: {}", DTMContext.getDTMContext().getGlobalTxId());
bankAController.transfer(id, money, errRate);
bankBController.transfer(id, money, errRate);
return "ok";
}
最佳实践 2 使用 DTM 保证银行转账业务数据一致性
bankA 服务
● 增加数据源DTMDataSource
// com.huawei.dubbo.banka.config.WebConfig.java;
@Bean(name = "bankDataSource")
@ConfigurationProperties(prefix = "spring.datasource.bank") public DataSource bankDataSource() {
return new DTMDataSource(datasource);
}@Bean(name = "bankJdbcTemplate")
public JdbcTemplate bankJdbcTemplate(@Qualifier("bankDataSource") DataSource dataSource) {
return new JdbcTemplate(dataSource);
}
● 实现转入业务逻辑
// com.huawei.dubbo.banka.controller.BankAController.java
public String transfer(@RequestParam(value = "id") int id, @RequestParam(value =
"money") int money, @RequestParam(value = "errRate") int errRate) { LOGGER.info("global tx id:{}, transfer in",
DTMContext.getDTMContext().getGlobalTxId());
bankAService.transferIn(id, money);
return "ok";
}// com.huawei.dubbo.common.impl.BankAService.java public void transferIn(int id, int money) {
LOGGER.info("BankA transfer in");
jdbcTemplate.update(DtmConst.TransferSql.TRANSFER_IN_SQL, money, id);
}
bankB 服务
● 增加数据源DTMDataSource
// com.huawei.dubbo.bankb.config.WebConfig.java;
@Bean(name = "bankDataSource")
@ConfigurationProperties(prefix = "spring.datasource.bank") public DataSource bankDataSource() {
return new DTMDataSource(datasource);
}@Bean(name = "bankJdbcTemplate")
public JdbcTemplate bankJdbcTemplate(@Qualifier("bankDataSource") DataSource dataSource) {
return new JdbcTemplate(dataSource);
}
● 实现转出业务逻辑
// com.huawei.dubbo.bankb.controller.BankBController.java public String transfer(int id, int money, int errRate) { LOGGER.info("global tx id:{}, transfer out", DTMContext.getDTMContext().getGlobalTxId());
ExceptionUtils.addRuntimeException(errRate);
bankBService.transferOut(id, money);
return "ok";
}// com.huawei.dubbo.bankb.config.WebConfig.java;
public void transferOut(int id, int money) { LOGGER.info("BankB transfer out");
jdbcTemplate.update(DtmConst.TransferSql.TRANSFER_OUT_SQL, money, id);
}
文档版本 01 (2021-12-28) 版权所有 © 华为技术有限公司 88
修改配置文件
application:
name: dtm-banka main:
allow-bean-definition-overriding: true datasource:
bank:
username: ${db_user_name}
password: ${db_user_pwd}
url: jdbc:mysql://${db_ip}/banka?
verifyServerCertificate=false&useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=
UTC driver-class-name: com.mysql.cj.jdbc.Driver
表 2-18 bankA-service 配置文件参数详解
参数 说明
表 2-19 dubbo.properties 配置文件参数详解
参数 说明
参数 说明
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://
www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/
dubbo.xsd">
<dubbo:application name="dtm-banka"/>
<dubbo:registry address="sc://${registry_address}"/>
<dubbo:protocol name="dubbo" port="8037"/>
<bean id="bankAController"
class="com.huawei.dubbo.banka.controller.BankAController"/>
<dubbo:service interface="com.huawei.dubbo.common.intf.IBankAController"
ref="bankAController"/>
<dubbo:provider timeout="30000"/>
</beans>
application:
name: dtm-bankb main:
allow-bean-definition-overriding: true datasource:
bank:
username: ${db_user_name}
password: ${db_user_pwd}
url: jdbc:mysql://${db_ip}/bankb?
verifyServerCertificate=false&useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=
UTC driver-class-name: com.mysql.cj.jdbc.Driver
2. 修改“dtm-dubbo-servicecomb\bankB-service\src\main\resources
3. 修改“dtm-dubbo-servicecomb\bankB-service\src\main\resources\spring
\dubbo-provider.xml”文件,参考表2-19,修改服务注册发现地址为您创建的微 服务引擎所属地址。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://
www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/
dubbo.xsd">
<dubbo:application name="dtm-bankb"/>
<dubbo:registry address="sc://${registry_address}"/>
<dubbo:protocol name="dubbo" port="8047"/>
<bean id="bankBController"
class="com.huawei.dubbo.bankb.controller.BankBController"/>
<dubbo:service interface="com.huawei.dubbo.common.intf.IBankBController"
ref="bankBController"/>
<dubbo:provider timeout="30000"/>
</beans>
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://
www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/
dubbo.xsd">
<dubbo:application name="bank-center"/>
<dubbo:registry address="sc://${registry_address}"/>
<dubbo:protocol name="dubbo" port="8031"/>
<bean id="bankCenterController"
class="com.huawei.dubbo.bank.center.controller.BankCenterController"/>
<dubbo:service interface="com.huawei.dubbo.common.intf.IBankCenterController"
ref="bankCenterController"/>
<dubbo:reference id="bankAController" check="false"
interface="com.huawei.dubbo.common.intf.IBankAController"/>
<dubbo:reference id="bankBController" check="false"
interface="com.huawei.dubbo.common.intf.IBankBController"/>
<dubbo:provider timeout="30000"/>
<dubbo:consumer cluster="dubbo-servicecomb"/>
</beans>
步骤4 修改invoke-service所需配置文件。
最佳实践 2 使用 DTM 保证银行转账业务数据一致性
1. 修改“dtm-dubbo-servicecomb\invoke-service\src\main\resources
xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://
www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/
dubbo.xsd">
<dubbo:application name="dtm-invoke"/>
<dubbo:registry address="sc://${registry_address}"/>
<dubbo:protocol name="dubbo" port="8878"/>
<dubbo:reference id="bankCenterController" check="false"
interface="com.huawei.dubbo.common.intf.IBankCenterController"/>
<dubbo:provider timeout="30000"/>
<dubbo:consumer cluster="dubbo-servicecomb"/>
</beans>
表 2-20 dtmClientConfig.properties 配置文件参数详解
参数 说明
参数 说明
rpc-ssl-switch SSL开关,该配置项可从“应用管理与运维平台”控制台
“分布式事务管理 DTM > 引擎实例”界面中得到。
● on:开启SSL
● off:关闭SSL
图 2-11 DTM 引擎实例
----结束
启动测试样例
步骤1 登录ECS,在bankAservicedubboservicecomb.jar包同级目录下,执行java
-Dfile.encoding=utf-8 -jar bankA-service-dubboservicecomb.jar启动banka服务。
步骤2 打开第二个窗口登录ECS,在bankB-service-dubboservicecomb.jar包同级目录下,执 行java -Dfile.encoding=utf-8 -jar bankB-service-dubboservicecomb.jar启动 bankb服务。
步骤3 打开第三个窗口登录ECS,在bank-center-dubboservicecomb.jar包同级目录下,执行 java -Dfile.encoding=utf-8 -jar bank-center-dubboservicecomb.jar启动
bankcenter服务。
步骤4 打开第四个窗口登录ECS,在invoke-service-dubboservicecomb.jar包同级目录下,执 行java -Dfile.encoding=utf-8 -jar invoke-service-dubboservicecomb.jar启动 invoke服务。
[0] 初始化数据库, 重置账号资金;
[1] 查询 Bank A 和 Bank B 余额;
[2] 非侵入用例 -> DTM 事务 微服务场景调用;
[3] TCC用例 -> DTM 事务 微服务场景调用;
[4] EXIT;
请输入命令执行操作:(当前远程调用/dubbo)
步骤5 在invoke服务中,输入命令0初始化数据库。
请输入命令执行操作:(当前远程调用/dubbo)
02021-06-15 21:00:32.905 INFO 16772 --- [main] c.h.dtm.invoke.service.TransferService: Init bankA bankB success
步骤6 输入命令1查询BankA和BankB帐号余额。
|--- userId ---|--- bankA-money ---|--- bankB-money ---|---- sum ----|
| 0| 1000000| 1000000| 2000000|
| 1| 1000000| 1000000| 2000000|
| 2| 1000000| 1000000| 2000000|
| 3| 1000000| 1000000| 2000000|
| 4| 1000000| 1000000| 2000000|
...
| 496| 1000000| 1000000| 2000000|
| 497| 1000000| 1000000| 2000000|
| 498| 1000000| 1000000| 2000000|
最佳实践 2 使用 DTM 保证银行转账业务数据一致性
| 499| 1000000| 1000000| 2000000|
2021-03-23 14:25:29,799 [INFO] Run finish. total a 500000000,total b 500000000,sum 1000000000
步骤7 输入命令2,执行非侵入样例DTM事务的微服务场景验证。
|--- userId ---|--- bankA-money ---|--- bankB-money ---|---- sum ----|
| 0| 1000000| 1000000| 2000000|
2021-06-15 21:01:41.243 INFO 16772 --- [main] c.h.dtm.invoke.service.TransferService: Run finish. total a 500004500,total b 499995500,sum 1000000000