应用管理与运维平台 ServiceStage应用管理与运维平台 ServiceStage

更新时间:2021/09/07 GMT+08:00
分享

ServiceComb接入DTM样例指南

本章节介绍ServiceComb 框架下DTM使用的demo,使得ServiceComb框架下的项目可以快速接入DTM。

其中,ServiceComb的样例代码在导入样例工程过程中准备的dtm-demo的dtm-servicecomb项目中。

前提条件

  1. 创建微服务引擎,请参考创建微服务引擎专享版
  2. (可选)获取AK/SK与项目名称,请参考AK/SK获取方法
    • 使用微服务引擎专业版,需要配置AK/SK。
    • 使用未开启安全认证的微服务引擎专享版,不需要配置AK/SK。

      DTM不支持开启了安全认证的微服务引擎专享版。

样例设计

ServiceComb样例中使用ServiceComb框架,样例流程如图1所示。

  • 组成:bankA服务、bankB服务、bankCenter服务。
  • 功能:bankCenter服务调用bankA和bankB服务进行初始化和转账等操作。

业务流程分析

  • 正常场景:BankA转入100,BankB转出100,两银行金额之和保持1000000000不变。
  • 异常场景:BankA转入100,发生异常情况,bankB转出失败,DTM会帮助回滚bankA的数据,两银行金额之和保持1000000000不变。
图1 非侵入样例代码设计流程

DTM全局事务发起者

定义非侵入样例微服务场景事务发起端,通过微服务接口调用bankA转入服务和bankB转出服务,同时概率抛出异常。

// com.huawei.bankcenter.controller.BankCenterController.java
@GetMapping(value = "transfer")
@DTMTxBegin(appName = "noninvasive-transfer-ServiceComb")
public String transfer(@RequestParam(value = "id") int id, @RequestParam(value = "money") int money, @RequestParam(value = "errRate") int errRate) {
    LOGGER.info("Bank-center start invoke bankA and bankB");
    restInvoker.getForObject(String.format(BANKA_TRANSFER, id, money, errRate), String.class);
    restInvoker.getForObject(String.format(BANKB_TRANSFER, id, money, errRate), String.class);
    return "ok";
}

bankA服务

  • 增加数据源DTMDataSource
    // com.huawei.banka.config.DataSourceConfig;
    @Bean(name = "BankADataSource")
    @Qualifier("BankADataSource")
    @ConfigurationProperties(prefix = "spring.datasource.banka")
    public DataSource bankBDataSource() {
        ...
        return new DTMDataSource(datasource);
    }
    @Bean(name = "bankaJdbcTemplate")
    public JdbcTemplate bankbJdbcTemplate(@Qualifier("BankADataSource") DataSource dataSource) {
        return new JdbcTemplate(dataSource);
    }
  • 实现转入业务逻辑
    // com.huawei.banka.controller.BankAController.java
    @GetMapping(value = "transfer")
    public String transfer(@RequestParam(value = "id") int id, @RequestParam(value = "money") int money) {
        bankAService.transferIn(id, money);
        return "ok";
    }
    // com.huawei.common.BankService 
    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.bankb.config.WebConfig;
    @Bean(name = "BankBDataSource")
    @Qualifier("BankBDataSource")
    @ConfigurationProperties(prefix = "spring.datasource.bankb")
    public DataSource bankBDataSource() {
        ...
        return new DTMDataSource(datasource);
    }
    
    @Bean(name = "bankbJdbcTemplate")
    public JdbcTemplate bankbJdbcTemplate(@Qualifier("BankBDataSource") DataSource dataSource) {
        return new JdbcTemplate(dataSource);
    }
  • 实现转出业务逻辑
    // com.huawei.bankb.controller.BankBController.java
    @GetMapping(value = "transfer")
    public String transfer(@RequestParam(value = "id") int id, @RequestParam(value = "money") int money, @RequestParam(value = "errRate") int errRate) {
        ExceptionUtil.addRuntimeException(errRate);
        bankBService.transferOut(id, money);
        return "ok";
    }
    // com.huawei.common.BankService 
    public void transferOut(int id, int money) {
        LOGGER.info("BankB transfer out");
        jdbcTemplate.update(DtmConst.TransferSql.TRANSFER_OUT_SQL, money, id);
    }

