SpringCloud+eureka+seata1.4.2分布式
2021-06-16 本文已影响0人
小胖学编程
- 版本信息
- 环境准备
2.1 seata-server准备
-2.1.1 seata-server的下载
-2.1.2 seata-server的配置文件
-2.1.3 seata-server启动命令
-2.1.4 seata-server数据表创建
2.2 eureka配置文件
2.3 业务库的undo_log表 - 业务代码编写
3.1 引入依赖
3.2 项目配置
3.3 启动类配置
3.4 分布式事务注解 - 推荐阅读
1. 版本信息
SpringBoot版本:2.2.6.RELEASE
SpringCloud版本:Hoxton.RELEASE
seata-server版本:1.4.2
seata-client版本:1.3.0
2. 环境准备
2.1 seata-server准备
2.1.1 seata-server的下载
image.png文件解压:
tar -zxvf 压缩文件名.tar.gz
2.1.2 seata-server的配置文件
进入conf
目录:
修改file.conf
文件,将存储介质由file修改为db:
## transaction log store, only used in seata-server
store {
## store mode: file、db、redis
mode = "db"
## rsa decryption public key
publicKey = ""
## file store property
file {
## store location dir
dir = "sessionStore"
# branch session size , if exceeded first try compress lockkey, still exceeded throws exceptions
maxBranchSessionSize = 16384
# globe session size , if exceeded throws exceptions
maxGlobalSessionSize = 512
# file buffer size , if exceeded allocate new buffer
fileWriteBufferCacheSize = 16384
# when recover batch read size
sessionReloadReadSize = 100
# async, sync
flushDiskMode = async
}
## database store property
db {
## the implement of javax.sql.DataSource, such as DruidDataSource(druid)/BasicDataSource(dbcp)/HikariDataSource(hikari) etc.
datasource = "druid"
## mysql/oracle/postgresql/h2/oceanbase etc.
dbType = "mysql"
driverClassName = "com.mysql.jdbc.Driver"
## if using mysql to store the data, recommend add rewriteBatchedStatements=true in jdbc connection param
url = "jdbc:mysql://127.0.0.1:3306/seata?rewriteBatchedStatements=true"
user = "root"
password = "123qwe"
minConn = 5
maxConn = 100
globalTable = "global_table"
branchTable = "branch_table"
lockTable = "lock_table"
queryLimit = 100
maxWait = 5000
}
## redis store property
redis {
## redis mode: single、sentinel
mode = "single"
## single mode property
single {
host = "127.0.0.1"
port = "6379"
}
## sentinel mode property
sentinel {
masterName = ""
## such as "10.28.235.65:26379,10.28.235.65:26380,10.28.235.65:26381"
sentinelHosts = ""
}
password = ""
database = "0"
minConn = 1
maxConn = 10
maxTotal = 100
queryLimit = 100
}
}
修改registry.conf
文件,注册中心修改为eureka:
registry {
# file 、nacos 、eureka、redis、zk、consul、etcd3、sofa
type = "eureka"
nacos {
application = "seata-server"
serverAddr = "127.0.0.1:8848"
group = "SEATA_GROUP"
namespace = ""
cluster = "default"
username = ""
password = ""
}
eureka {
serviceUrl = "http://localhost:7001/eureka"
application = "seata-server"
weight = "1"
}
redis {
serverAddr = "localhost:6379"
db = 0
password = ""
cluster = "default"
timeout = 0
}
zk {
cluster = "default"
serverAddr = "127.0.0.1:2181"
sessionTimeout = 6000
connectTimeout = 2000
username = ""
password = ""
}
consul {
cluster = "default"
serverAddr = "127.0.0.1:8500"
aclToken = ""
}
etcd3 {
cluster = "default"
serverAddr = "http://localhost:2379"
}
sofa {
serverAddr = "127.0.0.1:9603"
application = "default"
region = "DEFAULT_ZONE"
datacenter = "DefaultDataCenter"
cluster = "default"
group = "SEATA_GROUP"
addressWaitTime = "3000"
}
file {
name = "file.conf"
}
}
config {
# file、nacos 、apollo、zk、consul、etcd3
type = "file"
nacos {
serverAddr = "127.0.0.1:8848"
namespace = ""
group = "SEATA_GROUP"
username = ""
password = ""
dataId = "seataServer.properties"
}
consul {
serverAddr = "127.0.0.1:8500"
aclToken = ""
}
apollo {
appId = "seata-server"
## apolloConfigService will cover apolloMeta
apolloMeta = "http://192.168.1.204:8801"
apolloConfigService = "http://192.168.1.204:8080"
namespace = "application"
apolloAccesskeySecret = ""
cluster = "seata"
}
zk {
serverAddr = "127.0.0.1:2181"
sessionTimeout = 6000
connectTimeout = 2000
username = ""
password = ""
nodePath = "/seata/seata.properties"
}
etcd3 {
serverAddr = "http://localhost:2379"
}
file {
name = "file.conf"
}
}
2.1.3 seata-server启动命令
在Linux/Mac下
$ sh ./bin/seata-server.sh
在在 Windows 下
bin\seata-server.bat
启动eureka后,seata-server便会注册到eureka上:
image.png2.1.4 seata-server数据表创建
因为seata-server在file.conf指定了db,所以需要在127.0.0.1:3306
的seata
库创建如下的表。
-- the table to store GlobalSession data
drop table if exists `global_table`;
create table `global_table` (
`xid` varchar(128) not null,
`transaction_id` bigint,
`status` tinyint not null,
`application_id` varchar(32),
`transaction_service_group` varchar(32),
`transaction_name` varchar(128),
`timeout` int,
`begin_time` bigint,
`application_data` varchar(2000),
`gmt_create` datetime,
`gmt_modified` datetime,
primary key (`xid`),
key `idx_gmt_modified_status` (`gmt_modified`, `status`),
key `idx_transaction_id` (`transaction_id`)
);
-- the table to store BranchSession data
drop table if exists `branch_table`;
create table `branch_table` (
`branch_id` bigint not null,
`xid` varchar(128) not null,
`transaction_id` bigint ,
`resource_group_id` varchar(32),
`resource_id` varchar(256) ,
`lock_key` varchar(128) ,
`branch_type` varchar(8) ,
`status` tinyint,
`client_id` varchar(64),
`application_data` varchar(2000),
`gmt_create` datetime,
`gmt_modified` datetime,
primary key (`branch_id`),
key `idx_xid` (`xid`)
);
-- the table to store lock data
drop table if exists `lock_table`;
create table `lock_table` (
`row_key` varchar(128) not null,
`xid` varchar(96),
`transaction_id` long ,
`branch_id` long,
`resource_id` varchar(256) ,
`table_name` varchar(32) ,
`pk` varchar(36) ,
`gmt_create` datetime ,
`gmt_modified` datetime,
primary key(`row_key`)
);
2.2 eureka配置文件
server:
port: 7001
spring:
application:
name: eureka-server
info:
app:
name: "@project.name@"
description: "@project.description@"
version: "@project.version@"
spring-boot-version: "@project.parent.version@"
eureka:
instance:
prefer-ip-address: true
hostname: ${spring.cloud.client.ip-address}
client:
fetch-registry: false
register-with-eureka: false
service-url:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
server:
# 自我保护
enable-self-preservation: false
# 主动检查服务时间
eviction-interval-timer-in-ms: 5000
# 服务过期时间,超过这个时间剔除服务
lease-expiration-duration-in-seconds: 15
# 服务刷新时间 主动心跳
lease-renewal-interval-in-seconds: 5
# 禁用readOnlyCacheMap
useReadOnlyResponseCache: false
2.3 业务库的undo_log表
每一个业务都需要创建undo_log
表。
CREATE TABLE `undo_log` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`branch_id` bigint(20) NOT NULL,
`xid` varchar(100) NOT NULL,
`context` varchar(128) NOT NULL,
`rollback_info` longblob NOT NULL,
`log_status` int(11) NOT NULL,
`log_created` datetime NOT NULL,
`log_modified` datetime NOT NULL,
`ext` varchar(100) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `ux_undo_log` (`xid`,`branch_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
3. 业务代码编写
3.1 引入依赖
数据库+seata的依赖配置:
<!-- Seata -->
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-spring-boot-starter</artifactId>
<exclusions>
<exclusion>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
</exclusion>
</exclusions>
<version>1.3.0</version>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-seata</artifactId>
<exclusions>
<exclusion>
<groupId>io.seata</groupId>
<artifactId>seata-spring-boot-starter</artifactId>
</exclusion>
</exclusions>
<version>2.2.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.1.1</version>
</dependency>
<!--druid数据库连接池-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.9</version>
</dependency>
3.2 项目配置
eureka:
client:
serviceUrl:
defaultZone: http://localhost:7001/eureka/
registry-fetch-interval-seconds: 5
instance:
lease-expiration-duration-in-seconds: 15
lease-renewal-interval-in-seconds: 5
prefer-ip-address: true
#nacos配置中心 相关配置
spring:
application:
name: product001
datasource:
name: mysql_test
type: com.alibaba.druid.pool.DruidDataSource
#druid相关配置
druid:
#基本属性
url: jdbc:mysql://localhost:3306/exam
username: root
password: 123qwe
#初始化连接数
initial-size: 1
#最小活跃连接数
min-size: 1
#最大活跃连接数
max-active: 1
#获取连接的等待时间
max-wait: 60000
#间隔多久进行一次检查,检查需要关闭的空闲连接
time-between-eviction-runs-millis: 60000
#一个连接在池中最小的生存时间(5分钟)
min-evictable-idle-time-millis: 300000
# validation-query: SELECT 'X'
# 验证空闲的连接,若无法验证,则删除连接
test-while-idle: true
# 不检测池中连接的可用性(默认false)
# 导致的问题是,若项目作为服务端,数据库连接被关闭时,客户端调用就会出现大量的timeout
test-on-borrow: false
#在返回连接池之前是否验证对象
test-on-return: false
########################
server:
port: 8011
### Feign 配置
feign:
# hystrix:
# enabled: true #在Feign中开启Hystrix
client:
defaultToProperties: false
defaultConfig: myconf
config:
myconf:
connectTimeout: 2000
readTimeout: 5000
okhttp:
enabled: true
httpclient:
# 开启 Http Client
enabled: false
mybatis:
mapper-locations: classpath*:/mapping/*.xml
type-aliases-package: com.tellme.po
#读取全局配置的地址
config-location: classpath:mybatis-config.xml
# seata的配置
seata:
enabled: true
application-id: seata-server
tx-service-group: default # 此时不能变化,否则会出现io.seata.common.exception.FrameworkException: No available service
enable-auto-data-source-proxy: true
use-jdk-proxy: false
service:
vgroup-mapping:
default: seata-server
enable-degrade: false
disable-global-transaction: false
registry:
type: eureka
eureka:
weight: 1
service-url: http://localhost:7001/eureka/
3.3 启动类配置
@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
@EnableEurekaClient
@EnableFeignClients
@EnableAutoDataSourceProxy
public class Product001_App {
public static void main(String[] args) {
SpringApplication.run(Product001_App.class, args);
}
}
3.4 分布式事务注解
在方法上加上@GlobalTransactional
注解。
测试分布式事务,出现如下描述表示成功:
image.png4. 推荐阅读
https://blog.csdn.net/weixin_42155491/article/details/106930617