(2)搞一搞 seata 之 Spring Cloud 整合

7 篇文章 0 订阅
6 篇文章 0 订阅

前言, 上一篇博主使用的seata 版本和 spring cloud 版本有很大的问题, 导致netty 通信组件有很大的兼容问题, 本次博主的pom有大更新, 上一个篇博客, 就只能学习学分布式调用了, 本地使用的工程和上次有不同, 注意注意!!!

(3条消息) (1)搞一搞 seata 之 基础环境搭建_BIG.KE的博客-CSDN博客

1 工程的升级部分

1.0 seata 版本

链接:https://pan.baidu.com/s/1BhaiMq78Xsd2eSv9vZHpxA
提取码:ettv

seata-server-1.4.1.zip

下载后解压

在这里插入图片描述

我们主要关注这两个文件,

file.conf, seata 的配置参数 默认我们可以不改, 使用文件进行记录, 交给seata 自己去玩,

register.conf, 注册文件, 这个文件我们得需要改, seata 将会以一个微服务组件注册到我们的微服务集群

registry {
  # file 、nacos 、eureka、redis、zk、consul、etcd3、sofa
  type = "eureka"
  loadBalance = "RandomLoadBalance"
  loadBalanceVirtualNodes = 10

  # 我们工程使用的eureka
  eureka {
    # 我们注册中心
    serviceUrl = "http://localhost:18790/eureka/"
    application = "default"
    weight = "1"
  }
}

config {
  # file、nacos 、apollo、zk、consul、etcd3
  type = "file"

  # 配置文件记录方式, 选择保存至文件
  file {
    name = "file.conf"
  }
}

配置好以后, 需要将两个文件复制一份到我们需要使用分布式事务的项目的resources目录下

在这里插入图片描述

给file.conf 增加一个配置

# seata 服务
service {
  #此处的vgroupMapping.xxx配置后面的xxx要与yml配置中的spring.cloud.alibaba.seata.tx-service-group一致,配置的值要与regiester.conf里的registry节点下的eureka下的application保持一致。
  vgroupMapping.my_test_tx_group = "default"
  #当注册类型为file文件时配置,不要输入多个地址,此处的地址为seata server的监听地址(seata server也有相同配置)
  default.grouplist = "127.0.0.1:8091"
  #degrade, current not support
  enableDegrade = false
  #disable seata
  disableGlobalTransaction = false
}
所有使用分布式的工程加入以下文件

import com.zaxxer.hikari.HikariDataSource;
import io.seata.rm.datasource.DataSourceProxy;
import io.seata.spring.annotation.GlobalTransactionScanner;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;

import javax.sql.DataSource;

/**
 *  seata 配置类
 */
@Configuration
public class SeataConfig {

    @Autowired
    private Environment environment;

    // GlobalTransactional seata 全局注解解析
    @Bean
    public GlobalTransactionScanner globalTransactionScanner() {
        String applicationId = environment.getProperty("spring.application.name");
        return new GlobalTransactionScanner(applicationId, "my_test_tx_group");
    }

    // 替换数据源
    @Bean
    @ConfigurationProperties(prefix = "spring.datasource.hikari")
    public DataSource dataSource(DataSourceProperties properties) {
        HikariDataSource hikariDataSource =
                properties.initializeDataSourceBuilder().type(HikariDataSource.class).build();
        return new DataSourceProxy(hikariDataSource);
    }
}

1.1 父工程 pom

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.wangke</groupId>
    <artifactId>my-cloud</artifactId>
    <packaging>pom</packaging>
    <version>1.0-SNAPSHOT</version>
    <modules>
        <module>eureka</module>
        <module>service-user</module>
        <module>service-active</module>
        <!-- 这个工程博主是准备抽取部分公共配置出来的, 暂时还没整合成功 -->
        <module>common</module>
    </modules>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.6.RELEASE</version>
        <relativePath/>
    </parent>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Finchley.SR1</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
</project>

1.2 微服务A-user

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>my-cloud</artifactId>
        <groupId>com.wangke</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>service-user</artifactId>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
        <!-- mybatis -->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>1.3.2</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.11</version>
            <scope>runtime</scope>
        </dependency>
        <!-- io.netty.util.internal.ObjectUtil.checkPositive -->
        <!-- seata -->
        <dependency>
            <groupId>io.seata</groupId>
            <artifactId>seata-all</artifactId>
            <version>1.1.0</version>
        </dependency>
    </dependencies>
</project>
server:
  port: 18791
