SkyWalking之高级玩法

栏目: Java · 发布时间: 5年前

  • SkyWalking是基于javaagent的两大字节码操作 工具 之一的Byte Buddy实现的无侵入APM(application performance monitor) 系统,目前项目在Apache孵化器中,想了解SkyWalking和Byte Buddy源码的同学可在文章底部参考链接中,跳转至对应的官方资源。
  • 本文会已通过Byte Buddy实现应用组件SpringMVC记录请求路径、入参、执行时间的javagent项目、持续迭代javaagent项目的方法论、SkyWalking agent在项目如何持续debug插件代码、以及SkyWalking插件开发实践的四个章节,让大家掌握SkyWalking的玩法,进而让SkyWalking在自己公司中的二次开发变得触手可及。

Byte Buddy实现

  • 首先如果你对javaagent还不是很了解可以先百度一下,或在公众号内看下《JavaAgent原理与实践》简单入门下。SpringMVC分发请求的关键方法相信已经不用我在赘述了,让我们代码代码一把唆吧。
  • 编写Byte Buddy javaagent代码
public class AgentMain {
    public static void premain(String agentOps, Instrumentation instrumentation) {
        new AgentBuilder.Default()
                .type(ElementMatchers.named("org.springframework.web.servlet.DispatcherServlet"))
                .transform((builder, type, classLoader, module) ->
                        builder.method(ElementMatchers.named("doDispatch"))
                                .intercept(MethodDelegation.to(DoDispatchInterceptor.class)))
                .installOn(instrumentation);
    }
}
复制代码
  • 编写DispatcherServlet doDispatch拦截器代码(是不是跟AOP如出一辙)
public class DoDispatchInterceptor {
    @RuntimeType
    public static Object intercept(@Argument(0) HttpServletRequest request, @SuperCall Callable<?> callable) {
        final StringBuilder in = new StringBuilder();
        if (request.getParameterMap() != null && request.getParameterMap().size() > 0) {
            request.getParameterMap().keySet().forEach(key -> in.append("key=" + key + "_value=" + request.getParameter(key) + ","));
        }
        long agentStart = System.currentTimeMillis();
        try {
            return callable.call();
        } catch (Exception e) {
            System.out.println("Exception :" + e.getMessage());
            return null;
        } finally {
            System.out.println("path:" + request.getRequestURI() + " 入参:" + in + " 耗时:" + (System.currentTimeMillis() - agentStart));
        }
    }
}
复制代码
  • 增加agent描述文件resources.META-INF.MANIFEST.MF
Manifest-Version: 1.0
Premain-Class: com.z.test.agent.AgentMain
Can-Redefine-Classes: true
复制代码
  • pom.xml文件
dependencies
    +net.bytebuddy.byte-buddy 
    +javax.servlet.javax.servlet-api *scope=provided
plugins
    +maven-jar-plugin *manifestFile=src/main/resources/META-INF/MANIFEST.MF
    +maven-shade-plugin *include:net.bytebuddy:byte-buddy:jar:
    +maven-compiler-plugin
复制代码
  • 小结:没几十行代码就完成了通过Byte Buddy实现应用组件SpringMVC记录请求路径、入参、执行时间javagent项目,是不是觉得自己很优秀。

持续迭代javaagent

  • 本小结主要介绍javaagen如何debug,以及持续集成。
  • 首先我的javajagent项目目录结构如图所示:
    SkyWalking之高级玩法
  • 应用项目是用几行代码实现的SpringBootWeb项目:
@SpringBootApplication(scanBasePackages = {"com"})
public class TestBootWeb {
    public static void main(String[] args) {
        SpringApplication.run(TestBootWeb.class, args);
    }
    @RestController
    public class ApiController {
        @PostMapping("/ping")
        public String ping(HttpServletRequest request) {
            return "pong";
        }
    }
}

复制代码
  • 下面是关键javaagent项目如何持续迭代与集成:
VM options增加:-javaagent:/Users/zhao/Code/github/z_my_test/test-agent/target/test-agent-1.0-SNAPSHOT.jar=aaaaa
Before launch 在Build之前增加:
    Working directory:/Users/zhao/Code/github/incubator-skywalking
    Command line:-T 1C -pl test-agent -am clean package -Denforcer.skip=true -Dmaven.test.skip=true -Dmaven.compile.fork=true
复制代码
  • 详细配置见图片:
    SkyWalking之高级玩法
  • 小结:看到这里的将javaagent持续迭代集成,是不是瞬间觉得自己手心已经发痒起来,很想唆一个自己的agent代码了呢,等等还有一个好消息:test-demo这10几行的代码实现的Web服务居然有5k左右的类可以使用agent增强,根据二八原则,一般的 程序员 至少熟悉1k左右的类,还不挑一个自己熟悉的类去挑战下?
  • 注意mvn编译加速的命令是maven3+版本以上才支持的哈。

