springcloud+eureka+seata(AT模式)解决分布式事务

1. 我这里是Centos7,第一步先安装java环境; 2. 下载steata包,下载地址:[seata1.4.2]("https://github.com/seata/seata/releases/download/v1.4.2/seata-server-1.4.2.tar.gz") 3. 上传到linux的/software/目录后解压 ``` cd /software/ tar -zxvf seata-server-1.4.2.tar.gz cd /seata/seata-server-1.4.2 ``` 4.修改registry.conf文件 ``` registry { # file 、nacos 、eureka、redis、zk、consul、etcd3、sofa # 指定注册中心为eureka,以下只需要配置eureka相关配置参数即可 type = "eureka" nacos { application = "seata-server" serverAddr = "127.0.0.1:8848" group = "SEATA_GROUP" namespace = "" cluster = "default" username = "" password = "" } eureka { #修改了宿主机的hosts,将注册中心的ip统一为指定域名,方便维护 serviceUrl = "http://127.0.0.1:8761/eureka" #自定义注册中心服务名 application = "SEATA" 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" } } ``` 5.修改file.conf ``` ## transaction log store, only used in seata-server store { ## store mode: file、db、redis # 指定存储模式为db,集群必须配置为db mode = "db" ## 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.cj.jdbc.Driver" ## if using mysql to store the data, recommend add rewriteBatchedStatements=true in jdbc connection param url = "jdbc:mysql://xxx:3306/test_seata" user = "xxx" password = "xxx" 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 } } ``` 6. 启动 ``` #在test_seata数据库建以下几张表,建表语句: 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`) )ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; 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`) )ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; 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`) )ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; #后台运行 nohup ./bin/seata-server.sh -p 8091 -h 127.0.0.1 -m db &> ./logs/seata.log & #查看日志,看到-Server started即成功,再打开eureka是否有注册上去 tail -f ./logs/seata.log ``` - -p 指定启动seata server的端口号; - -h 指定seata server所绑定的主机; - -m 事务日志、事务执行信息存储的方式,目前支持file(文件方式)、db(数据库方式,建表语句请查看步骤6) 7. 在项目中使用,添加依赖(seata-spring-boot-starter方式,可直接在application.yml/application.properties中进行配置,但是需要手动传递XID;而使用spring-cloud-alibaba-seata,需要在每个微服务中添加registry.conf和file.conf文件,这里结合): ``` com.alibaba.cloud spring-cloud-alibaba-seata 2.2.0.RELEASE io.seata seata-spring-boot-starter 1.3.0 ``` 8. application.yml中添加: ``` #seata 配置, 代替file.conf和registry.conf配置 seata: enabled: true # 你的服务名称 application-id: ${spring.application.name} #自定义group tx-service-group: test-seata # 开启数据源自动代理 enable-auto-data-source-proxy: true service: vgroup-mapping: #这里对应端的file.conf中vgroup_mapping.seata_server_group = "seata-server" test-seata: SEATA enable-degrade: false disable-global-transaction: false # Eureka配置 registry: type: eureka eureka: service-url: http://127.0.0.1:8761/eureka ``` 9.seata1.1.0以后,不需要手动代理数据源,启动类上@SpringBootApplication(exclude = DataSourceAutoConfiguration.class): ![自定义数据源](https://upload-images.jianshu.io/upload_images/12763155-5c513c1745439426.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 10. 在你需要使用feign进行微服务间调到的方法上添加注解@GlobalTransactional ![注解](https://upload-images.jianshu.io/upload_images/12763155-3c7a4119cdab1def.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 11. 每个涉及到分布式事务的微服务的数据库都要有一张undo_log日志表,sql如下: ``` DROP TABLE IF EXISTS `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=utf8mb4 COLLATE=utf8mb4_general_ci; ``` 12. 在需要微服务调用的微服务中进行以上相同配置(7.8.9.10.12),除了@GlobalTransactional注解,之后便可以抛出异常看是否回滚成功 - 注:seata集群只需要再以其他端口启动seata文件目录即可 ![seata集群](https://upload-images.jianshu.io/upload_images/12763155-936f2c85f36115fa.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 13. docker-compose编排部署: ``` version: "3" services: seata-server: image: seataio/seata-server:1.4.2 container_name: seata-server hostname: seata-server networks: - seata-server ports: - "8091:8091" environment: #宿主机ip - SEATA_PORT=8091 # 指定seata-server的事务日志存储方式, 支持db ,file(默认),redis - STORE_MODE=db #seata的被发现地址,该IP用于向注册中心注册时使用(也就是自身的ip) - SEATA_IP=127.0.0.1 #给予权限 #- privileged=true volumes: - /software/docker/seata/config/registry.conf:/seata-server/resources/registry.conf - /software/docker/seata/config/file.conf:/seata-server/resources/file.conf - /software/docker/seata/mysql-connector-java-8.0.16.jar:/seata-server/libs/mysql-connector-java-8.0.16.jar - /project/docker/seata/logs:/root/logs/seata - /etc/localtime:/etc/localtime networks: seata-server: driver: bridge ```

你可能感兴趣的:(springcloud+eureka+seata(AT模式)解决分布式事务)