Hmily 源码解析(二)—— 调用微服务

Hmily 源码解析(二)—— 调用微服务由于篇幅过长,将该模块单独拎出一节,接上文Hmily源码解析(二)——执行主体方法上文我们把主体方法的执行及Feign的相关配置讲解了,知道在调用微服务时把对应的HmilyTransactionContext实例以“HMILY_TRANSACTION_CONTEXT”为key作为请求参数一同发送过来,及调用微服务成功之后会把调用接口的方法(有@Hmily注解的)封装为HmilyPa…

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


  • 上文我们把主体方法的执行及Feign的相关配置讲解了,知道在调用微服务时把对应的HmilyTransactionContext实例以“HMILY_TRANSACTION_CONTEXT”为key作为请求参数一同发送过来,及调用微服务成功之后会把调用接口的方法(有@Hmily注解的)封装为HmilyParticipant实例异步存储到存储到HmilyTransaction实例中。

  • 现在接着讲在库存微服务接收到请求后会如何执行请求并做了哪些操作。

  • 如下请求调用一开就需要先进入Hmily切面程序

在这里插入图片描述
在这里插入图片描述

  • 根据前文,前面的类不再重复介绍,现在执行到了interceptor方法,首先这个请求刚开始,这个线程内还未存在HmilyTransactionContext实例。所以到下面这个else模块,这里很重要,我们记得前面在请求头里面有存在“HMILY_TRANSACTION_CONTEXT”为key的HmilyTransactionContext实例信息,现在就从这里取出来了。致此我们了解了微服务间是如何实现关于事务信息的通信。

在这里插入图片描述

  • 我们现在来看一下factoryof方法里面是如何选择处理类的,传过来的角色为发起者(HmilyRoleEnum.START)所以选择了ParticipantHmilyTransactionHandler去执行后续操作。

在这里插入图片描述

  • 目前我们的状态是TRYING 所以我们目前只要关注红色框内的代码即可

在这里插入图片描述

  • 先看一下preTryParticipant内做了什么,首先新建了一个HmilyTransaction实例,这个实例是存储在hmily_inventory_service表中的,和前一个HmilyTransaction实例不是同一个实例了。
  • buildHmilyTransaction函数前面讲过,根据参数的不同,新建的这个HmilyTransaction实例的角色为提供者(PROVIDER),transId为传入的transId,运行状态为开始执行try阶段(PRE_TRY),其它的类信息,HmilyParticipant实例信息是从本次切面对象(decrease函数及对应的Hmily注解信息)上获取的。目前HmilyParticipant只有decrease函数本身。
  • 将生成的HmilyTransaction实例存储到缓存里(缓存和线程就无关了,而是以transId为key存储,只要在有效时间内都能获取得到),及异步保存到hmily_inventory_service表中。
  • HmilyTransactionContext将角色改为本地调用( LOCAL),又一个角色状态现在被使用了!而且HmilyTransaction实例并没有一起被修改,而微服务的调用者的角色状态也仍是发起者(START),大体可以猜测本地调用( LOCAL)可能是个中间状态,在这次使用完之后就会丢弃。
  • 然后HmilyTransactionContext绑定到本地线程。

在这里插入图片描述
在这里插入图片描述

  • preTry之后第一步执行主体方法,主体方法内部非常简单,就是一条数据库操作就不再述了,接着如果执行主体方法成功没问题,则修改执行状态为try完成(TRYING),并异步保存到数据库中。如果执行失败报出异常则发起请求异步删除hmilyTransaction实例,并向上继续抛出异常(抛给微服务调用者),再往下finally里就是线程结束时的收尾工作,不再复述了。

