dubbo使用hessian协议skywalking调用链断裂解决方案
问题:
在项目配置中skywalking的发现skywalking监控使用hessian协议的dubbo框架调用链会断裂。
原因
【dubbo使用hessian协议skywalking调用链断裂解决方案】通过查看skywalking源码发现:dubbo中的dubbo协议是消费者和生产者使用长连接进行数据传输,而hessian协议底层是通过http方式进行数据传输。dubbo协议可以通过RpcContext
上下文进行隐式传参,而hessian不可以。skywalking的dubbo插件正式利用了dubbo隐式传参将traceId进行跨进程传输,才保证了调用链不会断。
解决方案:
废话不多说,直接上源码改源码。
- 首先看下skywalking中的dubbo插件的代码实现,如图-1所示,源码使用的是拦截dubbo中的
MonitorFilter
这个类中的invoke
方法。具体如图2所示,通过获取dubbo的上下文RpcContext
先对消费者调用之前加入sky walking的跨进程协议header信息sw:traceId
,然后到生产者取出。
文章图片
图-1.png
文章图片
图-2.png - 通过源码可以看出,插件是使用的是dubbo的上下文
RpcContext
进行隐式传参,可是hessian协议就是不行,不止是hessian协议,通过dubbo源码可以发现dubbo使用WebService,Rest等待协议也不行。这里我仅仅验证了hessian,解决hessian隐式传参通过查资料看hessian源码发现有两种方式:- 使用http头信息传参
- hessian多序列化反序列化一个参数
- 这里我使用的是通过http头信息进行传参,在hessian客户端调用前在头信息中植入skywalking的
sw
,然后在服务端从头信息中取出sw
放入dubbo的RpcContext
对象中。- 客户端拦截hessian的
HessianProxy
中的addRequestHeaders
方法,具体实现如图-3所示。
文章图片
图-3 - 服务端拦截
HessianHandler
中的handle
方法,注意HessianHandler
是HessianProtocol
的私有类,得使用HessianProtocol$HessianHandler
类名关联,具体实现如图-4所示。
文章图片
图-4.png
- 客户端拦截hessian的
推荐阅读
- 由浅入深理解AOP
- 【译】20个更有效地使用谷歌搜索的技巧
- mybatisplus如何在xml的连表查询中使用queryWrapper
- MybatisPlus|MybatisPlus LambdaQueryWrapper使用int默认值的坑及解决
- MybatisPlus使用queryWrapper如何实现复杂查询
- dubbo基本认识
- iOS中的Block
- Linux下面如何查看tomcat已经使用多少线程
- 使用composer自动加载类文件
- android|android studio中ndk的使用