弧度网站建设,丹阳建设局网站,免费游戏网站建设,网站设计属于什么分类号一、分布式事务问题
1.1、本地事务
本地事务#xff0c;也就是传统的单机事务。在传统数据库事务中#xff0c;必须要满足四个原则#xff1a; 1.2、分布式事务
分布式事务#xff0c;就是指不是在单个服务或单个数据库架构下#xff0c;产生的事务#xff0c;例如也就是传统的单机事务。在传统数据库事务中必须要满足四个原则 1.2、分布式事务
分布式事务就是指不是在单个服务或单个数据库架构下产生的事务例如 跨数据源的分布式事务 跨服务的分布式事务 综合情况 在数据库水平拆分、服务垂直拆分之后一个业务操作通常要跨多个数据库、服务才能完成。例如电商行业中比较常见的下单付款案例包括下面几个行为 创建新订单 扣减商品库存 从用户账户余额扣除金额 完成上面的操作需要访问三个不同的微服务和三个不同的数据库。 订单的创建、库存的扣减、账户扣款在每一个服务和数据库内是一个本地事务可以保证ACID原则。
但是当我们把三件事情看做一个业务要满足保证“业务”的原子性要么所有操作全部成功要么全部失败不允许出现部分成功部分失败的现象这就是分布式系统下的事务了。
此时ACID难以满足这是分布式事务要解决的问题 二、理论基础
解决分布式事务问题需要一些分布式系统的基础知识作为理论指导。 2.1、CAP定理
1998年加州大学的计算机科学家 Eric Brewer 提出分布式系统有三个指标。 Consistency一致性 Availability可用性 Partition tolerance 分区容错性 它们的第一个字母分别是 C、A、P。
Eric Brewer 说这三个指标不可能同时做到。这个结论就叫做 CAP 定理。 2.1.1、一致性
Consistency一致性用户访问分布式系统中的任意节点得到的数据必须一致。
比如现在包含两个节点其中的初始数据是一致的 当我们修改其中一个节点的数据时两者的数据产生了差异 要想保住一致性就必须实现node01 到 node02的数据 同步
2.1.2、可用性
Availability 可用性用户访问集群中的任意健康节点必须能得到响应而不是超时或拒绝。
如图有三个节点的集群访问任何一个都可以及时得到响应 当有部分节点因为网络故障或其它原因无法访问时代表节点不可用
2.1.3、分区容错
Partition分区因为网络故障或其它原因导致分布式系统中的部分节点与其它节点失去连接形成独立分区。 Tolerance容错在集群出现分区时整个系统也要持续对外提供服务 2.1.4、矛盾
在分布式系统中系统间的网络不能100%保证健康一定会有故障的时候而服务有必须对外保证服务。因此Partition Tolerance不可避免。
当节点接收到新的数据变更时就会出现问题了 如果此时要保证一致性就必须等待网络恢复完成数据同步后整个集群才对外提供服务服务处于阻塞状态不可用。
如果此时要保证可用性就不能等待网络恢复那node01、node02与node03之间就会出现数据不一致。
也就是说在P一定会出现的情况下A和C之间只能实现一个。 2.2、BASE理论
BASE理论是对CAP的一种解决思路包含三个思想 Basically Available 基本可用分布式系统在出现故障时允许损失部分可用性即保证核心可用。 Soft State软状态在一定时间内允许出现中间状态比如临时的不一致状态。 Eventually Consistent最终一致性虽然无法保证强一致性但是在软状态结束后最终达到数据一致。 2.3、解决分布式事务的思路
分布式事务最大的问题是各个子事务的一致性问题因此可以借鉴CAP定理和BASE理论有两种解决思路 AP模式各子事务分别执行和提交允许出现结果不一致然后采用弥补措施恢复数据即可实现最终一致。 CP模式各个子事务执行后互相等待同时提交同时回滚达成强一致。但事务等待过程中处于弱可用状态。
但不管是哪一种模式都需要在子系统事务之间互相通讯协调事务状态也就是需要一个事务协调者(TC) 这里的子系统事务称为分支事务有关联的各个分支事务在一起称为全局事务。 三、Seata
Seata是 2019 年 1 月份蚂蚁金服和阿里巴巴共同开源的分布式事务解决方案。致力于提供高性能和简单易用的分布式事务服务为用户打造一站式的分布式解决方案。
官网地址http://seata.io/其中的文档、播客中提供了大量的使用说明、源码分析。 3.1、Seata的架构
Seata事务管理中有三个重要的角色 TC (Transaction Coordinator) - 事务协调者维护全局和分支事务的状态协调全局事务提交或回滚。 TM (Transaction Manager) - 事务管理器定义全局事务的范围、开始全局事务、提交或回滚全局事务。 RM (Resource Manager) - 资源管理器管理分支事务处理的资源与TC交谈以注册分支事务和报告分支事务的状态并驱动分支事务提交或回滚。 整体的架构如图 Seata基于上述架构提供了四种不同的分布式事务解决方案 XA模式强一致性分阶段事务模式牺牲了一定的可用性无业务侵入 TCC模式最终一致的分阶段事务模式有业务侵入 AT模式最终一致的分阶段事务模式无业务侵入也是Seata的默认模式 SAGA模式长事务模式有业务侵入
无论哪种方案都离不开TC也就是事务的协调者。 3.2、部署TC服务 1、下载 首先我们要下载seata-server包地址在http://seata.io/zh-cn/blog/download.html 2、解压 在非中文目录解压缩这个zip包其目录结构如下 3、修改配置 修改conf目录下的registry.conf文件 内容如下 registry {# tc服务的注册中心类这里选择nacos也可以是eureka、zookeeper等type nacosnacos {# seata tc 服务注册到 nacos的服务名称可以自定义application seata-tc-serverserverAddr localhost:8848group DEFAULT_GROUPnamespace cluster SH #所在集群username nacospassword nacos}
}config {# 读取tc服务端的配置文件的方式这里是从nacos配置中心读取这样如果tc是集群可以共享配置type nacos# 配置nacos地址等信息nacos {serverAddr localhost:8848namespace group SEATA_GROUPusername nacospassword nacosdataId seataServer.properties}
} 4、在nacos添加配置 特别注意为了让tc服务的集群可以共享配置我们选择了nacos作为统一配置中心。因此服务端配置文件seataServer.properties文件需要在nacos中配好。 格式如下 配置内容如下 # 数据存储方式db代表数据库
store.modedb
store.db.datasourcedruid
store.db.dbTypemysql
store.db.driverClassNamecom.mysql.jdbc.Driver
store.db.urljdbc:mysql://localhost:3306/seata?useUnicodetruerewriteBatchedStatementstrue
store.db.userroot
store.db.passwordroot
store.db.minConn5
store.db.maxConn30
store.db.globalTableglobal_table
store.db.branchTablebranch_table
store.db.queryLimit100
store.db.lockTablelock_table
store.db.maxWait5000
# 事务、日志等配置
server.recovery.committingRetryPeriod1000
server.recovery.asynCommittingRetryPeriod1000
server.recovery.rollbackingRetryPeriod1000
server.recovery.timeoutRetryPeriod1000
server.maxCommitRetryTimeout-1
server.maxRollbackRetryTimeout-1
server.rollbackRetryTimeoutUnlockEnablefalse
server.undo.logSaveDays7
server.undo.logDeletePeriod86400000# 客户端与服务端传输方式
transport.serializationseata
transport.compressornone
# 关闭metrics功能提高性能
metrics.enabledfalse
metrics.registryTypecompact
metrics.exporterListprometheus
metrics.exporterPrometheusPort9898 其中的数据库地址、用户名、密码都需要修改成你自己的数据库信息 5、创建数据库表 特别注意tc服务在管理分布式事务时需要记录事务相关数据到数据库中你需要提前创建好这些表。 新建一个名为seata的数据库 这些表主要记录全局事务、分支事务、全局锁信息
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS 0;-- ----------------------------
-- 分支事务表
-- ----------------------------
DROP TABLE IF EXISTS branch_table;
CREATE TABLE branch_table (branch_id bigint(20) NOT NULL,xid varchar(128) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,transaction_id bigint(20) NULL DEFAULT NULL,resource_group_id varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,resource_id varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,branch_type varchar(8) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,status tinyint(4) NULL DEFAULT NULL,client_id varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,application_data varchar(2000) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,gmt_create datetime(6) NULL DEFAULT NULL,gmt_modified datetime(6) NULL DEFAULT NULL,PRIMARY KEY (branch_id) USING BTREE,INDEX idx_xid(xid) USING BTREE
) ENGINE InnoDB CHARACTER SET utf8 COLLATE utf8_general_ci ROW_FORMAT Compact;-- ----------------------------
-- 全局事务表
-- ----------------------------
DROP TABLE IF EXISTS global_table;
CREATE TABLE global_table (xid varchar(128) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,transaction_id bigint(20) NULL DEFAULT NULL,status tinyint(4) NOT NULL,application_id varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,transaction_service_group varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,transaction_name varchar(128) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,timeout int(11) NULL DEFAULT NULL,begin_time bigint(20) NULL DEFAULT NULL,application_data varchar(2000) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,gmt_create datetime NULL DEFAULT NULL,gmt_modified datetime NULL DEFAULT NULL,PRIMARY KEY (xid) USING BTREE,INDEX idx_gmt_modified_status(gmt_modified, status) USING BTREE,INDEX idx_transaction_id(transaction_id) USING BTREE
) ENGINE InnoDB CHARACTER SET utf8 COLLATE utf8_general_ci ROW_FORMAT Compact;SET FOREIGN_KEY_CHECKS 1; 6、启动TC服务 进入bin目录运行其中的seata-server.bat即可 启动成功后seata-server应该已经注册到nacos注册中心了。 打开浏览器访问nacos地址http://localhost:8848然后进入服务列表页面可以看到seata-tc-server的信息 3.3、微服务集成Seata 引入依赖 首先在order-service中引入依赖 !--seata--
dependencygroupIdcom.alibaba.cloud/groupIdartifactIdspring-cloud-starter-alibaba-seata/artifactIdexclusions!--版本较低1.3.0因此排除-- exclusionartifactIdseata-spring-boot-starter/artifactIdgroupIdio.seata/groupId/exclusion/exclusions
/dependency
dependencygroupIdio.seata/groupIdartifactIdseata-spring-boot-starter/artifactId!--seata starter 采用1.4.2版本--version${seata.version}/version
/dependency 配置TC地址 在order-service中的application.yml中配置TC服务信息通过注册中心nacos结合服务名称获取TC地址 seata:registry: # TC服务注册中心的配置微服务根据这些信息去注册中心获取tc服务地址type: nacos # 注册中心类型 nacosnacos:server-addr: localhost:8848 # nacos地址namespace: # namespace默认为空group: DEFAULT_GROUP # 分组默认是DEFAULT_GROUPapplication: seata-tc-server # seata服务名称username: nacospassword: nacostx-service-group: seata-demo # 事务组名称service:vgroup-mapping: # 事务组与cluster的映射关系seata-demo: SH 微服务如何根据这些配置寻找TC的地址呢 我们知道注册到Nacos中的微服务确定一个具体实例需要四个信息 namespace命名空间 group分组 application服务名 cluster集群名 以上四个信息在刚才的yaml文件中都能找到 namespace为空就是默认的public 结合起来TC服务的信息就是publicDEFAULT_GROUPseata-tc-serverSH这样就能确定TC服务集群了。然后就可以去Nacos拉取对应的实例信息了。