Hmily 源码解析(一)

Hmily 源码解析(一)第一次看源码,也是第一次写分析源码的博文,写的不足之处希望多见谅。Hmily是分布式事务框架,基于TCC分布式事务概念。关于TCC概念我这边就不复述了,本博文基于对TCC概念有了解的基础上解析Hmily框架的实现。我计划将从两个维度进行分析,一个是业务流转的过程,通过状态的流转,方法调用来分析Hmily。另一个是从类功能的角度分析Hmily。主要以业务流转为主,类功能为辅解析Hmily的实…

大家好,又见面了,我是你们的朋友全栈君。


  • 第一次看源码,也是第一次写分析源码的博文,写的不足之处希望多见谅。
  • Hmily 是分布式事务框架,基于TCC分布式事务概念。关于TCC概念我这边就不复述了,本博文基于对TCC概念有了解的基础上解析Hmily框架的实现。
  • 我计划将从两个维度进行分析,一个是业务流转的过程,通过状态的流转,方法调用来分析Hmily。另一个是从类功能的角度分析Hmily。主要以业务流转为主,类功能为辅解析Hmily的实现,我觉得这样更能将hmily清晰的展现在我们眼前。

1.框架结构

  • 项目地址:https://github.com/yu199195/hmily
  • 解析基于的版本:2.0.3-RELEASE
  • 项目架构
    • hmily-admin:分布式事务后台模块,查看事务的失败情况等,这块暂不分析
    • hmily-dashboard:hmily-admin后台模块的前端页面,暂不分析
    • hmily-annotation:存放hmily的自定义注解
    • hmily-common: hmily核心模块,重点分析
    • hmily-core:hmily核心模块,重点分析
    • hmily-springcloud:基于springcloud分布式的hmily实现,重点分析
    • hmily-spring-boot-start:基于hmily-springcloud的再封装,暂不分析
    • 其它模块是基于dubbo等其他分布式框架的实现,同hmily-springcloud类似,我这边就分析基于springcloud的实现,毕竟其它的分布式框架我也没有接触过。
      在这里插入图片描述
  • hmily-demo模块
    • 基于springcloud分布式的demo
    • hmily-demo-springcloud-eureka:eureka注册中心
    • hmily-demo-springcloud-order:订单微服务
    • hmily-demo-springcloud-account:账户微服务
    • hmily-demo-springcloud-inventory:库存微服务
    • hmily-demo.sql:测试数据库初始化脚本
      在这里插入图片描述
  • 数据库结构
    • TCC 库: 事务日志库,为每一个微服务都建立一个日志表
    • order表:订单业务表
    • account表:账户金额表
    • inventory表:库存表

在这里插入图片描述

2.项目初始化

  • Hmily天然支持分布是的原因是因为Hmily本身就是基于分布式是实现的,它不像eureka之流有一个管理中心。Himly从代码层面的上来说没有主从之分。每一个需要使用或被参与到分布式事务的微服务都要依赖Hmily,它们之间的Hmily通信与状态的流转就是依靠于微服务本身的通信方式,比如springcloud中的fegin。
  • order,account,inventory都要参与分布事务,从业务上来说,order是主-发起者,其它两个是从-参与者。但是它们的初始化方式都是一样的,因为之前说了Himly在代码层面不存在主从分别,初始化我们通过一个微服务来讲解就好了。
    • 注:在看源码时我们会发现account的依赖方式同order,inventory不同。order、inventory是依赖hmily-springcloud,而account依赖与hmily-spring-boot-start。其实它们本质上是一样的,看hmily-spring-boot-start源码会发现它也是依赖于hmily-springcloud。它们的区别只是hmily-spring-boot-start可以把一些配置信息放置在application.yml文件中,hmily-springcloud是把信息放置在applicationContext.xml文件中。这里只是作者给我们提供了两种不同配置方案,我们根据项目需要选择就好。
  • 现在我们来分析hmily-demo-springcloud-order下Hmily的初始化。

