함께 쓰는 습관을 들이세요! "너겟 데일리 뉴플랜 · 4월 업데이트 챌린지" 참여 11일차입니다. 클릭하시면 이벤트 내용을 보실 수 있습니다 .
springcloud+nacos+seata 프로젝트 통합
1. 환경 준비
1.1 nacos1.3.2 및 seata1.3.0 준비
- 나코스 문서
- 시타 문서
- nacos1.3.2 다운로드 주소
- Seata1.3.0 다운로드 주소
- Seata1.3.0의 config.txt 주소 (seata 서비스 시작에 필요한 구성 매개변수)
- Seata1.3.0의 nacos-config.sh 주소 (linux에서 nacos 구성 센터로 config.txt를 가져오는 스크립트)
- Seata1.3.0의 nacos-config.py 주소 (config.txt를 창 아래의 nacos 구성 센터로 가져오는 스크립트)
- Seata1.3.0의 mysql.sql 주소 (seata 서비스에 필요한 데이터베이스 파일)
1.2 nacos 및 seata 구성 및 시작
将解压后的nacos重命名为nacos-server
将解压后的seata重命名为seata-server
复制代码
- 나코스를 시작하다
修改nacos-server/bin/startup.cmd文件
将set MODE="cluster" 改为 set MODE="standalone",表示单机模式
复制代码
window启动命令,nacos-server/bin下
双击 startup.cmd
复制代码
linux启动命令,nacos-server/bin下
sh shutdown.sh
复制代码
- 시타를 준비하다
下载config.txt放入seata-server目录下
下载nacos-config.py,nacos-config.sh,mysql.sql放入seata-server/conf目录下
复制代码
- Seata 데이터베이스 생성
在本地mysql数据库服务器中,创建以seata命名的数据库。
然后在数据库中执行下mysql.sql文件,创建seata相关的表。
复制代码
- config.txt의 구성을 nacos 구성 센터로 가져옵니다.
修改store.mode,改为db模式
修改store.db.url和store.db.user、store.db.password为刚创建的seata数据库的配置
特别注意:(后面搭建服务需要用到)
service.vgroupMapping.my_test_tx_group=default
my_test_tx_group表示事务群组,my_test_tx_group为分组,配置项值为TC集群名
这里加入两个事物群组:
service.vgroupMapping.order-service-group=default
service.vgroupMapping.storage-service-group=default
复制代码
window下,将config.txt推送到nacos的执行命令:
进入到seata-server\conf目录下执行:
python nacos-config.py 127.0.0.1:8848
(特别注意:要有python的环境,无的话自己手动添加到nacos配置中心啦(♥◠‿◠))
linux下,将config.txt推送到nacos的执行命令:
sh nacos-config.sh -h 127.0.0.1 -p 8848
复制代码
-
Seata 구성 수정
- nacos와 db를 사용하고 있기 때문에 seata-server/conf 아래의 file.conf 파일을 삭제할 수 있습니다.
- Seata-server/conf 아래의 registry.conf 파일을 수정합니다.
registry { # file 、nacos 、eureka、redis、zk、consul、etcd3、sofa type = "nacos" nacos { application = "seata-server" serverAddr = "127.0.0.1:8848" #这个端口号可以省略 # 这个group一定要配置成"DEFAULT_GROUP"否则找不到seata-server服务 group = "DEFAULT_GROUP" namespace = "" cluster = "default" username = "" password = "" } } config { # file、nacos 、apollo、zk、consul、etcd3 type = "nacos" nacos { serverAddr = "127.0.0.1" namespace = "" group = "SEATA_GROUP" username = "" password = "" } } 复制代码
- seata-server/bin에서 jvm 메모리 구성, .bat 및 .sh 파일 수정
%JAVACMD% %JAVA_OPTS% -server -Xmx512m -Xms512m -Xmn512m -Xss512k 复制代码
-
시타 서비스 시작
window启动命令,seata-server/bin下
双击 seata-server.bat
复制代码
linux启动命令,seata-server/bin下
sh seata-server.sh -p 8091 -h 127.0.0.1
复制代码
2.springcloud-nacos-seata 준비
1. AT 모드를 위한 데이터베이스 준비
在本地mysql数据库服务器中,执行一下database.sql文件创建seata-order和seata-storage数据库。
复制代码
2. 각 응용 프로그램의 리소스에 registry.conf를 구성해야 하며 이는 seata-server의 구성과 동일합니다.
application.yml 的各个配置项,注意spring.cloud.alibaba.seata.tx-service-group 是服务组名称,
与config.txt 配置的service.vgroup_mapping.${your-service-gruop}具有对应关系
复制代码
3.application.yml 배치
spring:
cloud:
nacos: # Nacos 注册中心地址
discovery:
server-addr: 127.0.0.1:8848
alibaba:
seata:
tx-service-group: ${spring.application.name}-group
复制代码
4. 글로벌 거래 열기
在服务调用方使用@GlobalTransactional注解即可。(无侵入式的喔(♥◠‿◠))
使用seata的AT模式,也就是两阶段提交
两阶段提交协议的演变:
一阶段:业务数据和回滚日志记录在同一个本地事务中提交,释放本地锁和连接资源。
二阶段:
提交异步化,非常快速地完成。
回滚通过一阶段的回滚日志进行反向补偿。
复制代码
/**
* 下单:创建订单、减库存,涉及到两个服务
*
* @param userId
* @param commodityCode
* @param count
*/
@GlobalTransactional
@Transactional(rollbackFor = Exception.class)
public void placeOrder(String userId, String commodityCode, Integer count) {
BigDecimal orderMoney = new BigDecimal(count).multiply(new BigDecimal(5));
Order order = new Order()
.setUserId(userId)
.setCommodityCode(commodityCode)
.setCount(count)
.setMoney(orderMoney);
orderDAO.insert(order);
storageFeignClient.deduct(commodityCode, count);
}
复制代码
注:seata也支持TCC模式,TCC是由蚂蚁金服提供支持的,懂的都懂(♥◠‿◠)。
性能优化,TCC模式虽然有代码侵入,但是比AT模式性能要高。
复制代码
5. 테스트
分布式事务成功,模拟正常下单、扣库存
localhost:9091/order/placeOrder/commit
分布式事务失败,模拟下单成功、扣库存失败,最终同时回滚
localhost:9091/order/placeOrder/rollback
复制代码
6. 원칙
TC (Transaction Coordinator) - 事务协调者
维护全局和分支事务的状态,驱动全局事务提交或回滚。
TM (Transaction Manager) - 事务管理器
定义全局事务的范围:开始全局事务、提交或回滚全局事务。
RM (Resource Manager) - 资源管理器
管理分支事务处理的资源,与TC交谈以注册分支事务和报告分支事务的状态,并驱动分支事务提交或回滚。
复制代码
1. TM向TC申请开启一个全局事务,全局事务创建成功并生成一个全局唯一的XID。
2. XID在微服务调用链路的上下文中传播。
3. RM向TC注册分支事务,将其纳入XID对应全局事务的管辖。
4. TM向TC发起针对XID的全局提交或回滚决议。
5. TC调度XID下管辖的全部分支事务完成提交或回滚请求。
复制代码
- 시타 1단계 로딩
- 시타 2단계 커밋
- 시타 2단계 롤백
Seata(AT 모드)의 기본 전역 격리 수준은 커밋되지 않은 읽기입니다.
7. 씨타 클러스터 구축
执行 ./seata-server.sh -p 18091 -n 1 命令,启动第一个TC Server;
-p:Seata TC Server 监听的端口;
-n:Server node,在多个 TC Server 时,需区分各自节点,用于生成不同区间的 transactionId 事务编号,以免冲突;
执行 ./seata-server.sh -p 28091 -n 2 命令,启动第二个TC Server;
复制代码
8.TCC 모드
一个分布式的全局事务,整体是两阶段提交(Try - [Comfirm/Cancel])的模型,在Seata中,AT模式与TCC模式事实上都是基于两阶段提交,它们的区别在于:
AT模式基于支持本地ACID事务的关系型数据库:
1、一阶段prepare行为:在本地事务中,一并提交“业务数据更新“和”相应回滚日志记录”;
2、二阶段 commit 行为:马上成功结束,自动异步批量清理回滚日志;
3、二阶段 rollback 行为:通过回滚日志,自动生成补偿操作,完成数据回滚;
而TCC 模式,需要我们人为编写代码实现提交和回滚:
1、一阶段 prepare 行为:调用自定义的 prepare 逻辑;(真正要做的事情,比如插入订单,更新库存,更新余额)
2、二阶段 commit 行为:调用自定义的 commit 逻辑;(自己写代码实现)
3、二阶段 rollback 行为:调用自定义的 rollback 逻辑;(自己写代码实现)
所以TCC模式,就是把自定义的分支事务的提交和回滚并纳入到全局事务管理中;
通俗来说,Seata的TCC模式就是手工版本的AT模式,它允许你自定义两阶段的处理逻辑而不需要依赖AT模式的undo_log回滚表;
复制代码
9. 테스트
分布式事务成功,模拟正常下单、扣库存
localhost:9091/order/placeOrderTcc/commit
分布式事务失败,模拟下单成功、扣库存失败,最终同时回滚
localhost:9091/order/placeOrderTcc/rollback
复制代码