前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >『互联网架构』dubbo 调用埋点(114)

『互联网架构』dubbo 调用埋点(114)

作者头像
IT架构圈
发布2019-07-22 16:32:18
5370
发布2019-07-22 16:32:18
举报
文章被收录于专栏:IT架构圈IT架构圈

上边几次都是说的单体的拦截埋点,应用的内部进行的,很多的情况系统都是分布式的,怎么去监听RPC(远程过程调用),dubbo,RMI,springcloud,http。只要远程调用,跨进程调用都属于RPC,也不可能所有的能都涉及到,很多公司都有自己的封装,例如阿里的HFS,这次只针对dubbo这种RPC进行调用。源码:https://github.com/limingios/netFuture/tree/master/源码/『互联网架构』调⽤链系统工程结构(111)

(一)Dubbo执行过程

对于dubbo的埋点,首先要了解dubbo的执行过程

节点

角色说明

Provider

暴露服务的服务提供方

Consumer

调用远程服务的服务消费方

Registry

服务注册与发现的注册中心

Monitor

统计服务的调用次数和调用时间的监控中心

Container

服务运行容器

  • Dubbo调用过程
  • 消费者调用过程
(二)调用端埋点实现
  • 埋点目的 1.捕捉消费者调用信息(远程接口、URL、参数、用时、返回结果、异常) 2.传递TraceRequest
  • 调用信息模型表结构

名称

类型

描述

servicePath

string

服务路径

serviceName

string

服务

inParam

json

返回结果

outParam

json

返回结果

ErrorMessage

string

异常信息

ErrorStack

text

异常堆栈

ResultState

string

执行状态

beginTime

date

开始时间

endTime

date

结束时间

addressIp

string

远程IP

fromIp

string

调用者IP

埋点位置

如何才能完整的捕捉到以上信息呢?那么就需要了解Dubbo内部的调用 1.分解调用过程为多个步骤。2.这些步骤分别是在哪些协作线程上完成的?3.经过了哪些方法?4.经过了哪些过滤器?

调用过程分解&线程协作

  • 埋点位置

如何才能完整的捕捉到以上信息呢?那么就需要了解Dubbo内部的调用 1.分解调用过程为多个步骤。2.这些步骤分别是在哪些协作线程上完成的?3.经过了哪些方法?4.经过了哪些过滤器?

  • 调用过程分解&线程协作

  1. 选择断点位置Debug调试调用过程
  2. 消费者调用线程源码分析:
  • 经过对源码的分析,埋点的位置如下: DubboInvoker.doInvoke() FutureFilter.invoke() DubboInvoker.doInvoke() 方法最靠近调用方,异常捕捉范围较大,但是该位置无法通过Attachment 向下传递TraceRequest 参数,所以需要FutureFilter.invoke() 进行补充,其具体分工如下:·1.DubboInvoker.doInvoke捕获如下信息:1、开始时间 2、服务路径 3、服务方法 4、输入参数 5、异常信息 6、本地地址 2.FutureFilter.invoke 基于Attachment 向下传递参数 2、异常信息与堆栈 3、返回结果

DubboInvoker.doInvoke拦截源码参见 :com.cbt.agent.collects.dubbo.DubboConsumerRpcExceptionMonitorHandle#invokerBefore FutureFilter.invoke拦截源码参见 :com.cbt.agent.collects.dubbo.DubboConsumerMonitorHandle#invokerBefore

(三)调用端埋点实现
  • 埋点目的 接收TraceRequest信息 ,并创建会话
  • 埋点位置:相对调用广方接收方埋点目的较简单,但同样需分析源码找准埋点位置
  • 提供者处理线程分析

经分析埋点位置选在离实际调用方法较远的EchoFilter过滤器理由是捕捉的信息更全面。

具体会话开启过程:

  1. 基于Attachment获取TraceId、ParentId、TraceProperties。
  2. 封装TraceRequest ,并此为参数开启会话。
  3. 在调用结束时关闭会话。具体源码参见:com.cbt.agent.collects.dubbo.DubboProviderMonitorHandle#invokerBefore
(二)Servlet处理埋点
  • Servlet埋点目的 1.生成TraceId 2.开启关闭监控会话 3.捕捉Http请求(url、客户端IP、参数、响应时长、响应状态码)
  • 埋点埋在哪?1.每一个Control方法 2.DispatcherServlet.doDispatch方法 3.HttpServlet.service 方法
  • 方案对比

方案

优点

缺点

应用层Control类

简单,风险因素低

判别成本高,有局限性,只能根据 HttpServlet 子类或@RequestMapping进行识别。

DispatcherServlet.doDispatch

简单,适应性强

1、只能针对spring mvc 项目 2、spring boot 项目不支持

HttpServlet.service

适应性强,与应用层和框架无关

1、不同的容器ClassPath不一样,存在兼容性问题。2、存在风险,几乎所有请求都会经过此方法 3、业务异常无法捕获

总合比较还是选择 HttpServlet.service 会更好些。

  • HttpServlet.service 埋点需要做的工作:1.字节码插桩 2.请求拦截并获取请求信息
  • 字节码插桩流程

字节码插是指在数据装载前在HttpServlet.service 插入监控指令,以拦截Http请求,其插桩的过程。

请求拦截是指具体Http请求过来时进行拦截过滤,这么做主要是为了完成两个目的

1.开启监控会话 2.开启对Servlet响应过程的监控

(三)Redis 调用埋点
  • 埋点可选方案

方案

优点

缺点

埋点jedis 类Get、Set等API方法

简单直接

工作量大,方法较多、需要了解每个方法特性

埋点 Connection sendCommand方法

全面、所有命令都会经过此方法

存在未知风险、不方便计算执行时间、和返回结果

埋点 Protocol

全面、所有命令都会经过此方法

存在未知风险、不方便计算执行时间、和返回结果

PS:源码中可以查看DevelopBootMain类,我看这代码也看了2天,原来老写业务代码,看看这确实很容易懵X,确实这才是有技术含量的代码。其实有没有技术含量不太重要,重要是的有没有商业价值。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-07-19,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 编程坑太多 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • (一)Dubbo执行过程
  • (二)调用端埋点实现
  • (三)调用端埋点实现
  • (二)Servlet处理埋点
  • (三)Redis 调用埋点
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档