前言, 上一篇博主使用的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