基于Seata源码构建部署Server服务端(Jenkins+Docker+Nacos+Mysql)

487 阅读3分钟

Seata官方文档提供了多种Server方式部署:1、直接部署 2、使用 Docker 3、使用 Docker-Compose 4、使用 Kubernetes 5、使用 Helm。最常见的就是通过Docker部署docker-hub的官方seata镜像的方式,只需简单配置就能部署使用,网上有大量的部署文档可供参考,参考价值比较高的的教程如下:cloud.tencent.com/developer/a…,该文档详细介绍了seata服务端如何进行docker部署,读者可自行验证。

之前由于项目需要分布式事务的场景,笔者通过ranchar容器化部署dockerhub镜像seataio/seata-server:1.6.1,对 server端服务进行域名上下文映射后(seata.xxxx.com),已接入多个业务线使用。最近公司进行网络安全等级升级,容器安全漏洞扫描发现seata:1.6.1存在多个安全漏洞,漏洞清单如下:

  • Spring Security RegexRequestMatcher 认证绕过漏洞(CVE-2022-22978)
  • Spring Security AuthenticatedVoter 权限绕过漏洞(CVE-2024-22257)
  • Apache Kafka Connect 远程代码执行漏洞(CVE-2023-25194)
  • Spring Web UriComponentsBuilder URL解析不当漏洞(CVE-2024-22243)
  • Spring Framework 特殊匹配模式下身份认证绕过漏洞(CVE-2023-20860)

因此需要手动修复以上漏洞,另外公司要求所有系统接入统一单点登录认证(SSO),所以需要屏蔽Seata自有的控制台登录认证方式,并需要对Seata源码进行二次开发,接入公司SSO系统。

最重要的一点dockerhub镜像仓库是国外站点,最近在国内访问dockerhub已经被限制,需要通过自建镜像仓库或者引入国内镜像仓库如阿里云、华为云等。所以现实情况需要下载源码并进行二次开发构建部署seata服务,笔者花了些时间查阅网上的相关资料,没有一篇完整、可用的文档教程值得参考,笔者在本地及测试服务器经过一段时间的不断调试和验证,终于实现了通过jenkins构建git源码,并将docker镜像上传到harbor私有镜像仓库,配置容器一键部署,再也不用受限于docker-hub和安全漏洞扫描的风险。以下是具体步骤:

一、源码下载

gitee地址:gitee.com/seata-io/se…

github地址:github.com/apache/incu…

二、源码配置修改

seata服务端默认配置路径是:server/src/main/resources/application.yml,本文采用nacos注册方式,数据持久化方式为db(Mysql)

需要自定义application.yml来替换server的默认配置,替换即可,本文nacos使用的是阿里云ak/sk,可替换为username/password方式:

