一个用go实现的分布式事务框架

简介: 一个用go实现的分布式事务框架

easycar是什么


easycar 是一个用go实现的支持两阶段提交协议的分布式事务框架。目前还只支持TCC,SAGA 模式,其他模式待开发。在介绍easycar 之前,先简单介绍几个角色。


Transaction Coordinator(TC)


负责全局事务的管理,所有参与分布式事务的分支都会注册到coordinator,会给每个分布式事务分配一个唯一id,当然还包括驱动全局 begin / commit /abort(我喜欢称rollback)


Transaction Manager (TM)


有些时候也叫 Transaction Client,当然不同的实现也许都会换个名字,但是职责都大差不差。一般通过TM对每个参与的RM发起一阶段的请求,如果一阶段的RM全部成功,那么TM会向TC发起commit请求,否则发起rollback。


Resource Manager(RM)


用户维度的角色,管理本地事务处理的资源。其实你可以这么理解,假设你的订单服务部分接口参与了分布式事务,无论是第一阶段TM调用接口,还是TC第二阶段调用接口,你的订单服务都会去负责本地的事务修改。

那么 easycar 上述角色有什么不同吗?有的。既然TC负责的就是全局事务的管理,那么我把职责都给了它。即由TC每个参与的RM发起一阶段的请求,然后再根据一阶段的结果,发起二阶段的请求。由TC接管整个分布式事务的生命周期。是的,我弱化了上面TM的能力。在我眼里,TM本质上就是一个客户端。客户端只需要做一些数据封装,简便化操作即可。所以即使没有客户端,其他语言的用户也可以直接通过http请求easycar服务接口。所以理论上,大部分模式下,不需要客户端也是可以直接使用easycar服务的。


支持协议和事务模式同时混用


参与分布式事务的服务往往由不同的多个部门维护,或者部分新老项目交错,可能无法保证服务的协议是一致的。另外,不同的服务所采用的事务模式具体是由:业务场景以及构造的成本来决定的。所以参与分布式事务之间所使用的事务模式不一定是统一的。在这些基础上,easycar支持协议混用(目前支持http和原生的grpc服务),支持部分事务模式混用(目前支持TCC,Saga)。


支持并发执行


假如现在有 order,account以及stock三个服务。由这三个服务组成一个分布式事务。当用户下单时,需要经过这三个服务中内部一些接口(account 扣钱,stock减库存,order 创建订单)。如果只是同步执行第一阶段,那么第一阶段总执行时间= (account+stock+order)。很多场景下,分布式事务之间并不会存在执行依赖先后的关系。所以多个子事务一阶段可以同时并发执行。流程就像这样


1668517036317.jpg


上图我们需要保证创建订单前必须先执行account扣减余额和stock扣减库存服务,才能创建订单order的服务。同时account和stock服务并不需要保证他们的执行顺序。那么我们一阶段总执行耗时可以粗略=max(account,stock)+order。因此,easycar是支持分层并发执行的。对参与的RM通过设置的权重做分层,同一层的RM可以并发调用,一层处理完毕再接下一层。在这个基础上,当某个RM发生调用错误时,那么后面一层也不会执行了,整个分布式事务需要回滚。


异常处理


分布式事务中会出现一些问题,比如

  • 空补 Cancel请求到来时,Try还没有执行,这时候这样的请求我们不能执行,理应直接返回。
  • 悬挂:Try执行时,Cancel已执行完成,不能执行,直接返回。
  • 幂等:所有操作的接口都存在这个问题。

这些问题需要用户自己去解决,框架不会自动帮你处理。在我看来,这些问题本身就是服务的必要工作,而不是通过外部服务来帮你保证换句话说,前端说它参数做了校验,难道后端就不校验接口了吗?


重试


这一块暂时还没决定最终方案。我眼中的重试有两种模式:同步和异步。同步的意思是说,当请求RM服务发生错误的时候(网络、服务本身挂了、或者服务里的中间件挂了),通过固定次数固定时间重试,这个时间通常很短,比如一秒。问题是服务挂的情况下,短时间大概率好不了,重试几乎可能是无用功。整个过程,客户端是阻塞等待的,白白耗费时间。异步重试采用指数退避算法之类的逻辑,比如第一次重试1分钟后,第二次2分钟.....,限制一个上限值,比如最多延迟一个小时还是不行的话,那只能发告警,线下处理了。这样的弊端是

  • 首先用户不能实时获取本次分布式事务结果了(正在重试中),只能等到真正执行完毕的时候通过回调的方式异步通知用户分布式事务最终结果。
  • 退避时间越长,就意味着数据不一致的时间越长。但是如果人工直接干预又存在极大的风险。比如在你人工干预的同时,正好逻辑已经开始执行了,可能会造成新的数据不一致。


状态流转图


easycar global 状态流转图


1668517064263.jpg


最后


easycar 开发不是很久,它还有好多工作需要去完成。感兴趣的可以一起加入项目地https://github.com/wuqinqiang/easycar

