Seata使用

本文以seata-server-1.5.2,以配置中心、注册中心使用Nacos,store.mode=db(mysql)为例进行操作。

一、Seata Server端

1、下载seata server

链接: http://seata.io/zh-cn/blog/download.html下载压缩包,解压至非中文目录。

下载版本参考之前我们提到的:SpringBoot、SpringCloud、Spring Cloud Alibaba版本对照表选择适合自己环境的版本。

本文版本环境:

复制代码
Spring Cloud Alibaba 2021.0.4.0
Spring Boot 2.6.11
Nacos 2.2.1
Seata1.5.2

解压后可以发现原来的conf/registry.conf配置文件没有了,可直接修改application.yml进行配置。

2、客户端配置-application.yml

配置application.yml(低版本的是file.conf+registry.conf文件),主要配置config:配置中心部分及registry:注册中心部分。

复制代码
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控制台,
# 可通过访问http://localhost:7091进行登录,账号如下seata/seata
console:
  user:
    username: seata
    password: seata

seata:
  # Seata接入Nacos配置中心
  config:
    # support: file, nacos, consul, apollo, zk, etcd3
    type: nacos
    nacos:
      server-addr: 127.0.0.1:8848
      namespace: 891d7906-dd03-4b8c-9fe9-a1f0609b3189
      group: SEATA_GROUP
      username: nacos
      password: nacos
      ##if use MSE Nacos with auth, mutex with username/password attribute
      #access-key: ""
      #secret-key: ""
  # Seata接入Nacos服务注册中心
  registry:
    # support: file, nacos, eureka, redis, zk, consul, etcd3, sofa
    type: nacos
    nacos:
      application: seata-server
      server-addr: 127.0.0.1:8848
      group: SEATA_GROUP
      namespace: 891d7906-dd03-4b8c-9fe9-a1f0609b3189
      cluster: default
      username: nacos
      password: nacos
      ##if use MSE Nacos with auth, mutex with username/password attribute
      #access-key: ""
      #secret-key: ""
  # 此处可不必配置,由于接入了nacos配置,以下store相关配置可直接通过seataServer.properties进行配置
  # 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

Tip:seata 版本客户端和服务端最好还保持一样

3、初始Mysql数据库

新建seata库->执行mysql.sql初始化脚本->【Seata 1.5版本mysql脚本】压缩包目录seata/script/db/mysql.sql

4、导入初始配置到nacos

1)先任意模式启动nacos,本文使用单机模式运行nacos。

win系统双击启动文件即可

Mac系统执行如下命令

复制代码
moon@moondeiMac  ~  %  cd /Users/moon/Downloads/nacos-2.2.1/distribution/target/nacos-server-2.2.1/nacos/bin
moon@moondeiMac bin % sh startup.sh -m standalone

2)新建一个namespace用于本地开发使用eg:dev

3)修改压缩包目录seata/script/config-center/config.txt文件中几处内容:

复制代码
# 存储模式
store.mode=db
 
store.db.datasource=druid
store.db.dbType=mysql
# 需要根据mysql的版本调整driverClassName
# mysql8及以上版本对应的driver:com.mysql.cj.jdbc.Driver
# mysql8以下版本的driver:com.mysql.jdbc.Driver
store.db.driverClassName=com.mysql.jdbc.Driver
# 注意根据生产实际情况调整参数host和port
store.db.url=jdbc:mysql://127.0.0.1:3306/seata?useUnicode=true&rewriteBatchedStatements=true
# 数据库用户名密码
store.db.user=root
store.db.password=12345678
# 微服务里配置与这里一致
service.vgroupMapping.dev_tx_group=default

特别说明下:

配置事务分组service.vgroupMapping.dev_tx_group=default

dev_tx_group:需要与客户端保持一致 ,可以自定义

default:需要跟客户端和application.yml中的cluster保持一致

default 必须要等于 registry.conf cluster = "default"

4)官方推荐通过压缩包目录seatascript/config-center/nacos/nacos-config.sh将修改后的config.txt发布到nacos上

复制代码
# 运行指令 ,通过 Git Bash Here
sh nacos-config.sh -h localhost -p 8848 -g SEATA_GROUP -t 891d7906-dd03-4b8c-9fe9-a1f0609b3189