spring:
  application:
    name: user
  datasource:
    url: jdbc:mysql://127.0.0.1:3306/wxcms?serverTimezone=UTC
    username: root
    password: 123456
    driver-class-name: com.mysql.cj.jdbc.Driver
  # seata 工作组
  cloud:
    alibaba:
      seata:
        tx-service-group: my_test_tx_group

eureka:
  client:
    service-url:
      defaultZone: http://localhost:18790/eureka/


# 日志记录级别
logging:
  level:
    io:
      seata: debug

1.3 服务器B - active

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>my-cloud</artifactId>
        <groupId>com.wangke</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>service-active</artifactId>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
        <!-- mybatis -->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>1.3.2</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.11</version>
            <scope>runtime</scope>
        </dependency>
        <!-- io.netty.util.internal.ObjectUtil.checkPositive -->
        <!-- seata -->
        <dependency>
            <groupId>io.seata</groupId>
            <artifactId>seata-all</artifactId>
            <version>1.1.0</version>
        </dependency>
    </dependencies>
</project>
server:
  port: 18792
spring:
  application:
    name: active
  datasource:
    url: jdbc:mysql://127.0.0.1:3306/wxcms?serverTimezone=UTC
    username: root
    password: 123456
    driver-class-name: com.mysql.cj.jdbc.Driver
  # seata 工作组
  cloud:
    alibaba:
      seata:
        tx-service-group: my_test_tx_group

eureka:
  client:
    service-url:
      defaultZone: http://localhost:18790/eureka/

# 日志记录级别
logging:
  level:
    io:
      seata: debug

1.4 注册中心-Eureka

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>my-cloud</artifactId>
        <groupId>com.wangke</groupId>
        <version>1.0-SNAPSHOT</version>
        <relativePath>../pom.xml</relativePath>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <packaging>jar</packaging>
    <artifactId>eureka</artifactId>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <!--增加eureka-server的依赖-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>
        <!--用于测试的,本例可省略-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
</project>
spring:
  application:
    name: eureka-server
eureka:
  client:
    # 此应用为注册中心,false:不向注册中心注册自己。
    register-with-eureka: false
    # 注册中心职责是维护服务实例
    fetch-registry: false
    service-url:
      defaultZone: http://localhost:${server.port}/eureka/
server:
  port: 18790

2, 测试是否能实现分布式事务管理

// TM + RM 微服务User 分布式事务发起者
@GlobalTransactional
public String addUser(String name) {
    User user = userMapper.findByName(name);
    if (user == null) {
        user = new User();
        user.setCreated(new Date());
        user.setName(name);
        userMapper.saveUser(user);
        // 分配的全局事务id, 可以传递给被分布式者
        String xid = RootContext.getXID();
        System.out.printf(xid);
        return activeFeignService.register(user.getName());
    }
    return "SUCCESS";
}

// RM 微服务Aactive 分布式事务参与者
@GlobalTransactional
public void registerGivePoint(String username) {
    PointAccount pointAccount = pointMapper.findByName(username);
    if (pointAccount == null) {
        pointAccount = new PointAccount();
        pointAccount.setCreated(new Date());
        pointAccount.setName(username);
        pointAccount.setPoint(1);
        pointMapper.createdAccount(pointAccount);
    }
}
2.1 测试正常情况

127.0.0.1:18791/user/register?name=test01

我们请求我们的代码, 在user 和 point_account 应该都有条记录

*测试结果:
在这里插入图片描述
在这里插入图片描述

2.2 非正常情况下, 我们在 active 中抛出异常
// RM 微服务Aactive 分布式事务参与者
@GlobalTransactional
public void registerGivePoint(String username) {
    // 除零异常
    int a = 12/0;
    PointAccount pointAccount = pointMapper.findByName(username);
    if (pointAccount == null) {
        pointAccount = new PointAccount();
        pointAccount.setCreated(new Date());
        pointAccount.setName(username);
        pointAccount.setPoint(1);
        pointMapper.createdAccount(pointAccount);
    }
}

*测试结果:

在这里插入图片描述

两个被回滚了, 我们的工程初步测试没有问题

3, 最后, 下一个博客, 我将会带大家关注 seata 理论知识

这里可以提一个有趣的问题, 如果在调用active之前, 也就是, 下面这行代码之前, 进行debug

activeFeignService.register(user.getName());

然后我们去看数据库中的user表, 您一定会发现一些有意思的东西

4, 附件

工程代码

链接:https://pan.baidu.com/s/1-vEXfax-uZRYcKB6aQxxsA
提取码:rz9r

工程数据库

链接:https://pan.baidu.com/s/1-5xcilJ2r2nTMUeA7Dx8cw
提取码:iaan

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值