IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> skywalking源码分析第二十一篇一agent端实战之dubbo插件 -> 正文阅读

[Java知识库]skywalking源码分析第二十一篇一agent端实战之dubbo插件

源码分析一插件定义

  • 拦截MonitorFilter.invoke
  • 消费端执行MonitorFilter前已经完成mock,cluster,loadbalance等功能
  • 提供者端执行MonitorFilter万后执行dubboInvoker内部的相关业务接口逻辑
public class DubboInstrumentation extends ClassInstanceMethodsEnhancePluginDefine {

    private static final String ENHANCE_CLASS = "org.apache.dubbo.monitor.support.MonitorFilter";

    private static final String INTERCEPT_CLASS = "org.apache.skywalking.apm.plugin.asf.dubbo.DubboInterceptor";

    @Override
    protected ClassMatch enhanceClass() {
        return NameMatch.byName(ENHANCE_CLASS);
    }

    @Override
    public ConstructorInterceptPoint[] getConstructorsInterceptPoints() {
        return null;
    }

    @Override
    public InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
        return new InstanceMethodsInterceptPoint[] {
            new InstanceMethodsInterceptPoint() {
                @Override
                public ElementMatcher<MethodDescription> getMethodsMatcher() {
                    return named("invoke");
                }

                @Override
                public String getMethodsInterceptor() {
                    return INTERCEPT_CLASS;
                }

                @Override
                public boolean isOverrideArgs() {
                    return false;
                }
            }
        };
    }
}

源码分析一拦截器

  • beforeMethod作为消费者createExitSpan,并将ContextCarrier追加到rpc消息上下文的附件中
  • beforeMethod提供者 createEntrySpan并将rpc消息上下文的附件的ContextCarrier提取出来,反序列化注入到当前的TracerContext
  • afterMethod作为提供者会将当前TraceContext栈中的span加入Segment并上报OAP
  • afterMethod作为消费者会将当前TraceContext栈中的span加入Segment

public class DubboInterceptor implements InstanceMethodsAroundInterceptor {
    @Override
    public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments,
        Class<?>[] argumentsTypes, MethodInterceptResult result) throws Throwable {
        Invoker invoker = (Invoker)allArguments[0];
        Invocation invocation = (Invocation)allArguments[1];
        RpcContext rpcContext = RpcContext.getContext();
        boolean isConsumer = rpcContext.isConsumerSide();
        URL requestURL = invoker.getUrl();
        AbstractSpan span;

        final String host = requestURL.getHost();
        final int port = requestURL.getPort();
        if (isConsumer) {
            将tracerContext序列化到ContextCarrier,然后传递给下一个进程
            final ContextCarrier contextCarrier = new ContextCarrier();
            span = ContextManager.createExitSpan(generateOperationName(requestURL, invocation), contextCarrier, host + ":" + port);
            CarrierItem next = contextCarrier.items();
            while (next.hasNext()) {
                next = next.next();
                通过dubbo的附件传递当前ContextCarrier 
                rpcContext.getAttachments().put(next.getHeadKey(), next.getHeadValue());
            }
        } else {
            ContextCarrier contextCarrier = new ContextCarrier();
            CarrierItem next = contextCarrier.items();
            将消费者注入Attachment附件中的ContextCarrier提取出来
            while (next.hasNext()) {
                next = next.next();
                next.setHeadValue(rpcContext.getAttachment(next.getHeadKey()));
            }
            将contextCarrier解析到当前TracerContext
            span = ContextManager.createEntrySpan(generateOperationName(requestURL, invocation), contextCarrier);
        }
        为当前span打上一些kv键值对
        Tags.URL.set(span, generateRequestURL(requestURL, invocation));
        span.setComponent(ComponentsDefine.DUBBO);
        SpanLayer.asRPCFramework(span);
    }

    @Override
    public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments,
        Class<?>[] argumentsTypes, Object ret) throws Throwable {
        Result result = (Result)ret;
        if (result != null && result.getException() != null) {
            span中记录异常kv键值对
            dealException(result.getException());
        }
        离开时将Span加入Segment,dubbo Provider一般是EntrySpan此时需要上报OAP consumer端一般是ExitSpan,此时activeSpanStack还存在span不进行上报
        ContextManager.stopSpan();
        return ret;
    }

    private String generateOperationName(URL requestURL, Invocation invocation) {
        operationName 就是span的端口名称 dubbo的span名称是接口签名
        比如com.renxl.DemoService.sayHello(String);
        StringBuilder operationName = new StringBuilder();
        接口名处理
        operationName.append(requestURL.getPath());
        方法名处理
        operationName.append("." + invocation.getMethodName() + "(");
        参数处理
        for (Class<?> classes : invocation.getParameterTypes()) {
            operationName.append(classes.getSimpleName() + ",");
        }
        删除最后一个,if (invocation.getParameterTypes().length > 0) {
            operationName.delete(operationName.length() - 1, operationName.length());
        }
        operationName.append(")");
        return operationName.toString();
    }
}

总结

  • 跨进程基于ContextCarrier进行TracerContext的序列化和饭序列化
  • ContextCarrier放置于插件拦截的中间件当前的请求对象上
  • 比如MQ的requestHeader.properties
  • 比如dubbo的rpcContext.attachments
  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-03-11 21:59:56  更:2022-03-11 22:00:50 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 10:45:53-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码