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已创建完成,接下来就是愉快的使用啦。