server:
  port: 8080
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:
    type: nacos
    nacos:
      server-addr: mse-*******.aliyuncs.com:8848
      namespace: demo
      group: demo
      #seata的服务端其他配置通过nacos-config配置
      data-id: seata.properties
      access-key: **********
      secret-key: **********
      #username: **********
      #password: **********
  registry:
    type: nacos
    nacos:
      application: seata-server
      server-addr: mse-*******.aliyuncs.com:8848
      namespace: demo
      group: demo
      cluster: default
      access-key: **********
      secret-key: **********
      #username: **********
      #password: **********
  security:
    secretKey: SeataSecretKey0c382ef121d778043159209298fd40bf3850a017
    tokenValidityInMilliseconds: 1800000
    ignore:
      urls: /,/**/*.css,/**/*.js,/**/*.html,/**/*.map,/**/*.svg,/**/*.png,/**/*.ico,/console-fe/public/**,/api/v1/auth/login

三、新增Nacos配置文件

3.1 配置seata事务、db等信息

在上一步设置的nacos的配置中心地址的命名空间下,新增data-id为seata.properties的文件(seata.properties只是个名字,可按自己喜欢的命名修改为yaml)

seata.properties完整示例:

# 数据存储方式,db代表数据库
store.mode=db
store.db.datasource=druid
store.db.dbType=mysql
store.db.driverClassName=com.mysql.cj.jdbc.Driver
store.db.url=jdbc:mysql://********:3306/seata?useUnicode=true&rewriteBatchedStatements=true&serverTimezone=GMT
store.db.user=*****
store.db.password=*******
store.db.minConn=5
store.db.maxConn=30
store.db.globalTable=global_table
store.db.branchTable=branch_table
store.db.queryLimit=100
store.db.lockTable=lock_table
store.db.maxWait=5000
# 事务、日志等配置
server.recovery.committingRetryPeriod=3000
server.recovery.asynCommittingRetryPeriod=3000
server.recovery.rollbackingRetryPeriod=3000
server.recovery.timeoutRetryPeriod=3000
server.maxCommitRetryTimeout=-1
server.maxRollbackRetryTimeout=-1
server.rollbackRetryTimeoutUnlockEnable=false
server.undo.logSaveDays=7
server.undo.logDeletePeriod=86400000
# 客户端与服务端传输方式
transport.serialization=seata
transport.compressor=none
# 关闭metrics功能,提高性能
metrics.enabled=false
metrics.registryType=compact
metrics.exporterList=prometheus
metrics.exporterPrometheusPort=9898

3.2 配置客户端事务组TM、RM映射

在上一步设置的nacos的配置中心地址的命名空间下,新增data-id为client.properties的文件(client.properties只是个名字,可按自己喜欢的命名修改为yaml)

client.properties完整示例:

# 事务组映射关系
service.vgroupMapping.my-tx-group=default
#是否启用降级
service.enableDegrade=false
service.disableGlobalTransaction=false
# 与TC服务的通信配置
transport.type=TCP
transport.server=NIO
transport.heartbeat=true
transport.enableClientBatchSendRequest=false
transport.threadFactory.bossThreadPrefix=NettyBoss
transport.threadFactory.workerThreadPrefix=NettyServerNIOWorker
transport.threadFactory.serverExecutorThreadPrefix=NettyServerBizHandler
transport.threadFactory.shareBossWorker=false
transport.threadFactory.clientSelectorThreadPrefix=NettyClientSelector
transport.threadFactory.clientSelectorThreadSize=1
transport.threadFactory.clientWorkerThreadPrefix=NettyClientWorkerThread
transport.threadFactory.bossThreadSize=1
transport.threadFactory.workerThreadSize=default
transport.shutdown.wait=3
# RM配置
client.rm.asyncCommitBufferLimit=10000
client.rm.lock.retryInterval=10
client.rm.lock.retryTimes=30
client.rm.lock.retryPolicyBranchRollbackOnConflict=true
client.rm.reportRetryCount=5
client.rm.tableMetaCheckEnable=false
client.rm.tableMetaCheckerInterval=60000
client.rm.sqlParserType=druid
client.rm.reportSuccessEnable=false
client.rm.sagaBranchRegisterEnable=false
# TM配置
client.tm.commitRetryCount=5
client.tm.rollbackRetryCount=5
client.tm.defaultGlobalTransactionTimeout=60000
client.tm.degradeCheck=false
client.tm.degradeCheckAllowTimes=10
client.tm.degradeCheckPeriod=2000
# undo日志配置
client.undo.dataValidation=true
client.undo.logSerialization=jackson
client.undo.onlyCareUpdateColumns=true
client.undo.logTable=undo_log
client.undo.compress.enable=true
client.undo.compress.type=zip
client.undo.compress.threshold=64k
client.log.exceptionRate=100

四、Jenkins配置

4.1 源码管理-配置git地址

4.2 Build-配置maven命令

maven构建命令

-Prelease-seata -DskipTests=true clean install -U

4.3 执行脚本-Dockerfile

执行脚本完整示例:

pwd

echo "Version:$version"

docker login -udemo -pdemo https://harbor.demo.com/

REPOSITORY=harbor.demo.com/demo/seata-server:$version

cat > Dockerfile << EOF

FROM openjdk:11.0.16-jdk

ADD server/target/seata-server.jar /opt/data/run.jar

# 在容器创建新用户
RUN useradd -u 1000 server 
RUN chown -R  server /opt 
CMD ["java","-jar","-Dserver.port=8080","-Dspring.profiles.active=test","/opt/data/run.jar"]

EXPOSE 8080 
EXPOSE 7091 
EXPOSE 8091

EOF

docker build -t $REPOSITORY .

docker push $REPOSITORY

通过以上jenkins配置一键构建打包,生成seata服务端的镜像,笔者所在公司使用的自建rancher容器服务,通过jenkins配置每次构建后主动触发容器部署镜像。

自此服务端的配置工作就到此结束,在seata-server容器服务日志中查看,出现Success to connect to server....说明服务端已正常注册到Nacos。

五、客户端TM应用配置

服务端正常注册到Nacos,接下来就是客户端TM配置seata,以能够正常订阅seata服务端。以下是笔者项目中的配置demo,仅供参考。

5.1 seata客户端SDK依赖

<dependency>
  <groupId>com.alibaba.cloud</groupId>
  <artifactId>spring-cloud-starter-alibaba-seata</artifactId>
  <exclusions>
    <exclusion>
      <artifactId>seata-spring-boot-starter</artifactId>
      <groupId>io.seata</groupId>
    </exclusion>
  </exclusions>
  <version>2021.0.6.0</version>
</dependency>
<dependency>
  <groupId>io.seata</groupId>
  <artifactId>seata-spring-boot-starter</artifactId>
  <version>1.5.2</version>
</dependency>

5.2 spring配置

seata.enabled=true
seata.registry.type=nacos
seata.registry.nacos.server-addr=***************.aliyuncs.com:8848
seata.registry.nacos.namespace=***************
seata.registry.nacos.group=***************
seata.registry.nacos.access-key=***************
seata.registry.nacos.secret-key=***************
seata.registry.nacos.application=seata-server
#seata-事务组配置
seata.tx-service-group=my-tx-group
seata.service.vgroupMapping.my-tx-group=default
seata.config.type=nacos
seata.config.nacos.server-addr=***************.aliyuncs.com:8848
seata.config.nacos.group=***************
seata.config.nacos.namespace=***************
seata.config.nacos.access-key=***************
seata.config.nacos.secret-key=***************
seata.config.nacos.data-id=seata-client.properties

客户端服务启动后,控制台如果打印以下信息,则说明订阅成功,register TM success. client version:1.5.2, server version:1.6.1,channel......

服务端也会有客户端TM注册日志

自此,基于Seata源码构建部署Server已创建完成,接下来就是愉快的使用啦。