# 具体说明参见:http://seata.io/zh-cn/docs/user/configurations.html
# -h: nacos host,默认localhost
# -p: nacos端口,默认8848
# -g: nacos分组,默认'SEATA_GROUP'.
# -t: 租户信息Tenant information,对应nacos namespace ID,默认''
# -u: nacos用户名,默认''
# -w: nacos用户密码,默认''

5)导入结果:

复制代码
namespace: dev
group: SEATA_GROUP
配置项变成了N个,每项都可单独修改。

5、启动测试

进入seata/bin 目录下,执行命令:

复制代码
sh seata-server.sh 

可以看到seata-server成功注入nacos,至此Seata Server端处理完毕。

二、Seata Client端搭建

1、为示例业务创建表

以用户购买商品的业务逻辑为例搭建微服务系统:

仓储服务(Stock):对给定的商品扣除仓储数量。

订单服务(Order):根据采购需求创建订单。

账户服务(Account):从用户账户中扣除余额。

三个独立的应用,分别使用三个独立的数据源。

为示例业务创建库、表,及每个库增加undo_log表,执行脚本

注意:每个业务数据库都要有UNDO_LOG

2、业务代码集成 Seata

源码:项目源码

1)父pom引入依赖:

复制代码
 <dependency>
          <groupId>org.springframework.cloud</groupId>
          <artifactId>spring-cloud-dependencies</artifactId>
          <version>2021.0.4</version>
          <type>pom</type>
          <scope>import</scope>
        </dependency>
        <dependency>
          <groupId>com.alibaba.cloud</groupId>
          <artifactId>spring-cloud-alibaba-dependencies</artifactId>
          <version>2021.0.4.0</version>
          <type>pom</type>
          <scope>import</scope>
        </dependency>
        <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-dependencies</artifactId>
          <version>2.6.11</version>
          <type>pom</type>
          <scope>import</scope>
        </dependency>

2)子pom引入依赖:

复制代码
 <!-- seata -->
<dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-seata</artifactId>
</dependency>
  <!--seata starter -->
<dependency>
			<groupId>io.seata</groupId>
			<artifactId>seata-spring-boot-starter</artifactId>
</dependency>

 <!--nacos discovery -->
 <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
  </dependency>
   <!--nacos config -->
<dependency>
       <groupId>com.alibaba.cloud</groupId>
       <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
 </dependency>
     <!--openfeign -->
<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
            <version>3.1.3</version>
 </dependency>

3)yml文件,其他两个类似:

复制代码
server:
  port: 2001

spring:
  application:
    name: seata-order-service
  cloud:
    nacos:
      discovery:
        # 服务分组
        group: SEATA_GROUP
        server-addr: http://localhost:8848
        # 必须填命名空间的ID
        namespace: 891d7906-dd03-4b8c-9fe9-a1f0609b3189
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource  #当前数据源操作类型
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3306/seata_order?allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8&useSSL=false #useSSL安全加固
    username: root
    password: 12345678


# MyBatis Plus配置
mybatis-plus:
  # 配置mapper的扫描,找到所有的mapper.xml映射文件
  mapper-locations: classpath*:mapper/**/*.xml
  #实体扫描,多个package用逗号或者分号分隔
  typeAliasesPackage: com.qytest.springcloud.entitites
  global-config:
    db-config:
      id-type: auto
  configuration:
    # 开启驼峰,开启后,只要数据库字段和对象属性名字母相同,无论中间加多少下划线都可以识别
    map-underscore-to-camel-case: true

# Seata 配置
seata:
  application-id: seata-server
  # 是否启用数据源bean的自动代理
  enable-auto-data-source-proxy: false
  tx-service-group: dev_tx_group  # 必须和服务器配置一样
  registry:
    type: nacos
    nacos:
      # Nacos 服务地址
      server-addr: http://localhost:8848
      group: SEATA_GROUP
      namespace: 891d7906-dd03-4b8c-9fe9-a1f0609b3189
      application: seata-server # 必须和服务器配置一样
      username: nacos
      password: nacos
      cluster: default
  config:
    type: nacos
    nacos:
      server-addr: ${spring.cloud.nacos.discovery.server-addr}
      group: SEATA_GROUP
      namespace: 891d7906-dd03-4b8c-9fe9-a1f0609b3189
  service:
    vgroup-mapping:
      tx-service-group: dev_tx_group # 必须和服务器配置一样
    disable-global-transaction: false
  client:
    rm:
      # 是否上报成功状态
      report-success-enable: true
      # 重试次数
      report-retry-count: 5

4)编写业务测试类

