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保持连接

相关推荐
Wx-bishekaifayuan9 分钟前
django电商易购系统-计算机设计毕业源码61059
java·spring boot·spring·spring cloud·django·sqlite·guava
customer0813 分钟前
【开源免费】基于SpringBoot+Vue.JS周边产品销售网站(JAVA毕业设计)
java·vue.js·spring boot·后端·spring cloud·java-ee·开源
Stringzhua2 小时前
【SpringCloud】Kafka消息中间件
spring·spring cloud·kafka
想进大厂的小王7 小时前
项目架构介绍以及Spring cloud、redis、mq 等组件的基本认识
redis·分布式·后端·spring cloud·微服务·架构
customer088 小时前
【开源免费】基于SpringBoot+Vue.JS医院管理系统(JAVA毕业设计)
java·vue.js·spring boot·后端·spring cloud·开源·intellij-idea
杨荧8 小时前
【JAVA毕业设计】基于Vue和SpringBoot的服装商城系统学科竞赛管理系统
java·开发语言·vue.js·spring boot·spring cloud·java-ee·kafka
aloha_78921 小时前
从零记录搭建一个干净的mybatis环境
java·笔记·spring·spring cloud·maven·mybatis·springboot
茶馆大橘1 天前
微服务系列五:避免雪崩问题的限流、隔离、熔断措施
java·jmeter·spring cloud·微服务·云原生·架构·sentinel
荆州克莱1 天前
[FE] React 初窥门径(四):React 组件的加载过程(render 阶段)
spring boot·spring·spring cloud·css3·技术