Docker安装Seata(并在Nacos上注册)以及Seata分布式全局事务在Spring Cloud上的实践

2 篇文章 0 订阅
1 篇文章 0 订阅

内容快捷导航

一、Docker安装Seata
    1、docker拉取seata镜像(注意Seata版本,具体参照自己的Spring Cloud)
    2、启动容器
    3、拷贝seata启动后的镜像文件文件至这里我放在mydata中
    4、移除旧的容器
    5、重新启动新容器
二、Seata配置修改(以Nacos作为注册中心,File作为配置文件)
    1、进入resources目录
    2、修改registry.conf文件
    3、file.conf文件不用改,用默认的
    4、重启seata-server容器
    5、启动nacos查看效果
三、Seata分布式全局事务在Spring Cloud上的实践
    1、导入依赖(这边我的seata版本用的是父项目版本控制中心的,直接解决版本依赖问题巴适)
    2、修改applicaton配置文件
    3、解决冲突
    4、最后亲测可行

一、Docker安装Seata

1、docker拉取seata镜像(注意Seata版本,具体参照自己的Spring Cloud)

具体Docker官网查看:Docke Hub官网

docker pull seataio/seata-server:1.4.2
2、启动容器
docker run -d --name seata-server -p 8091:8091 seataio/seata-server:1.4.2
3、拷贝seata启动后的镜像文件文件至这里我放在mydata中
  • 创建目录/mydata/seata
mkdir /mydata/seata

在这里插入图片描述

  • 拷贝seata启动后的镜像文件至/mydata/seata
docker cp seata-server:/seata-server /mydata/seata

效果图:
在这里插入图片描述

  • 将seata-server移动出来(主要我看它嵌套在里面不舒服)

在这里插入图片描述