相关文章
|
5月前
|
人工智能 测试技术 Go
Go 语言的主流框架
本文全面解析了 Go 语言主流技术生态,涵盖 Web 框架、微服务、数据库工具、测试与部署等多个领域。重点介绍了 Gin、Echo、Beego 等高性能框架,以及 gRPC-Go、Go-Micro 等微服务组件。同时分析了 GORM、Ent 等 ORM 工具与测试部署方案,并结合场景提供选型建议,助力开发者构建高效稳定的 Go 应用。
1399 0
|
3月前
|
消息中间件 缓存 NoSQL
Redis各类数据结构详细介绍及其在Go语言Gin框架下实践应用
这只是利用Go语言和Gin框架与Redis交互最基础部分展示;根据具体业务需求可能需要更复杂查询、事务处理或订阅发布功能实现更多高级特性应用场景。
309 86
|
2月前
|
JavaScript 前端开发 Java
【GoWails】Go做桌面应用开发?本篇文章带你上手Wails框架!一步步带你玩明白前后端双端的数据绑定!
wails是一个可以让你使用Go和Web技术编写桌面应用的项目 可以将它看作Go的快并且轻量级的Electron替代品。可以使用Go的功能,并结合现代化UI完成桌面应用程序的开发
561 4
|
2月前
|
开发框架 前端开发 Go
【GoGin】(0)基于Go的WEB开发框架,GO Gin是什么?怎么启动?本文给你答案
Gin:Go语言编写的Web框架,以更好的性能实现类似Martini框架的APInet/http、Beego:开源的高性能Go语言Web框架、Iris:最快的Go语言Web框架,完备的MVC支持。
389 1
|
9月前
|
数据采集 存储 数据可视化
分布式爬虫框架Scrapy-Redis实战指南
本文介绍如何使用Scrapy-Redis构建分布式爬虫系统,采集携程平台上热门城市的酒店价格与评价信息。通过代理IP、Cookie和User-Agent设置规避反爬策略,实现高效数据抓取。结合价格动态趋势分析,助力酒店业优化市场策略、提升服务质量。技术架构涵盖Scrapy-Redis核心调度、代理中间件及数据解析存储,提供完整的技术路线图与代码示例。
962 0
分布式爬虫框架Scrapy-Redis实战指南
|
6月前
|
开发框架 JSON 中间件
Go语言Web开发框架实践:路由、中间件、参数校验
Gin框架以其极简风格、强大路由管理、灵活中间件机制及参数绑定校验系统著称。本文详解其核心功能:1) 路由管理,支持分组与路径参数;2) 中间件机制,实现全局与局部控制;3) 参数绑定,涵盖多种来源;4) 结构体绑定与字段校验,确保数据合法性;5) 自定义校验器扩展功能;6) 统一错误处理提升用户体验。Gin以清晰模块化、流程可控及自动化校验等优势,成为开发者的优选工具。
|
6月前
|
开发框架 安全 前端开发
Go Web开发框架实践:模板渲染与静态资源服务
Gin 是一个功能强大的 Go Web 框架,不仅适用于构建 API 服务,还支持 HTML 模板渲染和静态资源托管。它可以帮助开发者快速搭建中小型网站,并提供灵活的模板语法、自定义函数、静态文件映射等功能,同时兼容 Go 的 html/template 引擎,具备高效且安全的页面渲染能力。
|
6月前
|
开发框架 JSON 中间件
Go语言Web开发框架实践:使用 Gin 快速构建 Web 服务
Gin 是一个高效、轻量级的 Go 语言 Web 框架,支持中间件机制,非常适合开发 RESTful API。本文从安装到进阶技巧全面解析 Gin 的使用:快速入门示例(Hello Gin)、定义 RESTful 用户服务(增删改查接口实现),以及推荐实践如参数校验、中间件和路由分组等。通过对比标准库 `net/http`,Gin 提供更简洁灵活的开发体验。此外,还推荐了 GORM、Viper、Zap 等配合使用的工具库,助力高效开发。
|
7月前
|
监控 Java 调度
SpringBoot中@Scheduled和Quartz的区别是什么?分布式定时任务框架选型实战
本文对比分析了SpringBoot中的`@Scheduled`与Quartz定时任务框架。`@Scheduled`轻量易用,适合单机简单场景,但存在多实例重复执行、无持久化等缺陷;Quartz功能强大,支持分布式调度、任务持久化、动态调整和失败重试,适用于复杂企业级需求。文章通过特性对比、代码示例及常见问题解答,帮助开发者理解两者差异,合理选择方案。记住口诀:单机简单用注解,多节点上Quartz;若是任务要可靠,持久化配置不能少。
703 4
|
10月前
|
开发框架 前端开发 Go
eino — 基于go语言的大模型应用开发框架(二)
本文介绍了如何使用Eino框架实现一个基本的LLM(大语言模型)应用。Eino中的`ChatModel`接口提供了与不同大模型服务(如OpenAI、Ollama等)交互的统一方式,支持生成完整响应、流式响应和绑定工具等功能。`Generate`方法用于生成完整的模型响应,`Stream`方法以流式方式返回结果,`BindTools`方法为模型绑定工具。此外,还介绍了通过`Option`模式配置模型参数及模板功能,支持基于前端和用户自定义的角色及Prompt。目前主要聚焦于`ChatModel`的`Generate`方法,后续将继续深入学习。
1359 7