dubbo使用hessian协议skywalking调用链断裂解决方案

问题: 在项目配置中skywalking的发现skywalking监控使用hessian协议的dubbo框架调用链会断裂。
原因 【dubbo使用hessian协议skywalking调用链断裂解决方案】通过查看skywalking源码发现:dubbo中的dubbo协议是消费者和生产者使用长连接进行数据传输,而hessian协议底层是通过http方式进行数据传输。dubbo协议可以通过RpcContext上下文进行隐式传参,而hessian不可以。skywalking的dubbo插件正式利用了dubbo隐式传参将traceId进行跨进程传输,才保证了调用链不会断。
解决方案: 废话不多说,直接上源码改源码。

  1. 首先看下skywalking中的dubbo插件的代码实现,如图-1所示,源码使用的是拦截dubbo中的MonitorFilter这个类中的invoke方法。具体如图2所示,通过获取dubbo的上下文RpcContext先对消费者调用之前加入sky walking的跨进程协议header信息sw:traceId,然后到生产者取出。
    dubbo使用hessian协议skywalking调用链断裂解决方案
    文章图片
    图-1.png
    dubbo使用hessian协议skywalking调用链断裂解决方案
    文章图片
    图-2.png
  2. 通过源码可以看出,插件是使用的是dubbo的上下文RpcContext进行隐式传参,可是hessian协议就是不行,不止是hessian协议,通过dubbo源码可以发现dubbo使用WebService,Rest等待协议也不行。这里我仅仅验证了hessian,解决hessian隐式传参通过查资料看hessian源码发现有两种方式:
    • 使用http头信息传参
    • hessian多序列化反序列化一个参数
  3. 这里我使用的是通过http头信息进行传参,在hessian客户端调用前在头信息中植入skywalking的sw,然后在服务端从头信息中取出sw放入dubbo的RpcContext对象中。
    • 客户端拦截hessian的HessianProxy中的addRequestHeaders方法,具体实现如图-3所示。
      dubbo使用hessian协议skywalking调用链断裂解决方案
      文章图片
      图-3
    • 服务端拦截HessianHandler中的handle方法,注意HessianHandlerHessianProtocol的私有类,得使用HessianProtocol$HessianHandler类名关联,具体实现如图-4所示。
      dubbo使用hessian协议skywalking调用链断裂解决方案
      文章图片
      图-4.png
结论 通过以上方式进行对hessian协议连上链路,其实dubbo其他非dubbo协议可以通过类似方式进行重新连上链路。

    推荐阅读