导读

  • 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 {@RuntimeTypepublic 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项目目录结构如图所示:
  • 应用项目是用几行代码实现的SpringBootWeb项目:
@SpringBootApplication(scanBasePackages = {"com"})
public class TestBootWeb {public static void main(String[] args) {SpringApplication.run(TestBootWeb.class, args);}@RestControllerpublic 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-skywalkingCommand line:-T 1C -pl test-agent -am clean package -Denforcer.skip=true -Dmaven.test.skip=true -Dmaven.compile.fork=true
复制代码
  • 详细配置见图片:
  • 小结:看到这里的将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-skywalkingCommand 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源码即可

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";@Overrideprotected ClassMatch enhanceClass() {return NameMatch.byName(ENHANCE_CLASS);}@Overrideprotected ConstructorInterceptPoint[] getConstructorsInterceptPoints() {return null;}@Overrideprotected InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {return new InstanceMethodsInterceptPoint[] {new InstanceMethodsInterceptPoint() {@Overridepublic ElementMatcher<MethodDescription> getMethodsMatcher() {return named("dispatcher1");}@Overridepublic String getMethodsInterceptor() {return INTERCEPT_CLASS;}@Overridepublic boolean isOverrideArgs() {return false;}}};}
}
复制代码
  • 自定义interceptor实现span的创建
public class KobInterceptor implements InstanceMethodsAroundInterceptor {@Overridepublic 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);}@Overridepublic Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes, Object ret) throws Throwable {ContextManager.stopSpan();return ret;}@Overridepublic void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes, Throwable t) {}
}
复制代码
  • 实现效果,将操作名改成任务执行节点+任务执行方法,实现kob的SkyWalking的插件编写,加上报警体系,可以进一步增加公司基础组件的稳定性。

参考链接

  • Apache SkyWalking(an APM system) github.com/apache/incu…
  • Byte Buddy(runtime code generation for the Java virtual machine) github.com/raphw/byte-…

SkyWalking之高级玩法相关推荐

  1. 【ASP.NET Core】依赖注入高级玩法——如何注入多个服务实现类

    依赖注入在 ASP.NET Core 中起中很重要的作用,也是一种高大上的编程思想,它的总体原则就是:俺要啥,你就给俺送啥过来.服务类型的实例转由容器自动管理,无需我们在代码中显式处理. 因此,有了依 ...

  2. 12面魔方公式图解法_【高级篇】(三)三阶魔方CFOP高级玩法之——F2L

    一.F2L这一步要干什么 1.先了解一下"棱角对"和"槽位"的概念 棱角对:即由一个棱块和一个角块构成,是F2L的基本单元(共四组) 槽位:给"棱角对 ...

  3. Vim的几个高级玩法

    文章目录 vim的几种模式 扩展命令模式命令: 命令模式高频命令: 命令模式进阶命令: vim高级玩法 小结:  在Linux中编辑文件的场景非常之多,掌握一些关键命令和技巧.能够大大提高效率,使用体 ...

  4. 涨知识!原来华为手机摄像头还有这些高级玩法,学会轻松提高工作效率

    众所周知,华为手机广受用户的喜爱,主要是因为华为手机的实用性强,并且拍照能力也是世界顶尖水平.不过你知道吗?拍照与办公融合,将解锁华为手机摄像头的高级玩法,今天笔者就分享两个,不仅有趣还非常实用的摄像 ...

  5. java enum枚举类的用法以及高级玩法

    enum(枚举)类介绍 java枚举类是一组预定义常量的集合,使用enum关键字声明这个类,常量名称官方建议大写 1.enum类基本用法 举一个常见的例子,例如星期就可以描述为一个枚举类,如下 pub ...

  6. vnc移植_【安富莱】开源原创高级玩法,用F429接SDRAM虚拟远程VNC桌面

    [安富莱]开源原创高级玩法,用F429接SDRAM虚拟远程VNC桌面说明: 0. 这个项目的可玩性极高,可以做很多有意思的应用.做一些远程智能控制尤其方便,省去了学习html,xml,js等麻烦,且无 ...

  7. 魔方cfop公式软件_【高级篇】(三)三阶魔方CFOP高级玩法之——F2L

    一.F2L这一步要干什么 1.先了解一下"棱角对"和"槽位"的概念 棱角对:即由一个棱块和一个角块构成,是F2L的基本单元(共四组) 槽位:给"棱角对 ...

  8. 魔方cfop公式软件_【高级篇】(四)三阶魔方CFOP高级玩法之——OLL

    一.OLL这一步需要做什么? OLL这一步是最容易理解的,到了这一步,前两层已经全部复原了 那不管顶面出现什么情况,都能用一个公式将顶面黄色朝向全部调整正确(顺序不管) 一步到位的代价就是--这步骤有 ...

  9. 乐高凯德机器人_酷炫到底!乐高EV3机器人+冰淇淋的高级玩法,你GET到了吗?...

    原标题:酷炫到底!乐高EV3机器人+冰淇淋的高级玩法,你GET到了吗? 你喜欢吃冰淇淋吗? 甜甜凉凉的冰淇淋圣代, 最适合炎热的夏天啦~ 我们"多才多艺"的EV3机器人, 也会做冰 ...

最新文章

  1. UVA816 Abbott的复仇 Abbott's Revenge(final的BFS)(真•答案)
  2. AJAX跨域请求数据原理与案例
  3. XML Parsing in a Producer-Consumer Model
  4. linux android build tools,build.gradle 文件中的 Android SDK Build Tools version
  5. Win8系统搜索不到无线信号该怎么办?
  6. SylixOS 缺页异常
  7. Jquery checkbox选中问题
  8. 计算机ws2_32dll丢失,电脑显示计算机中丢失ws2-32.dll,怎么办
  9. cordova 美洽_phonegap-cordova-美洽客服插件-Android
  10. 串口通信根据波特率计算定时器初值
  11. android 支付宝登录无法返回
  12. 7、mysql的redo log、bin log日志
  13. [1927-2011][影片][历届奥斯卡最佳影片合集][全82部]
  14. 浅谈Thread.setDaemon
  15. 适合穷人挣钱最快的方法
  16. 通过php执行mysql语句进行学生成绩表的增删改查
  17. 计算机控制系统期末测试,学堂在线计算机操作系统考试题及答案
  18. 电子商务计算机网络的定义,网络营销的定义概念是什么
  19. Even if you get no applause, you should accept a curtain call gracefully and app
  20. Git多人协作开发流程

热门文章

  1. 002_jQuery语法
  2. python自动化运维平台能用php开发吗_关于数据库自动化运维平台的设计及开发实现思路...
  3. pytorch 查看当前学习率_pytorch调整模型训练的学习率
  4. office2013软件安装资料及教程
  5. mysql很简单,Mysql入门很简单
  6. firewall添加白名单_firewall的规则设置与命令(白名单设置)
  7. python安装环境配置linux_linux下安装python环境
  8. php 实现心芯图案,利用php输出不同的心形图案
  9. Java高并发编程:Copy-On-Write容器
  10. Python爬虫==【openurl】