Review the directory

  • The business scenario | synchronous implementation: kill Redis in seconds kill function of practice
  • Design patterns | a word understand design patterns
  • Apache SkyWalking | SkyWalking advanced play
  • Apache SkyWalking | SkyWalking Java plug-in contribution to practice
  • A distributed job scheduling | HOME LINK distributed operation platform (recommended)

takeaway

  • SkyWalking is a non-invasive APM(Application Performance Monitor) system implemented by Byte Buddy, one of the two large bytecode operating tools based on JavaAgent. Currently, the project is in Apache incubator. Those interested in the source code of SkyWalking and Byte Buddy can go to the official resources at the bottom of this article.
  • This article will have implemented the application component SpringMVC through Byte Buddy record request path, input parameters, execution time javAgent project, continuous iteration javaAgent project methodology, SkyWalking Agent has four chapters on how to continuously debug the plug-in code of the project and the development practice of SkyWalking plug-in, so that everyone can master the gameplay of SkyWalking, and then make the secondary development of SkyWalking in their own company easy to reach.

Byte Buddy implementation

  • First of all, if you are not very familiar with JavaAgent you can first baidu, or look at the public number “JavaAgent principle and practice” simple introduction. The key method for SpringMVC to distribute requests will not need to be described, so let’s start with the code.
  • Write Byte Buddy JavaAgent code
 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); }}Copy the code
  • Write DispatcherServlet doDispatch interceptor code
public class DoDispatchInterceptor { @RuntimeType public static Object intercept(@Argument(0) HttpServletRequest request, @SuperCall Callable<? > callable) { final StringBuilderin = 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() + "The ginseng." + in + "Take."+ (System.currentTimeMillis() - agentStart)); }}}Copy the code
  • Add agent description file resources.meta-inf.manifest.mf
The Manifest - Version: 1.0 Premain - Class: com. Z.t est. Agent. AgentMain Can Redefine - Classes:true
Copy the code
  • Pom. The XML file
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
Copy the code
  • In short, I realized the application component SpringMVC with Byte Buddy to record the request path, input parameter, execution time and javAgent project.

Iterate over javaAgent continuously

  • This summary focuses on javaagen debugging and continuous integration.
  • First, my JavajAgent project directory structure looks like this:
  • The application project is a SpringBootWeb project implemented with a few lines of code:
@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"; }}}Copy the code
  • Here’s how key JavaAgent projects continue to iterate and integrate:
VM options增加:-javaagent:/Users/zhao/Code/github/z_my_test/test-agent/target/test-agent-1.0-snapshot. jar=aaaaa Before launch Before Build add:  Working directory:/Users/zhao/Code/github/incubator-skywalking Command line:-T 1C -pltest-agent -am clean package -Denforcer.skip=true -Dmaven.test.skip=true -Dmaven.compile.fork=true
Copy the code
  • See picture for detailed configuration:
  • Summary: see here javaAgent continuous iterative integration, is not immediately feel my hand has itching, would like to talk about a own agent code, etc. There is also a good news :test-demo 10 lines of code to achieve the Web service has 5K classes can use agent enhancement. According to the 80/20 rule, the average programmer is familiar with at least 1K classes. Why not pick a familiar class to challenge?
  • Note that the MVN compiler acceleration command is not supported until maven3+.

SkyWalking Debug

  • In fact, through the matting above, I think you have more or less already know how I want to say how SkyWalking and Debug. So HERE I mainly talk about a few points can be optimized, to avoid people think there is no new, to sell in advance, my integration time optimization to 30 seconds or so:
VM options: - javaagent: - javaagent: / Users/zhao/Code/lot/incubator - skywalking/skywalking - agent/skywalking - agent. The jar: Do not use skywalk-agent. jar (dist) Before launch.  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=trueMaven-checkstyle-plugin is also a root POM annotation to speed up compilationCopy the code
  • Javaagent project to debug, also need to put the Agent code and access agent project at least in the same workspace, there are many online methods, here I recommend you a simple method. File->New->Module from Exisiting Sources… Introduce skywalk-agent source code can be

Kob’s SkyWalking plug-in

  • Kob (Shell distributed Job Scheduling Framework) is the basic component of shell housing project micro-service cluster. By writing the SkyWalking plug-in of shell distributed job scheduling framework, the execution link information of job scheduling tasks can be collected in real time, so as to obtain the stability of the basic component in time. For details, see introduction to shell Distributed Scheduling Framework. To learn more about SkyWalking plug-in writing, go to the official resources at the bottom of this article.
  • Apm-sdk-plugin POM.xml adds its own plug-in model
<artifactId>apm-sdk-plugin</artifactId>
    <modules>
        <module>kob-plugin</module>
        ...
    <modules>
Copy the code
  • Resources.skywalking -plugin.def adds your own description
kob=org.apache.skywalking.apm.plugin.kob.KobInstrumentation
Copy the code
  • Writing method 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; }}}; }}Copy the code
  • The custom Interceptor implements span creation
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();returnret; } @Override public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments, Class<? >[] argumentsTypes, Throwable t) { } }Copy the code
  • To achieve the effect, change the operation name into task execution node + task execution method, realize koB’s SkyWalking plug-in writing, plus the alarm system, can further increase the stability of the company’s basic components.

Refer to the link

  • Apache SkyWalking (an APM System) github.com/apache/incu…
  • Byte Buddy (Runtime Code Generation for the Java Virtual Machine) github.com/raphw/byte-…