在这里插入图片描述

  • 微服务的try阶段就完成了,之前说的本地调用( LOCAL)状态好像没用到,的确demo里没有覆盖这么全面,没有案例我也先不去分析了。

  • 我们可以再简单介绍一下CONFIRMING,与CANCELING的情况,当微服务第二次接收到请求时,状态就会变成CONFIRMING或者CANCELING。

  • 首先他们的第一步都是通过transId从缓存中获取HmilyTransaction实例。

    • 为什么要这样做,不直接从数据库获取HmilyTransaction实例?我猜测是这样的,上文异步保存HmilyTransaction实例到数据库与第二次请求的时间之间谁快谁慢这是说不准的,有可能第二次请求已经来了,但是数据库中还未保存HmilyTransaction实例,如果这时候去数据库中去可能就会返回null。在缓存中存储一个HmilyTransaction实例就可以解决这个问题,如果第二次请求更快则直接取缓存数据,反之第二次请求由于某些原因特别慢导致缓存已经失效了,但是这时间足以保证HmilyTransaction实例保存到数据中,这时依然能够通过HmilyTransactionGuavaCacheManager从数据库中获取该实例(见GuavaCache的获取机制)。
  • 接着就是根据HmilyTransaction实例执行对应confirm方法或cancel方法。

在这里插入图片描述

  • 我们看一下confirm方法做了什么,cancel方法类似就不分析了
  • 1.修改状态为CONFIRM阶段(CONFIRMING)
  • 2.前文说了,hmilyParticipant实例只有一个就是decrease函数本身,如何通过反射调用Hmily注解里面配置的confirm方法(confirmMethod)。如果有执行失败的hmilyParticipant会存储在failList集合里面。
  • 3.,然后执行executeHandler函数,如下二图,成功删除相应的HmilyTransaction实例信息,如果有失败案例,则异步修改HmilyTransaction实例的hmilyParticipants集合(只保留执行失败的hmilyParticipant集合),后面定时器会再根据日志去定时执行这些hmilyParticipants集合,直到所有的hmilyParticipant被正确处理,或超过执行重试次数报个管理员手工处理。关于定时器重试执行的内容这边先按下不表。
  • 对于这个demo的情况就是,hmilyParticipants集合里只有一个hmilyParticipant实例,如果confirm失败了,就通过定时器不停的重试执行,cancel失败如是,直到超过最大重试次数。

在这里插入图片描述

在这里插入图片描述

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

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/143269.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • java二维数组初始化的三种方式「建议收藏」

    java二维数组初始化的三种方式「建议收藏」有些知识觉得很简单,但其中一些细节性的东西我们未必知道,比如说数组的定义以及初始化的方式。下面主要介绍下二位数组初始化的三种方式1、定义数组的同时使用大括号直接赋值,适合数组元素已知的情况2、定义二维数组的大小,然后分别赋值3、数组第二维的长度可变化//第一种方式:定义的同时大括号直接复制int[][]array1={{1,3,1},{…

  • 更新kali源「建议收藏」

    更新kali源「建议收藏」新安装的kali系统,在进行软件下载升级的时候会使用kali官方源去下载,在国内访问会比较慢,更换为国内源后,会提升下载速度。1、打开kali源文件sudovim/etc/apt/sources.list

  • C#后台调用前台javascript的五种方法

    C#后台调用前台javascript的五种方法

  • redis一级缓存和二级缓存_面试官让面试者先回去

    redis一级缓存和二级缓存_面试官让面试者先回去说起mybatis,大家可能都知道它是一个优秀的久层框架,它支持定制化SQL、存储过程以及高级映射。面试中都会问起mybatis一级缓存和二级缓存,它体现出你对mybatis这个开发中的理解,如果照着答案背的话只能拿到一个及格分,所以今天咱们就好好聊聊mybatis。另外本人整理了20年面试题大全,包含spring、并发、数据库、Redis、分布式、dubbo、JVM、微服务等方面总结,下图是部分截图,需要的话点这里点这里,暗号CSDN。1.首先,什么是Mybatis?MyBatis是一.

  • freemarker中的round、floor和ceiling数字的舍入处理

    freemarker中的round、floor和ceiling数字的舍入处理

    2021年11月15日
  • pytest指定用例_ppt怎么设置自定义放映顺序

    pytest指定用例_ppt怎么设置自定义放映顺序前言测试用例在设计的时候,我们一般要求不要有先后顺序,用例是可以打乱了执行的,这样才能达到测试的效果.有些同学在写用例的时候,用例写了先后顺序,有先后顺序后,后面还会有新的问题(如:上个用例返回

发表回复

您的电子邮箱地址不会被公开。

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