修改配置文件

  1. 通过IDEA打开dtm-servicecomb项目,修改banka所需配置文件。

    1. 修改“dtm-servicecomb\bank-a\src\main\resources\microservice.yaml”文件中的数据库配置信息,参考表1,修改username、password和url为您创建好的数据库用户名、密码和地址,拷贝完成后保存退出。
      spring:
        datasource:
          banka:
            username: ${db_user_name}
            password: ${db_user_pwd}
            url: jdbc:mysql://${db_ip}:3306/banka?verifyServerCertificate=false&useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC
      表1 microservice.yaml配置文件参数详解

      参数

      说明

      db_user_name

      客户端MySQL数据库用户名。

      db_user_pwd

      客户端MySQL数据库的密码。

      db_ip

      客户端MySQL数据库业务数据库地址,分别为banka和bankb的地址,根据实际修改。

    2. 修改“dtm-servicecomb\bank-a\src\main\resources\microservice.yaml”文件中的handler配置,Consumer增加dtm-consumer,Provider增加dtm-provider。
      servicecomb:
        ...
        handler:
          chain:
            Consumer:
              default: loadbalance,bizkeeper-consumer,dtm-consumer
            Provider:
              default: dtm-provider
    3. 修改“dtm-servicecomb\bank-a\src\main\resources\microservice.yaml”文件中的address信息,参考表2
      servicecomb:
        service:
          registry:
            address: ${cse_address}
      表2 配置microservice.yaml servicecomb参数详解

      参数

      说明

      cse_address

      服务注册发现地址,该配置项可从“应用管理与运维平台”微服务 CSE > 引擎实例界面中得到。

    4. (可选)配置AK/SK。

      如果使用微服务引擎专业版,需要配置AK/SK;如果使用未开启安全认证的微服务引擎专享版,不需要配置AK/SK,可以跳过这个步骤。

      “microservice.yaml”文件中添加以下配置信息,并修改accessKey、secretKey和project。
        servicecomb:  
          credentials:
            accessKey: AK
            secretKey: SK
            project: 项目名称
            akskCustomCipher: default

  2. 修改bankb所需配置文件。

    1. 修改“dtm-servicecomb\bank-b\src\main\resources\microservice.yaml”文件中的数据库配置信息,参考表1,修改username、password和url为您创建好的数据库用户名、密码和地址,拷贝完成后保存退出。
      spring:
        datasource:
          bankb:
            username: ${db_user_name}
            password: ${db_user_pwd}
            url: jdbc:mysql://${db_ip}:3306/bankb?verifyServerCertificate=false&useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC
    2. 修改“dtm-servicecomb\bank-b\src\main\resources\microservice.yaml”文件中的handler配置,Consumer增加dtm-consumer,Provider增加dtm-provider。
      servicecomb:
        ...
        handler:
          chain:
            Consumer:
              default: loadbalance,bizkeeper-consumer,dtm-consumer
            Provider:
              default: dtm-provider
    3. 修改“dtm-servicecomb\bank-b\src\main\resources\microservice.yaml”文件中address信息,参考表2
      servicecomb:
        service:
          registry:
            address: ${cse_address}
    4. (可选)配置AK/SK。

      如果使用微服务引擎专业版,需要配置AK/SK;如果使用未开启安全认证的微服务引擎专享版,不需要配置AK/SK,可以跳过这个步骤。

      “microservice.yaml”文件中添加以下配置信息,并修改accessKey、secretKey和project。
        servicecomb:  
          credentials:
            accessKey: AK
            secretKey: SK
            project: 项目名称
            akskCustomCipher: default

  3. 修改bankcenter所需配置文件。

    1. 修改“dtm-servicecomb\bank-center\src\main\resources\microservice.yaml”文件中的handler配置,Consumer增加dtm-consumer,Provider增加dtm-provider。
      servicecomb:
        ...
        handler:
          chain:
            Consumer:
              default: loadbalance,bizkeeper-consumer,dtm-consumer
            Provider:
              default: dtm-provider
    2. 修改“dtm-servicecomb\bank-center\src\main\resources\microservice.yaml”文件中servicecomb信息,参考表2
      servicecomb:
        service:
          registry:
            address: ${cse_address}
    3. (可选)配置AK/SK。

      如果使用微服务引擎专业版,需要配置AK/SK;如果使用未开启安全认证的微服务引擎专享版,不需要配置AK/SK,可以跳过这个步骤。

      “microservice.yaml”文件中添加以下配置信息,并修改accessKey、secretKey和project。
        servicecomb:  
          credentials:
            accessKey: AK
            secretKey: SK
            project: 项目名称
            akskCustomCipher: default

  4. 修改invoke所需配置文件。

    1. 修改“dtm-servicecomb\invoke-service\src\main\resources\microservice.yaml”文件中的handler配置,Consumer增加dtm-consumer,Provider增加dtm-provider。
      servicecomb:
        ...
        handler:
          chain:
            Consumer:
              default: loadbalance,bizkeeper-consumer,dtm-consumer
            Provider:
              default: dtm-provider
    2. 修改“dtm-servicecomb\invoke-service\src\main\resources\microservice.yaml”文件中servicecomb信息,参考表2
      servicecomb:
        service:
          registry:
            address: ${cse_address}
    3. (可选)配置AK/SK。

      如果使用微服务引擎专业版,需要配置AK/SK;如果使用未开启安全认证的微服务引擎专享版,不需要配置AK/SK,可以跳过这个步骤。

      “microservice.yaml”文件中添加以下配置信息,并修改accessKey、secretKey和project。
        servicecomb:  
          credentials:
            accessKey: AK
            secretKey: SK
            project: 项目名称
            akskCustomCipher: default

  5. 通过Maven执行clean、install,将工程进行打包,生成banka、bankb、bankcenter以及invoke服务的jar包。
  6. 登录创建好的弹性云服务器,将四个jar包放在同级目录下,同时在目录下新建“dtm-config”文件夹。在新建目录“dtm-config”下,新建配置文件“dtmClientConfig.properties”,将下列配置拷贝到配置文件“dtmClientConfig.properties”中,参考表3,按实际修改auto-create-table-dtm-tran-info、dtm-app-name、sc-server-address和rpc-ssl-switch。

    auto-create-table-dtm-tran-info=on
    dtm-app-name=xxxx
    sc-server-address=xxxx
    rpc-ssl-switch=off
    表3 dtmClientConfig.properties配置文件参数详解

    参数

    说明

    auto-create-table-dtm-tran-info

    是否自动创建DTM事务表dtm_tran_info,用来记录事务信息。

    • on:自动创建
    • off:手动创建

    dtm-app-name

    应用名称,该配置项可从“应用管理与运维平台”分布式事务管理 DTM > 引擎实例界面中得到。

    sc-server-address

    服务中心地址,该配置项可从“应用管理与运维平台”分布式事务管理 DTM > 引擎实例界面中得到。

    rpc-ssl-switch

    SSL开关,该配置项可从“应用管理与运维平台”分布式事务管理 DTM > 引擎实例界面中得到。

    • on:开启SSL
    • off:关闭SSL

