什么是Seata?
官方文档:快速启动 | Seata
Seata(Simple Extensible Autonomous Transaction Architecture)是一个开源的分布式事务解决方案,旨在解决分布式系统中的数据一致性问题。它提供了一种高效、简单和可靠的方式来管理和协调分布式事务。
Seata的设计目标是为分布式系统中的事务管理提供全面的解决方案。它提供了分布式事务的核心功能,包括全局事务管理、分支事务管理和一致性协调,在分布式环境下实现了多个资源的原子性操作。
Seata的架构由三个主要组件组成:
-
TC(Transaction Coordinator):全局事务协调器,负责全局事务的启动、提交和回滚等操作,协调各个分支事务的执行。
-
TM(Transaction Manager):事务管理器,负责全局事务的提交和回滚等操作,与TC进行协作。
-
RM(Resource Manager):资源管理器,负责管理和控制分支事务所涉及的资源(如数据库)的操作,与TC进行协作。
Seata利用了全局事务ID和分支事务ID来标识全局事务和分支事务,通过在TC和各个RM之间的通信协议(如AT、TCC、SAGA等)来实现分布式事务的一致性。
Seata提供了与Spring Cloud、Dubbo等常见的分布式系统框架的集成,可以方便地与现有的应用程序进行集成,并提供了高可用、高性能和可靠的分布式事务解决方案。
总结来说,Seata是一个开源的分布式事务解决方案,通过协调全局事务和分支事务的执行来实现多个资源的原子性操作,解决了分布式系统中的数据一致性问题。
一、分布式事务
分布式事务是指在分布式系统中涉及多个节点或服务的事务操作。在传统的单体应用中,事务是在单个数据库中进行的,而在分布式系统中,数据可能分布在不同的数据库、消息队列、缓存等存储或服务中。
分布式事务的目标是保证多个节点或服务在执行事务操作时,要么全部成功,要么全部失败,即保持数据的一致性。
分布式事务面临以下挑战:
-
原子性(Atomicity):要求整个分布式事务的操作要么全部成功完成,要么全部失败回滚,不允许部分节点或服务操作成功而其他失败。
-
一致性(Consistency):要求在分布式事务开始和结束时,数据要保持一致状态,即符合预定义的业务规则。
-
隔离性(Isolation):要求并发执行的分布式事务之间相互隔离,互不影响。分布式系统中的并发操作可能会导致数据不一致或冲突。
-
持久性(Durability):要求一旦分布式事务提交成功,其结果应可靠地持久保存,即使发生故障也不会丢失。
为了实现分布式事务的一致性,通常使用两种主要的方式:
-
两阶段提交(Two-Phase Commit,2PC):是一种协调者和参与者之间协作的分布式事务协议。协调者在事务提交过程中向参与者发送指令,要么所有参与者都同意提交,要么回滚。缺点是需要同步等待所有参与者的响应,存在单点故障和性能瓶颈的风险。
-
补偿事务(Compensating Transaction):也称为补偿性事务或业务补偿,通过在分布式事务操作中引入补偿步骤,以补偿或撤销之前已执行的操作。这种方式具有一定的灵活性,但需要开发者设计和实现补偿逻辑。
分布式事务是构建高可靠的分布式系统的重要组成部分,但也需要开发人员谨慎设计和实施,以确保数据的一致性和可靠性
二、两阶段提交
两阶段提交(Two-Phase Commit,2PC)是一种分布式事务协议,用于实现多个节点或服务之间的数据一致性。它包括两个阶段:准备阶段(Prepare Phase)和提交阶段(Commit Phase)。
以下是两阶段提交的详细过程:
-
协调者(Coordinator)向参与者(Participant)发送事务提交请求。
-
参与者收到提交请求后,执行本地事务操作,并记录事务操作日志。所记录的日志包含了事务的标识、执行结果等信息。
-
在准备阶段,参与者将事务的执行结果通知给协调者,表示事务执行是否成功。
-
协调者等待所有参与者的准备结果。如果有任何一个参与者返回的准备结果为失败,则协调者发出回滚请求给所有参与者。
-
如果所有参与者的准备结果都为成功,协调者发出提交请求给所有参与者。
-
参与者收到提交请求后,在提交阶段,执行事务的最终提交操作,并释放相关资源。
-
参与者将提交结果通知给协调者。
-
协调者等待所有参与者的提交结果,如果有任何一个参与者返回的提交结果为失败,则协调者发出回滚请求给所有参与者。
-
如果所有参与者的提交结果都为成功,协调者发送提交成功的消息给应用程序,事务完成。
虽然两阶段提交协议可以保证分布式事务的一致性,但也存在一些问题:
-
同步阻塞:在准备和提交阶段,协调者需要等待所有参与者的响应,这会导致系统的响应时间增长和并发性能下降。
-
单点故障:协调者作为中心节点,一旦发生故障,可能导致整个分布式系统无法正常工作。
-
脑裂问题:如果在协调者向参与者发送准备请求后,网络故障导致协调者与部分参与者无法通信,可能会导致数据一致性问题。
尽管存在这些问题,两阶段提交协议仍然是解决分布式事务一致性问题的一种重要手段,尤其适用于对数据一致性要求较高的场景。
三、AT模式
AT模式是Seata(Simple Extensible Autonomous Transaction Architecture)框架中的一种分布式事务协议,它基于数据库的事务支持机制实现。
AT模式(也称为自动补偿模式)的关键思想是,在分布式事务执行期间,每个参与者(也称为服务或资源)在执行事务操作时,在本地数据库中创建事务日志并锁定相关数据。当所有参与者都成功执行了事务操作后,协调者(也称为事务管理器)提交全局事务;如果有任何一个参与者未能成功执行事务操作,则协调者回滚全局事务。
以下是AT模式的详细过程:
-
协调者向各个参与者发送全局事务开始请求。
-
参与者接收到全局事务开始请求后,在本地数据库中创建事务日志,记录需要参与全局事务的操作,并进行数据行级别的锁定。
-
参与者执行本地事务操作,保持数据库的一致性。
-
当参与者的本地事务执行成功后,在不对外暴露的情况下,参与者会将事务日志状态更改为"待提交"。
-
协调者向所有参与者发送确认提交请求。
-
参与者收到确认提交请求后,将事务日志状态更改为"已提交",并对数据行级别的锁进行解除。
-
协调者确认所有参与者的提交请求,提交全局事务。
如果在执行过程中发生故障或某个参与者无法提交事务,那么协调者会向所有参与者发送回滚请求,参与者将会回滚本地事务操作。
AT模式相对于传统的两阶段提交(2PC)协议,减少了等待和通信的时间,降低了系统的延迟,并且允许并发执行局部事务。这种模式适用于不涉及强一致性要求的场景,但在存在较高并发和大规模数据修改的情况下,可能需要考虑性能和扩展性的问题。
四、TCC模式
TCC模式是一种分布式事务解决方案,它基于“尝试(Try)- 确认(Confirm)- 取消(Cancel)”的操作模式来实现分布式事务的一致性。
TCC模式的主要思想是将一个复杂的分布式事务拆分为多个阶段,在每个阶段中执行相应的操作,并在需要时进行确认或取消操作,以保证数据的一致性。
以下是TCC模式的详细过程:
-
尝试阶段(Try Phase):
-
在这个阶段,参与者(也称为服务或资源)尝试预留和准备执行事务所需的资源和操作。
-
参与者执行一些必要的检查和准备工作,并提供必要的保证来确保后续的确认或取消操作能够成功执行。
-
-
确认阶段(Confirm Phase):
-
如果所有的参与者在尝试阶段都成功执行了事务操作,并且没有发生任何错误,协调者(也称为事务管理器)会向所有参与者发送确认请求。
-
参与者执行确认操作,并释放事务中使用的资源。确认操作是幂等的,可以多次执行而不会有副作用。
-
-
取消阶段(Cancel Phase):
-
如果在尝试阶段或确认阶段之后的任何时间点,参与者出现错误或者某个参与者无法执行确认操作,协调者会向所有参与者发送取消请求。
-
参与者执行取消操作,回滚已执行的事务操作,并释放事务中使用的资源。取消操作也是幂等的。
-
TCC模式的关键在于设计良好的接口和逻辑,以确保在每个阶段中的事务操作可以得到正确的执行和回滚。每个参与者需要实现三个接口方法:Try、Confirm和Cancel,分别对应尝试、确认和取消操作。
TCC模式的优势在于其灵活性和扩展性,可以应对复杂的分布式事务场景,并允许开发者根据业务需求进行定制和扩展。然而,由于需要手动实现逻辑和控制流程,TCC模式在编程和维护上可能需要更多的工作。
五、可靠消息最终一致性方案
可靠消息最终一致性方案是一种通过消息队列实现分布式系统中的数据一致性的机制。该方案通过可靠的消息传递和一致性保证,确保在分布式环境中发送和接收的消息可以被正确处理并保持一致。
以下是可靠消息最终一致性方案的基本流程和组成部分:
-
消息发送方将消息发送到消息队列:发送方将要发送的消息放入消息队列中进行缓存,确保消息的可靠传递。消息队列负责持久化消息,即使在系统故障或重启后也能恢复消息。
-
消息接收方从消息队列中获取消息并处理:接收方从消息队列中获取待处理的消息,并进行相应的业务逻辑处理。处理完成后,接收方发送确认消息给发送方,告知消息已成功处理。
-
发送方根据接收方的确认消息进行处理:发送方根据接收方发送的确认消息来确定消息是否被正确处理。如果接收方发送了确认消息,发送方可以将该消息从消息队列中移除。如果未收到确认消息或收到失败的确认消息,发送方可以采取相应的重试策略,例如重新发送消息给接收方。
-
幂等性处理:为了防止重复处理消息导致数据不一致的情况,接收方的处理逻辑应该是幂等的。这样,即使收到重复的消息,也不会对系统数据造成影响。
-
超时处理:在消息传递过程中,可能会出现网络故障或其他原因导致消息传递失败或延迟。发送方可以设置超时机制,当一定时间内未收到接收方的确认消息时,触发相应的处理策略,如重新发送消息或报错。
通过这种可靠消息最终一致性方案,分布式系统可以保证消息的可靠传递和处理,并最终达到数据一致性。这种方案应用于许多场景,包括分布式事务、异步消息处理、事件驱动架构等。常用的消息队列系统包括RabbitMQ、Kafka、ActiveMQ等。
六、Seata服务(TC)搭建高可用(DB+NACOS)
-
下载
-
修改TC存储模式
-
File模式:默认使用的存储方式,事务日志会以文件的形式进行存储。该方式适用于单机开发测试环境,简单易用。
-
DB模式:将事务日志存储在关系型数据库中,支持主流的数据库,如MySQL、Oracle等。该方式适用于生产环境,可以实现高可用、可靠的存储。
-
新建数据库,将script/server/db/mysql.sql文件写入数据库
-
通过conf/application.yml修改,存在状态为db
store: # support: file 、 db 、 redis mode: db session: mode: file lock: mode: file file: dir: sessionStore max-branch-session-size: 16384 max-global-session-size: 512 file-write-buffer-cache-size: 16384 session-reload-read-size: 100 flush-disk-mode: async db: datasource: druid db-type: mysql driver-class-name: com.mysql.jdbc.Driver url: jdbc:mysql://127.0.0.1:3306/seata?rewriteBatchedStatements=true user: mysql password: mysql min-conn: 10 max-conn: 100 global-table: global_table branch-table: branch_table lock-table: lock_table distributed-lock-table: distributed_lock query-limit: 1000 max-wait: 5000
-
-
Redis模式:将事务日志存储在Redis中,适用于对高性能和高可扩展性有要求的场景。
-
-
整合Nacos
-
通过conf/application.yml修改注册中心
registry: # support: nacos 、 eureka 、 redis 、 zk 、 consul 、 etcd3 、 sofa type: nacos preferred-networks: 30.240.* nacos: application: seata-server server-addr: 127.0.0.1:8848 group: SEATA_GROUP namespace: cluster: default username: password: context-path: ##if use MSE Nacos with auth, mutex with username/password attribute #access-key: #secret-key:
-
通过conf/application.yml修改配置中心
config: # support: nacos 、 consul 、 apollo 、 zk 、 etcd3 type: nacos nacos: server-addr: 127.0.0.1:8848 namespace: group: SEATA_GROUP username: password: context-path: ##if use MSE Nacos with auth, mutex with username/password attribute #access-key: #secret-key: data-id: seataServer.properties
-
将配置文件写入nacos
-
执行script/config-center/nacos/nacos-config.sh文件
-
命令 :./nacos-config.sh <NACOS_SERVER_ADDRESS> <NACOS_NAMESPACE> <NACOS_GROUP> <SEATA_CONFIG_PATH>
-
参数说明:
-
<NACOS_SERVER_ADDRESS>:Nacos服务器的地址,例如127.0.0.1:8848。
-
<NACOS_NAMESPACE>:Nacos的命名空间,默认值为public。
-
<NACOS_GROUP>:Nacos的配置组,默认值为DEFAULT_GROUP。
-
<SEATA_CONFIG_PATH>:Seata的配置文件存放路径,默认为${SEATA_HOME}/conf。
-
-
-
-
-
启动Seata server
-
执行bin/seata-server.sh文件
-
命令:./seata-server.sh -p <PORT> -m <MODE> -h <HOST> -n <NACOS_SERVER_ADDRESS> -g <NACOS_GROUP>
-
参数说明:
-
<PORT>:Seata Server的监听端口,默认值为8091。
-
<MODE>:Seata Server的启动模式,可选值为standalone(单机模式)或cluster(集群模式),默认为standalone。
-
<HOST>:Seata Server的主机地址,默认为127.0.0.1。
-
<NACOS_SERVER_ADDRESS>:Nacos服务器的地址,例如127.0.0.1:8848。
-
<NACOS_GROUP>:Nacos的配置组,默认值为DEFAULT_GROUP。
-
-
-
-
-
代码测试分布式事务
-
添加依赖
<dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-seata</artifactId> </dependency>
-
添加配置
spring: application: name: sca-customer datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://127.0.0.1:3306/seata?useUnicode=true&characterEncoding=utf8&characterSetResults=utf8 username: root password: 123456 cloud: nacos: # Nacos 服务注册发现 discovery: server-addr: 127.0.0.1:8848 alibaba: seata: # Seata 事务组名称,对应file.conf文件中 vgroup_mapping.sca-customer-seata-tx-service-group tx-service-group: my_test_tx_group seata: registry: type: nacos nacos: server-addr: 127.0.0.1:9100 application: 服务名 username: x password: x group: x config: nacos: server-addr: 127.0.0.1:9100 username: x password: x group: x
-
使用@ClobalTransactional注解,代码调试
-