mv seata-server/* .
rm -rf seata-server

效果图:
在这里插入图片描述

4、移除旧的容器
docker rm -f seata-server
5、重新启动新容器
docker run -d \
--restart always \
--privileged=true \
--name seata-server \
-p 8091:8091 \
-v /mydata/seata:/seata-server \
-e SEATA_IP=[访问linux的ip地址] \
-e SEATA_PORT=8091 \
seataio/seata-server:1.4.2

我的访问ip是192.168.56.10,所以就如下

docker run -d \
--restart always \
--privileged=true \
--name seata-server \
-p 8091:8091 \
-v /mydata/seata:/seata-server \
-e SEATA_IP=192.168.56.10 \
-e SEATA_PORT=8091 \
seataio/seata-server:1.4.2

二、Seata配置修改(以Nacos作为注册中心,File作为配置文件)

1、进入resources目录

在这里插入图片描述

cd /mydata/seata/resources
2、修改registry.conf文件

在这里插入图片描述

vi registry.conf

选择nacos作为注册中心,并填写nacos的账号和密码
在这里插入图片描述
默认type="file"不要修改,对应的配置文件就是file{name=“file.conf”}中的file.conf
在这里插入图片描述

3、file.conf文件不用改,用默认的

在这里插入图片描述

4、重启seata-server容器

在这里插入图片描述

5、启动nacos查看效果

在这里插入图片描述

三、Seata分布式全局事务在Spring Cloud上的实践

1、导入依赖(这边我的seata版本用的是父项目版本控制中心的,直接解决版本依赖问题巴适)

在这里插入图片描述
父项目版本中心的依赖(对应docker中下载的是seata:1.4.2)

	 <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-seata</artifactId>
        <version>2.2.6.RELEASE</version>
      </dependency>
2、修改applicaton配置文件

由于我用的是Mybatis-Plus以及DruidDataSource,所以要取消对应的自动代理数据源,否则会与Mybatis-Plus的增强组件冲突导致报错,具体报错名称可看:Seata与Mybatis-plus冲突导致其组件全失效

spring:
  cloud:
    alibaba:
      seata:
        tx-service-group: mall-group

# 不然使用druid数据源会冲突从而报错
# enable-auto-data-source-proxy就是表示不使用自动代理数据源,否则会与 多数据源、Mybatis-Plus冲突
seata:
  enabled: true
  enable-auto-data-source-proxy: false
  service:
    grouplist:
      default: 192.168.56.10:8091  # seata-server服务器地址,默认是 8091
    enable-degrade: false # 降级,当前不支持
    disable-global-transaction: false  # 启用全局事务
    vgroup-mapping:
      mall-group: default # 事务分组,默认:${spring.applicaiton.name}-seata-service-group,可以随便写

在这里插入图片描述

3、解决冲突

具体冲突原因和 Seata DataSourceProxy 的使用,请看这里:一文讲清楚 seata DataSourceProxy 的使用
具体的配置文件如下:(特别注意在分布式服务中所有用到Seata以及相关Mybatis-Plus增强功能的都需要引入下面的配置文件,不然全局事务回滚会失效哦)

@Configuration
@ConditionalOnClass(DruidDataSource.class)
//@AutoConfigureAfter(DataSourceAutoConfiguration.class)
public class MyDataSourceConfig {

    /**
     * 新的分页插件,一缓和二缓遵循mybatis的规则,需要设置 MybatisConfiguration#useDeprecatedExecutor = false 避免缓存出现问题(该属性会在旧插件移除后一同移除)
     */
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor(DbType.MYSQL);
        // 请求页面大于最大页面,true返回到首页,false继续请求,默认false
        paginationInnerInterceptor.setOverflow(true);
        // 设置最大单页限制数量,默认500
        paginationInnerInterceptor.setMaxLimit(500l);
        interceptor.addInnerInterceptor(paginationInnerInterceptor);
        return interceptor;
    }

	// 通过自动注入DataSourceProperties,获取properties/yml配置文件有关DataSource的配置信息
    @Resource
    private DataSourceProperties dataSourceProperties;
    
    @Bean
    public DataSourceProxy dataSourceProxy() {
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setUrl(dataSourceProperties.getUrl());
        dataSource.setUsername(dataSourceProperties.getUsername());
        dataSource.setPassword(dataSourceProperties.getPassword());
        dataSource.setDriverClassName(dataSourceProperties.getDriverClassName());
//        dataSource.setInitialSize(1);
//        dataSource.setMaxActive(120);
//        dataSource.setMaxWait(60000);
//        dataSource.setMinIdle(1);
//        dataSource.setValidationQuery("Select 1 from DUAL");
//        dataSource.setTestOnBorrow(false);
//        dataSource.setTestOnReturn(false);
//        dataSource.setTestWhileIdle(true);
//        dataSource.setTimeBetweenEvictionRunsMillis(60000);
//        dataSource.setMinEvictableIdleTimeMillis(25200000);
//        dataSource.setRemoveAbandoned(true);
//        dataSource.setRemoveAbandonedTimeout(1800);
//        dataSource.setLogAbandoned(true);
        return new DataSourceProxy(dataSource);
    }

	// 通过自动注入MybatisPlusProperties,获取properties/yml配置文件有关Mybatis-Plus的配置信息
    @Resource
    private MybatisPlusProperties properties;
    
    @Bean(name = "sqlSessionFactory")
    public SqlSessionFactory sqlSessionFactoryBean(DataSourceProxy dataSourceProxy) throws Exception {
//         DataSource dataSourceProxy = new DataSourceProxy(druidDataSource);
        MybatisSqlSessionFactoryBean bean = new MybatisSqlSessionFactoryBean();
        bean.setDataSource(dataSourceProxy);
        bean.setTypeAliasesPackage(properties.getTypeAliasesPackage());
        ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        // bean.setConfigLocation(resolver.getResource("classpath:mybatis-config.xml"));
        bean.setMapperLocations(resolver.getResources("classpath*:/mapper/**/*.xml"));
        bean.setGlobalConfig(properties.getGlobalConfig());
        SqlSessionFactory factory = null;
        try {
            factory = bean.getObject();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return factory;
    }
    
}
4、最后亲测可行

我的项目:首先在方法上加 @GlobalTransactional,订单服务(order)利用openFeign调用库存服务(ware),此时库存服务已经写入数据,库存++,由于订单服务中报错,然后全局事务回滚(订单数据和库存数据都回滚了)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值