在这里插入图片描述

  • 打开applicationContent.xml文件(截取核心的代码)
    在这里插入图片描述

  • HmilyTransactionBootstrap类处于core模块内。

    • 首先继承HmilyConfig类,这个类的作用是存放Hmily的配置信息,配置我都采用默认配置。
    • 另外又继承了ApplicationContextAware接口。这个接口只有一个抽象方法setApplicationContext,它的作用是在该对象实例化之后spring会调用该方法将ApplicationContext传递进来,我们看到ApplicationContext被放置到SpringBeanUtils的唯一实例之中,这样hmily就拥有了动态创建对象的能力。

在这里插入图片描述

  • 在对象初始化时,通过@Autowired注解spring实例了一个HmilyInitService对象进来,这个对象将继续进行着Hmily框架的初始化。
  • setApplicationContext方法在将ApplicationContext实例放置好之后,就以本实例为参数调用了start方法
  • 在start方法的参数类型是HmilyConfig,HmilyTransactionBootstrap的作用到这里已经结束了,只有它继承的HmilyConfig部分将继续发挥作用。start方法内只有一条语句,通过hmilyInitService将继续进行着Hmily框架的初始化。

  • HmilyInitService是接口,它的实现是HmilyInitServiceImpl类,我们定位到该类找到initialization方法
    在这里插入图片描述* 首先在虚拟机关闭时加了一个日志线程,输出关闭日志。
  • 其次根据配置文件加载spi支持
    • 一个是序列化方式, 默认是kryo序列化算法。一些类需要作为日志存储起来所以需要用到统一的序列化方式。
    • 一个是日志的维护接口(HmilyCoordinatorRepository),这里是采用db方式,具体实现类为JdbcCoordinatorRepository。维护的具体对象就是tcc库下的三张日志表。
    • 接着我们看到序列化方式被放置到HmilyCoordinatorRepository中了,看来对于对象的序列化只会在这里使用到。
    • 接着HmilyCoordinatorRepository实例根据HmilyCoordinatorRepository的class名被注册到SpringBeanUtils之中为单例对象。以后想要维护日志,根据HmilyCoordinatorRepository的class名从SpringBeanUtils中获取该实例即可。
      在这里插入图片描述
  • 我们继续看initialization方法,是hmilyCoordinatorService实例继续根据hmilyConfig接着初始化的工作。
  • hmilyCoordinatorService的来源呢?同上文一样在该实例初始化时被实例进来的。
    在这里插入图片描述
  • HmilyLogo().logo()的作用是初始化完成后输出banner日志,不多说了
  • 我们接着看hmilyCoordinatorService.start方法是如何初始化的

  • hmilyCoordinatorService接口的实现是HmilyCoordinatorServiceImpl类,它的是管理日志的service层,同前面的HmilyCoordinatorRepository实例配合使用。

  • 首先我们定位到start方法
    在这里插入图片描述

  • 首先是获取repositorySuffix,这个属性的作用是作为日志表的后缀名,比如tcc库下hmily_order_service表的后缀”order_service”,我们看一下是如何获取的。

  • buildRepositorySuffix方法内,首先hmilyConfig里面如果有配置,采用配置的(默认没有)。其次根据hmilyApplicationService(同上初始化时注入)获取,默认返回是application.yml文件中spring.application.name值。
    在这里插入图片描述

  • 我们看start方法的第二条语句,从SpringBeanUtils获取我们前面注册的coordinatorRepository对象并放置到hmilyApplicationService中。

  • 接着coordinatorRepository继续着初始化工作,已经第四个了。。。。


  • coordinatorRepository 是日志维护的Repository层,我们这边的实现类是JdbcCoordinatorRepository类,我们定位到init方法(尽力截图…)
    在这里插入图片描述
  • 第一步获取HmilyDbConfig,数据库的配置,我们在前面的配置文件中可以看到。
  • 接下来的if-else 是设置数据库连接的(dataSource),按下不表。
  • 接下来RepositoryPathUtils根据传进来的后缀属性生成日志表名,如例即得表名“hmily_order_service”
  • 接着DbTypeUtils根据配置文件获取连接的数据库类型,这里是mysql,作用先按下不表。
  • 最后生成日志, 首先通过SqlHelper生成创建表的sql语句,再通过executeUpdate执行该sql,都很简单不再细说了。

  • 到这边初始化就做完了,我们总结一下做了什么
  • 首先在SpringBeanUtils中我们有了ApplicationContext(应用上下文)了,拥有了创建实例对象与注册对象获取注册对象的功能。
  • 通过spi创建了ObjectSerializer(序列化方式),HmilyCoordinatorRepository(日志数据操作类),并把HmilyCoordinatorRepository注册到应用上下文之中为单例对象。把它注册进去为单例对象的原因是因为HmilyCoordinatorRepository中存储了和数据库的连接仓库(datasource),还有日志表名等。
  • 接着我们根据配置信息创建了日志表的表名,生成数据库连接信息datasource等都存储在HmilyCoordinatorRepository之中。最后创建了日志表。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/143158.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • JQuery Datepicker 中文显示设置

    JQuery Datepicker 中文显示设置

    2021年8月21日
    65
  • linux驱动ioctl函数,Linux中与驱动相关的ioctl函数

    linux驱动ioctl函数,Linux中与驱动相关的ioctl函数一:ioctl函数的作用ioctl用于向设备发控制和配置命令,有些命令也需要读写一些数据,但这些数据是不能用read/write读写的,称为Out-of-band数据。也就是说,read/write读写的数据是in-band数据,是I/O操作的主体,而ioctl命令传送的是控制信息,其中的数据是辅助的数据。ioctl是设备驱动程序中对设备的I/O通道进行管理的函数,所谓对I/O通道进行管理…

    2022年10月17日
    0
  • 存储过程与视图

    存储过程与视图存储过程与视图

    2022年4月24日
    34
  • 左连接 ,右连接,内连接和全外连接的4者区别[通俗易懂]

    左连接 ,右连接,内连接和全外连接的4者区别[通俗易懂]基本定义:  leftjoin(左连接):返回包括左表中的所有记录和右表中连接字段相等的记录。  rightjoin(右连接):返回包括右表中的所有记录和左表中连接字段相等的记录。  innerjoin(等值连接或者叫内连接):只返回两个表中连接字段相等的行。  fulljoin(全外连接):返回左右表中所有的记录和左右表中连接字段相等的记录。举个例子: …

    2022年5月24日
    36
  • java超市仓库管理系统(超市条形码管理系统)

    目录文档说明:一、语言和环境二、要求三、重要说明四、推荐实现步骤五、注意事项实现代码:一、数据库:二、JavaSwing:com.ynavc.Beancom.ynavc.Controllercom.ynavc.Daocom.ynavc.Testcom.ynavc.Vive文档说明:一、语言和环境A、实现语言Java(SWING+JDBC),MySqlB、开发环境MyEclipse9.0及以上版本,MySql5.6及…

    2022年4月10日
    91
  • Mysql数据库中的各种锁「建议收藏」

    Mysql数据库中的各种锁「建议收藏」在介绍InnoDB与MyIsam的区别时,提到了:InnoDB支持表、行(默认)级锁,而MyISAM支持表级锁本文便着重对Mysql数据库中的锁进行介绍概述相对其他数据库而言,MySQL的锁机制比较简单,其最显著的特点是不同的存储引擎支持不同的锁机制。MySQL大致可归纳为以下3种锁:表级锁:开销小,加锁快;不会出现死锁;锁定粒度大,发生锁冲突的概率最高,并发度最…

    2022年6月11日
    38

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号