9、seata使用
9.1、部署steata服务并启动
9.1.1、数据库准备
- 资源地址
- client
存放client端sql脚本 (包含 undo_log表) ,参数配置
- config-center
各个配置中心参数导入脚本,config.txt(包含server和client,原名nacos-config.txt)为通用参数文件
- server
server端数据库脚本 (包含 lock_table、branch_table 与 global_table) 及各个容器配置
9.1.2、下载seata服务
9.1.3、执行sql脚本seata/script/server/db/mysql.sql
-- -------------------------------- The script used when storeMode is 'db' --------------------------------
-- the table to store GlobalSession data
CREATE TABLE IF NOT EXISTS `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_status_gmt_modified` (`status` , `gmt_modified`),
KEY `idx_transaction_id` (`transaction_id`)
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4;
-- the table to store BranchSession data
CREATE TABLE IF NOT EXISTS `branch_table`
(
`branch_id` BIGINT NOT NULL,
`xid` VARCHAR(128) NOT NULL,
`transaction_id` BIGINT,
`resource_group_id` VARCHAR(32),
`resource_id` VARCHAR(256),
`branch_type` VARCHAR(8),
`status` TINYINT,
`client_id` VARCHAR(64),
`application_data` VARCHAR(2000),
`gmt_create` DATETIME(6),
`gmt_modified` DATETIME(6),
PRIMARY KEY (`branch_id`),
KEY `idx_xid` (`xid`)
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4;
-- the table to store lock data
CREATE TABLE IF NOT EXISTS `lock_table`
(
`row_key` VARCHAR(128) NOT NULL,
`xid` VARCHAR(128),
`transaction_id` BIGINT,
`branch_id` BIGINT NOT NULL,
`resource_id` VARCHAR(256),
`table_name` VARCHAR(32),
`pk` VARCHAR(36),
`status` TINYINT NOT NULL DEFAULT '0' COMMENT '0:locked ,1:rollbacking',
`gmt_create` DATETIME,
`gmt_modified` DATETIME,
PRIMARY KEY (`row_key`),
KEY `idx_status` (`status`),
KEY `idx_branch_id` (`branch_id`),
KEY `idx_xid_and_branch_id` (`xid` , `branch_id`)
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4;
CREATE TABLE IF NOT EXISTS `distributed_lock`
(
`lock_key` CHAR(20) NOT NULL,
`lock_value` VARCHAR(20) NOT NULL,
`expire` BIGINT,
primary key (`lock_key`)
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4;
INSERT INTO `distributed_lock` (lock_key, lock_value, expire) VALUES ('AsyncCommitting', ' ', 0);
INSERT INTO `distributed_lock` (lock_key, lock_value, expire) VALUES ('RetryCommitting', ' ', 0);
INSERT INTO `distributed_lock` (lock_key, lock_value, expire) VALUES ('RetryRollbacking', ' ', 0);
INSERT INTO `distributed_lock` (lock_key, lock_value, expire) VALUES ('TxTimeoutCheck', ' ', 0);
9.1.4、修改配置文件seata/conf/application.yml
server:
port: 7091
spring:
application:
name: seata-server
logging:
config: classpath:logback-spring.xml
file:
path: ${user.home}/logs/seata
# extend:
# logstash-appender:
# destination: 127.0.0.1:4560
# kafka-appender:
# bootstrap-servers: 127.0.0.1:9092
# topic: logback_to_logstash
console:
user:
username: seata
password: seata
seata:
config:
# support: nacos, consul, apollo, zk, etcd3
type: nacos
nacos:
server-addr: 172.16.156.139:8847
namespace: 170ee694-566d-4c3a-b316-fe233d984d43
group: SEATA_GROUP
username: nacos
password: nacos
##if use MSE Nacos with auth, mutex with username/password attribute
#access-key: ""
#secret-key: ""
# data-id: seataServer.properties
registry:
# support: nacos, eureka, redis, zk, consul, etcd3, sofa
type: nacos
# preferred-networks: 30.240.*
nacos:
application: seata-server
server-addr: 172.16.156.139:8847
group: SEATA_GROUP
namespace: 170ee694-566d-4c3a-b316-fe233d984d43
cluster: default
username: nacos
password: nacos
store:
# support: file 、 db 、 redis
mode: db
# server:
# service-port: 8091 #If not configured, the default is '${server.port} + 1000'
security:
secretKey: SeataSecretKey0c382ef121d778043159209298fd40bf3850a017
tokenValidityInMilliseconds: 1800000
ignore:
urls: /,/**/*.css,/**/*.js,/**/*.html,/**/*.map,/**/*.svg,/**/*.png,/**/*.ico,/console-fe/public/**,/api/v1/auth/login
9.1.5、修改seata/script/config-center/config.txt文件中数据库连接
# 改为db
store.mode=db
store.lock.mode=db
store.session.mode=db
# 改为对应的数据库连接地址
store.db.driverClassName=com.mysql.cj.jdbc.Driver
store.db.url=jdbc:mysql://114.67.111.175:3306/seata_server?useUnicode=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true&useSSL=false
store.db.user=root
store.db.password=123456
9.1.6、进入seata/script/config-center/nacos执行脚本上传配置到nacos
./nacos-config.sh -h 172.16.156.139 -p 8847 -g SEATA_GROUP -t 170ee694-566d-4c3a-b316-fe233d984d43 -u nacos -w nacos
- -h: 注册注册中心的ip
- -p:注册中心的端口
- -g: 注册到注册中心的Group
- -t: 注册到注册中心的命名空间
- -u: 注册中心的账号
- -w: 注册中心的密码
9.1.7、进入seata/bin启动seata服务
./seata-server.sh -h 127.0.0.1 -p 8091
- -h:seata服务地址
- -p:监听端口,从8091开始
9.2、客户端client
- 准备在需要开启分布式事务的各数据库新建undo_log表,主要通过 BeforeImage 和 AfterImage 保存前后逻辑 , 用于回退处理,使用at模式
-- for AT mode you must to init this sql for you business database. the seata server not need it.
CREATE TABLE IF NOT EXISTS `undo_log`
(
`branch_id` BIGINT NOT NULL COMMENT 'branch transaction id',
`xid` VARCHAR(128) NOT NULL COMMENT 'global transaction id',
`context` VARCHAR(128) NOT NULL COMMENT 'undo_log context,such as serialization',
`rollback_info` LONGBLOB NOT NULL COMMENT 'rollback info',
`log_status` INT(11) NOT NULL COMMENT '0:normal status,1:defense status',
`log_created` DATETIME(6) NOT NULL COMMENT 'create datetime',
`log_modified` DATETIME(6) NOT NULL COMMENT 'modify datetime',
UNIQUE KEY `ux_undo_log` (`xid`, `branch_id`)
) ENGINE = InnoDB
AUTO_INCREMENT = 1
DEFAULT CHARSET = utf8mb4 COMMENT ='AT transaction mode undo table';
9.2.1、导入依赖
9.2.1.1、服务提供方
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.2.2</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.2.11</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-seata</artifactId>
<exclusions>
<exclusion>
<groupId>io.seata</groupId>
<artifactId>seata-spring-boot-starter</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
9.2.1.2、服务调用方
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.2.2</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.2.11</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-loadbalancer</artifactId>
</dependency>
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-seata</artifactId>
<exclusions>
<exclusion>
<groupId>io.seata</groupId>
<artifactId>seata-spring-boot-starter</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
9.2.2、配置文件
9.2.2.1、服务提供方
server:
port: 6062
spring:
main:
allow-circular-references: true
application:
name: stock-db
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://114.67.111.175:3306/test?allowPublicKeyRetrieval=true&useSSL=false&serverTimezone=Asia/Shanghai
username: root
password: 123456
cloud:
nacos:
server-addr: 172.16.156.139:8847
username: nacos
password: nacos
alibaba:
seata:
# 事务分组,可自定义,对应属性 service.vgroupMapping.default_tx_group=default
tx-service-group: default_tx_group
---
mybatis:
type-aliases-package: com.wanqi.pojo
mapper-locations: classpath:mapper/*.xml
---
seata:
tx-service-group: default_tx_group
registry:
type: nacos # 配置seata的注册中心,告诉seata client如何访问seata server
nacos:
server-addr: 172.16.156.139:8847 # seata server注册的nacos中心
group: SEATA_GROUP # seata server注册的分组
application: seata-server # seata server注册的服务名
namespace: 170ee694-566d-4c3a-b316-fe233d984d43 # seata server注册的命名空间
cluster: default # seata server集群名称
username: nacos # nacos账号
password: nacos # nacos密码
config:
type: nacos
nacos:
server-addr: 172.16.156.139:8847 # seata配置注册的nacos中心
group: SEATA_GROUP # 配置注册的分组
namespace: 170ee694-566d-4c3a-b316-fe233d984d43 # 配置注册的命名空间
username: nacos # nacos账号
password: nacos # nacos密码
9.2.2.2、服务调用方,在需要开启事务的方法上使用@GlobalTransactional开启全局事务
server:
port: 6061
spring:
main:
allow-circular-references: true
application:
name: order-db
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://39.104.101.11:3306/test
username: wq
password: 123456
cloud:
nacos:
server-addr: 172.16.156.139:8847
password: nacos
username: nacos
alibaba:
seata:
# 事务分组,可自定义,对应属性 service.vgroupMapping.default_tx_group=default
tx-service-group: default_tx_group
---
mybatis:
type-aliases-package: com.wanqi.pojo
mapper-locations: classpath:mapper/*.xml
---
feign:
client:
config:
default:
loggerLevel: Full
connectTimeout: 6000
readTimeout: 6000
---
logging:
level:
com.wanqi.feign: debug
---
seata:
tx-service-group: default_tx_group
registry:
type: nacos
nacos:
server-addr: 172.16.156.139:8847 # seata服务注册的nacos中心
group: SEATA_GROUP # 注册的分组
application: seata-server # 注册的服务名
namespace: 170ee694-566d-4c3a-b316-fe233d984d43 # 注册的命名空间
cluster: default # 集群名称
username: nacos # nacos账号
password: nacos # nacos密码
config:
type: nacos
nacos:
server-addr: 172.16.156.139:8847 # seata配置注册的nacos中心
group: SEATA_GROUP # 配置注册的分组
namespace: 170ee694-566d-4c3a-b316-fe233d984d43 # 配置注册的命名空间
username: nacos # nacos账号
password: nacos # nacos密码
9.2.3、client接口与调用
9.2.3.1、服务提供方接口
@RestController
public class StockController {
@Autowired
StockMapper stockMapper;
@PostMapping("/add")
public int add(@RequestParam("orderId") Long id) {
System.out.println(id);
Stock select = stockMapper.select();
int x = stockMapper.update(id);
System.out.println(select);
return x;
}
@PostMapping(value = "/sqlFile")
public String genSqlFile(@RequestParam("sqlId")String sqlId,@RequestParam("sql")String sql){
MyTest test = new MyTest(sqlId,sql);
System.out.println(test);
return test.toString();
}
}
9.2.3.2、调用方接口
@FeignClient(name = "stock-db",contextId = "stock-db")
public interface StockFeignService {
@PostMapping("/add")
public int add(@RequestParam("orderId") Long orderId);
@PostMapping(value = "/sqlFile")
public String genSqlFile(@RequestParam("sqlId")String sqlId,@RequestParam("sql")String sql);
}
@RestController
public class OrderController {
@Autowired
OrderService orderService;
@Autowired
StockFeignService stockFeignService;
@GetMapping("add/{name}")
public String add(@PathVariable("name") String name){
System.out.println(name);
orderService.add(name);
return "ok";
}
@GetMapping("add2/{orderId}")
public int add2(@PathVariable("orderId") Long orderId) {
return stockFeignService.add(orderId);
}
@PostMapping(value = "/sqlFile")
public String genSqlFile(@RequestParam("sqlId")String sqlId,@RequestParam("sql")String sql){
MyTest test = new MyTest(sqlId,sql);
String msg = stockFeignService.genSqlFile(test.getSqlId(),test.getSql());
System.out.println(msg + "调用成功啦!!!");
return msg;
}
}
@Service
public class OrderService {
@Autowired
StockFeignService stockFeignService;
@Autowired
OrderMapper orderMapper;
//注解开启全局事务
@GlobalTransactional
public String add(String name) {
orderMapper.save(name);
stockFeignService.add(Long.valueOf("999"));
int a = 1/0;
return "ok";
}
}
10、SkyWalking链路追踪,安装包使用阿里云镜像地址
10.1、解压后修改为mysql模式,apache-skywalking-apm-bin/config/application.yml
- 设置为mysql,默认是h2
storage:
selector: ${SW_STORAGE:mysql}
- 新建数据库swtest,修改jdbcUrl地址为自己的数据库地址
mysql:
properties:
jdbcUrl: ${SW_JDBC_URL:"jdbc:mysql://114.67.111.165:3306/swtest?rewriteBatchedStatements=true"}
dataSource.user: ${SW_DATA_SOURCE_USER:root}
dataSource.password: ${SW_DATA_SOURCE_PASSWORD:123456}
10.2、修改web端口,apache-skywalking-apm-bin/webapp/webapp.yml
- 可选操作,默认端口8080使用频率较高避免重复
server:
port: 8868
10.3、启动服务,apache-skywalking-apm-bin/bin/startup.sh
10.4、访问UI界面
10.5、idea接入,配置启动参数然后启动即可
-DSW_AGENT_NAME=api-gateway
-DSW_AGENT_COLLECTOR_BACKEND_SERVICES=172.16.156.139:11800
-javaagent:/Users/wandaren/Downloads/Compressed/skywalking-agent/skywalking-agent.jar
10.6、logback日志集成
10.6.1、引入依赖
<dependency>
<groupId>org.apache.skywalking</groupId>
<artifactId>apm-toolkit-logback-1.x</artifactId>
<version>8.11.0</version>
</dependency>
10.6.2、修改agent配置增加以下内容
- 文件:skywalking-agent/config/agent.config
plugin.toolkit.log.grpc.reporter.server_host=${SW_GRPC_LOG_SERVER_HOST:172.16.156.139}
plugin.toolkit.log.grpc.reporter.server_port=${SW_GRPC_LOG_SERVER_PORT:11800}
plugin.toolkit.log.grpc.reporter.max_message_size=${SW_GRPC_LOG_MAX_MESSAGE_SIZE:10485760}
plugin.toolkit.log.grpc.reporter.upstream_timeout=${SW_GRPC_LOG_GRPC_UPSTREAM_TIMEOUT:30}
10.6.3、编写logback日志配置,文件名logback-spring.xml
- 如果不是使用的logback-spring.xml文件名,需要在配置文件中指application.yml定
logging:
# 如果不想配置必须使用文件名:logback-spring.xml
config: classpath:logback.xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="false">
<!--定义日志文件的存储地址 勿在 LogBack 的配置中使用相对路径-->
<property name="LOG_HOME" value="/data/log" />
<!-- 控制台输出 -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
</encoder>
</appender>
<!-- GRPCLogClientAppender处理器上传日志到skywalking -->
<appender name="gpr-log" class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.log.GRPCLogClientAppender">
<!-- 日志输出编码 -->
<encoder>
<!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n
</pattern>
</encoder>
</appender>
<!--mybatis log configure-->
<logger name="com.apache.ibatis" level="TRACE"/>
<logger name="java.sql.Connection" level="DEBUG"/>
<logger name="java.sql.Statement" level="DEBUG"/>
<logger name="java.sql.PreparedStatement" level="DEBUG"/>
<!-- 日志输出级别 -->
<root level="INFO">
<appender-ref ref="STDOUT" />
<appender-ref ref="gpr-log"/>
</root>
</configuration>
10.7、自定义链路追踪
10.7.1、引入依赖
<dependency>
<groupId>org.apache.skywalking</groupId>
<artifactId>apm-toolkit-trace</artifactId>
<version>8.11.0</version>
</dependency>
10.7.2、使用注解指定方法,示例
@Trace
@Tag(key = "select",value = "returnedObj")
public String select(){
return stockFeignService.select();
}
@PostMapping(value = "/myTest")
@Trace
@Tags({@Tag(key = "sqlId",value = "arg[0]"),
@Tag(key = "sql",value = "arg[1]"),
@Tag(key = "sqlId",value = "returnedObj.sqlId"),
@Tag(key = "sql",value = "returnedObj.sql")})
public MyTest myTest(@RequestParam("sqlId")String sqlId,@RequestParam("sql")String sql){
return new MyTest(sqlId + "111",sql + "222");
}
10.8、告警参考官网
springcloudalibaba入门(一)
springcloudalibaba入门(二)
springcloudalibaba入门(三)