order通过feign接口调用库存及账户系统接口

复制代码
@RestController
@RequestMapping("")
@Slf4j
public class OrderController {
    @Resource
    private OrderService orderService;
    @GetMapping("/order/create")
    public CommonResult<Order> create(Order order) {
        orderService.create(order);
        return new CommonResult<Order>(200, "订单创建成功", order);
    }

}

public interface OrderService extends IService<Order> {
    void create(Order order);
}

@Service
@Slf4j
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService {

        @Resource
        private StorageService storageService;
        @Resource
        private AccountService accountService;

        /**
         * 创建订单->调用库存服务扣减库存->调用账户服务扣减账户余额->修改订单状态
         * 简单说:下订单->扣库存->减余额->改状态
         */
        @Override
        public void create(Order order) {
            //1 新建订单
            log.info("----->开始新建订单");
            baseMapper.create(order);
            log.info("----->新建订单完成");

            //2 扣减库存
            log.info("----->订单微服务开始调用库存,做扣减Count");
            storageService.decrease(order.getProductId(), order.getCount());
            log.info("----->库存扣减Count完成");

            //3 扣减账户
            log.info("----->订单微服务开始调用账户,做扣减Money");
            accountService.decrease(order.getUserId(), order.getMoney());
            log.info("----->账户扣减Money完成");

            //4 修改订单状态,从0到1,1代表已经完成
            log.info("----->修改订单状态开始");
            baseMapper.update(order.getUserId(),0);
            log.info("----->修改订单状态结束");

            log.info("----->下订单结束了,O(∩_∩)O哈哈~");

        }
}

5)启动测试

复制代码
# 先单机模式启动nacos
moon@moondeiMac  ~  %  cd /Users/moon/Downloads/nacos-2.2.1/distribution/target/nacos-server-2.2.1/nacos/bin
moon@moondeiMac bin % sh startup.sh -m standalone

# 再启动seata
moon@moondeiMac  ~  %  cd /Users/moon/Downloads/seata/bin
moon@moondeiMac bin % sh seata-server.sh 

分别访问:http://localhost:8848/nacos、http://localhost:7091/确认下nacos和seata启动无误。

然后依次启动seata-account-service、seata-storage-service、seata-order-service

请求接口,模拟正常下单:

http://localhost:2001/order/create?userId=1\&productId=1\&count=10\&money=100

运行结果:

3、常见问题

1)can not get cluster name in registry config 'service.vgroupMapping.xx', please make sure registry问题解决;

核对项目中和配置文件是否一致:

2)ERROR --- [cos.client.naming.updater] c.a.nacos.client.security.SecurityProxy : [SecurityProxy] login http request failed url: http://127.0.0.1:8848/nacos/v1/auth/users/login, params: {username=nacos}, bodyMap: {password=nacos}, errorMsg: Server returned HTTP response code: 500 for URL: http://127.0.0.1:8848/nacos/v1/auth/users/login?username=nacos

大体上是版本问题,参考文章开头,更换组件版本。

注意以下几点:

Seata相关配置是否正确

Seata Server是否正常启动,并可以被访问

Seata Client是否正确配置,并与Seata Server保持连接

相关推荐
这儿有个昵称11 小时前
Java面试场景:从音视频到微服务的技术深挖
java·spring boot·spring cloud·微服务·面试·kafka·音视频
Remember_99312 小时前
深入理解 Java String 类:从基础原理到高级应用
java·开发语言·spring·spring cloud·eclipse·tomcat
鸽鸽程序猿1 天前
【JavaEE】【SpringCloud】注册中心_nacos
java·spring cloud·java-ee
递归尽头是星辰1 天前
Spring Cloud Alibaba 核心理论体系:Nacos、Sentinel、Seata深度解析
spring cloud·nacos·sentinel·seata·微服务治理
lpfasd1231 天前
springcloud docker 部署问题排查与解决方案
spring·spring cloud·docker
蓝眸少年CY1 天前
(第七篇)spring cloud之Hystrix断路器
spring·spring cloud·hystrix
蓝眸少年CY1 天前
(第八篇)spring cloud之zuul路由网关
后端·spring·spring cloud
码出财富2 天前
SpringBoot 内置的 20 个高效工具类
java·spring boot·spring cloud·java-ee
daladongba2 天前
Spring Cloud Gateway
java·spring cloud·gateway
梁bk2 天前
[spring cloud] Seata分布式事务管理
分布式·spring·spring cloud