启动测试样例

  1. 登录ECS,在bankA-service-servicecomb.jar包同级目录下,执行java -Dfile.encoding=utf-8 -jar bankA-service-servicecomb.jar启动banka服务。
  2. 打开第二个窗口登录ECS,在bankB-service-servicecomb.jar包同级目录下,执行java -Dfile.encoding=utf-8 -jar bankB-service-servicecomb.jar启动bankb服务。
  3. 打开第三个窗口登录ECS,在bankCenter-service-servicecomb.jar包同级目录下,执行java -Dfile.encoding=utf-8 -jar bankCenter-service-servicecomb.jar启动bankcenter服务。
  4. 打开第四个窗口登录ECS,在invoke-service-servicecomb.jar包同级目录下,执行java -Dfile.encoding=utf-8 -jar invoke-service-servicecomb.jar启动invoke服务。

    [0] 初始化数据库, 重置账号资金;
    [1] 查询 Bank A 和 Bank B 余额;
    [2] 非侵入用例 -> DTM 事务 微服务场景调用;
    [3] TCC用例 -> DTM 事务 微服务场景调用;
    [4] DTM对接消息用例 -> DTM 事务 微服务场景调用;
    [5] EXIT;
    请选择命令执行操作

  5. 在invoke服务中,输入命令0初始化数据库。

    2021-03-23 11:51:59.417 [main] INFO  c.h.d.c.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|
    |           499|            1000000|            1000000|      2000000|
    2021-03-23 14:25:29,799 [INFO] Run finish. total a 500000000,total b 500000000,sum 1000000000 com.huawei.client.service.TransferService.queryMoney(TransferService.java:74)

  7. 输入命令2,执行非侵入样例DTM事务的微服务场景验证。
  8. 输入运行的线程数量、每个线程的事务数量以及发生异常的概率值,输入格式为线程数量:单线程事务数量:异常概率,运行结束后输入命令1查询帐号余额,结果如下图所示。bankA转入了钱,bankB转出了钱,两者总和保持1000000000不变。

    请输入命令执行操作:(当前远程调用/feign)
    2
    请输入线程数量:单线程事务数量:异常概率
    10:10:50
    ......
    |--- userId ---|--- bankA-money ---|--- bankB-money ---|---- sum ----|
    |             0|            1000000|            1000000|      2000000|
    |             1|            1000000|            1000000|      2000000|
    |             2|            1000100|             999900|      2000000|
    |             3|            1000100|             999900|      2000000|
    |             4|            1000100|             999900|      2000000|
    ......
    |           496|            1000100|             999900|      2000000|
    |           497|            1000000|            1000000|      2000000|
    |           498|            1000000|            1000000|      2000000|
    |           499|            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
    com.huawei.client.service.TransferService.queryMoney(TransferService.java:74)

  9. 输入命令5退出执行程序。
分享:

    相关文档

    相关产品