背景
2019年我们经历了一整年的各种迁移,其中包括了一项RPC
框架的切换。以前我们用的HSF RPC
框架,它是来自于阿里巴巴,经过了多年的双11
高并发的洗礼,高性能这块儿毫无疑问没有任何的问题,而且它还同时支持TCP
与HTTP
的方式,唯一不太好的就是它不开源,如果出现问题定位起来确实有一些问题与风险。
所以,我们为了拥抱开源,全部采用SpringCloud
,系统与系统之间调用是通过FeignClient
的方式来调用的,但是由于底层的部分系统由于时间、人力、历史等原因,无法在短时间内都像我们一样能积极响应。所以就出现了SpringCloud
与HSF服务同时存在的情况,为了大家再编码过程中都能像本地调用(TCP
,FeignClient
),所以就写了一个代理工具。
交互图
如果是上面的方式,我们还是能感受到每次都是通过HttpClient
等方式发起一次Http
请求,写代码时候的体验不是很好。
为了解决这个问题,那么我们的任务就是来写一个这个代理封装。
分析功能点
了解一下FeignClient
我们参考一下FeignClient的功能一个解析过程,如图:
- 生成动态代理类
- 解析出等的MethodHandler
- 动态生成Request
- Encoder
- 拦截器处理
- 日志处理
- 重试机制
代理需要考虑什么?
那我们不用说写那么完善,我们的第一个目标就是实现扫描 → 代理 → 发送请求。
因为HSF的参数与标准的Http方式不太一致,所以在发起Http请求的时候,需要特殊的构造一下报文的格式
1 | curl -d "ArgsTypes=[\"com.cyblogs..QueryConfigReq\"]&ArgsObjects=[{\"relationCode\":\"ABCD\"}]" |
代码框架实现
SpringBoot
总入口,打开@EnableHsfClients
注解
1 |
|
这里定义好需要扫描的包,具体的类等
1 | (RetentionPolicy.RUNTIME) |
利用Spirng
的ImportBeanDefinitionRegistrar
来进行自动注入生成Bean。
1 | public class HsfClientsRegistrar implements ImportBeanDefinitionRegistrar, ResourceLoaderAware, BeanClassLoaderAware { |
HsfClientFactoryBean
定义
1 |
|
代理类的实现
1 | public class HsfInvocationHandler implements InvocationHandler { |
最后就是就是HsfMethodHandler
的一个具体实现,包括上面所提到的Request
参数的构造,一个invoke
方法的调用。
总结
- 其实通过HttpClient的方式去调用也不是不行,只是说如果通过参考别人的代码,做一个RPC调用底层原理的一个分析,我们是可以做到一些系统层面的封装的,而且这个jar包是可以做成plugin的方式去提供给别人用的。
- 了解动态代理的原理,可以做到对代码项目无感知或者少感知的作用。
- 通过该过程举一反三,其他的场景都可以复制该思路去做事情。
如果大家喜欢我的文章,可以关注个人订阅号。欢迎随时留言、交流。如果想加入微信群的话一起讨论的话,请加管理员简栈文化-小助手(lastpass4u),他会拉你们进群。