SkyWalking Debug

  • 峰回路转,到了文章的主题SkyWalking之高级玩法的正文啦,其实通过了上面的铺垫,我想大家也或多或少已经知道我要说怎么SkyWalking怎么Debug了。所以我这里主要讲几个可以优化点,避免大家觉得没有新意,提前卖个关子,我的集成时间优化到30秒左右哈:
VM options增加:-javaagent:-javaagent:/Users/zhao/Code/github/incubator-skywalking/skywalking-agent/skywalking-agent.jar:不要用dist里面的skywalking-agent.jar,具体原因大家可以看看源码^_^
Before launch 在Build之前增加:
    Working directory:/Users/zhao/Code/github/incubator-skywalking
    Command line:-T 1C -pl apm-sniffer/apm-sdk-plugin -amd clean package -Denforcer.skip=true -Dmaven.test.skip=true -Dmaven.compile.fork=true: 这里我针对插件包,因为紧接着下文要开发插件
另外根pom注释maven-checkstyle-plugin也可加速编译
复制代码
  • javaagent项目想debug,还需要将agent代码与接入agent项目至少在同一个工作空间内,网上方法有很多,这里我推荐大家一个最简单的方法。File->New->Module from Exisiting Sources...引入skywalking-agent源码即可
    SkyWalking之高级玩法

kob之SkyWalking插件编写

  • kob(贝壳分布式作业调度框架)是贝壳找房项目微服务集群中的基础组件,通过编写贝壳分布式作业调度框架的SkyWalking插件,可以实时收集作业调度任务的执行链路信息,从而及时得到基础组件的稳定性,了解细节可点击阅读《 贝壳分布式调度框架简介 》。想详细了解SkyWalking插件编写可在文章底部参考链接中,跳转至对应的官方资源,好话不多说,代码一把唆起来。
  • apm-sdk-plugin pom.xml增加自己的插件model
<artifactId>apm-sdk-plugin</artifactId>
    <modules>
        <module>kob-plugin</module>
        ...
    <modules>
复制代码
  • resources.skywalking-plugin.def增加自己的描述
kob=org.apache.skywalking.apm.plugin.kob.KobInstrumentation
复制代码
  • 编写方法instrumentation
public class KobInstrumentation extends ClassInstanceMethodsEnhancePluginDefine {
    private static final String ENHANCE_CLASS = "com.ke.kob.client.spring.core.TaskDispatcher";
    private static final String INTERCEPT_CLASS = "org.apache.skywalking.apm.plugin.kob.KobInterceptor";
    @Override
    protected ClassMatch enhanceClass() {
        return NameMatch.byName(ENHANCE_CLASS);
    }
    @Override
    protected ConstructorInterceptPoint[] getConstructorsInterceptPoints() {
        return null;
    }
    @Override
    protected InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
        return new InstanceMethodsInterceptPoint[] {
                new InstanceMethodsInterceptPoint() {
                    @Override
                    public ElementMatcher<MethodDescription> getMethodsMatcher() {
                        return named("dispatcher1");
                    }
                    @Override
                    public String getMethodsInterceptor() {
                        return INTERCEPT_CLASS;
                    }
                    @Override
                    public boolean isOverrideArgs() {
                        return false;
                    }
                }
        };
    }
}
复制代码
  • 自定义interceptor实现span的创建
public class KobInterceptor implements InstanceMethodsAroundInterceptor {
    @Override
    public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments,  Class<?>[] argumentsTypes, MethodInterceptResult result) throws Throwable {
        final ContextCarrier contextCarrier = new ContextCarrier();
        com.ke.kob.client.spring.model.TaskContext context = (TaskContext) allArguments[0];
        CarrierItem next = contextCarrier.items();
        while (next.hasNext()) {
            next = next.next();
            next.setHeadValue(JSON.toJSONString(context.getUserParam()));
        }
        AbstractSpan span = ContextManager.createEntrySpan("client:"+allArguments[1]+",task:"+context.getTaskKey(), contextCarrier);
        span.setComponent(ComponentsDefine.TRANSPORT_CLIENT);
        SpanLayer.asRPCFramework(span);
    }
    @Override
    public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes, Object ret) throws Throwable {
        ContextManager.stopSpan();
        return ret;
    }
    @Override
    public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes, Throwable t) {
    }
}
复制代码
  • 实现效果,将操作名改成任务执行节点+任务执行方法,实现kob的SkyWalking的插件编写,加上报警体系,可以进一步增加公司基础组件的稳定性。
    SkyWalking之高级玩法

参考链接


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Practical JavaScript, DOM Scripting and Ajax Projects

Practical JavaScript, DOM Scripting and Ajax Projects

Frank Zammetti / Apress / April 16, 2007 / $44.99

http://www.amazon.com/exec/obidos/tg/detail/-/1590598164/ Book Description Practical JavaScript, DOM, and Ajax Projects is ideal for web developers already experienced in JavaScript who want to ......一起来看看 《Practical JavaScript, DOM Scripting and Ajax Projects》 这本书的介绍吧!

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具