java agent实现dubbo灰度发布DEMO

核心代码DEMO,仅供参考:

package com.zcm.transform.premain;

import javassist.*;

import java.io.File;
import java.io.IOException;
import java.lang.instrument.ClassFileTransformer;
import java.lang.instrument.IllegalClassFormatException;
import java.lang.instrument.Instrumentation;
import java.net.URISyntaxException;
import java.net.URL;
import java.security.ProtectionDomain;
import java.util.*;
import java.util.jar.JarFile;

/**
 * 检测方法的执行时间
 *
 * @author 周cm
 * @myblog xx
 * @create 2018年4月21日
 */
public class DubboTransformer extends BaseTransformer implements ClassFileTransformer {

    final static String prefix = "\nlong startTime = System.currentTimeMillis();\n";
    final static String postfix = "\nlong endTime = System.currentTimeMillis();\n";

    // 被处理的方法列表
    final static Map<String, List<String>> methodMap = new HashMap<String, List<String>>();

    static boolean hasIn = false;

    ClassLoader dubboTransformClassLoader;


    String agentOps;
    Instrumentation inst;

    public DubboTransformer() {
        add("com.zcm.service.impl.IDogImpl",ROUTER);
        add("com.alibaba.dubbo.config.ReferenceConfig", ROUTER);
        add("com.alibaba.dubbo.config.ApplicationConfig", ROUTER);
        //add("com.alibaba.dubbo.config.ConsumerConfig", ROUTER);
        add("com.alibaba.dubbo.config.ServiceConfig", DYNAMIC_GROUP);
        dubboTransformClassLoader = DubboTransformer.class.getClassLoader();

    }

    public DubboTransformer(String agentOps, Instrumentation inst){

        this();
        this.agentOps = agentOps;
        this.inst = inst;

        try {

            String filePath = "C:\\Users\\ody\\workspace\\jim-framework-master\\full-link-log\\web\\target\\web-1.2-SNAPSHOT\\WEB-INF\\lib\\dubbo-2.6.0.jar";
            String filePath1 = "C:\\Users\\ody\\workspace\\jim-framework-master\\full-link-log\\web\\target\\web-1.2-SNAPSHOT\\WEB-INF\\lib\\javassist-3.20.0-GA.jar";
            JarFile jarFile = new JarFile(filePath);
            //inst.appendToBootstrapClassLoaderSearch(jarFile);
            //inst.appendToSystemClassLoaderSearch(jarFile);
            //inst.appendToSystemClassLoaderSearch(new JarFile(filePath1));
            //SimpleLoadAJar.addJar(filePath);
            //SimpleLoadAJar.addJar(filePath1);
        } catch (IOException e) {
            e.printStackTrace();
        }catch (Exception e){
            e.printStackTrace();
        }

    }

    private void add(String clazzString,String method) {

        methodMap.put(clazzString, Arrays.asList(method));

    }


    public static final String DYNAMIC_GROUP = "dynamicGroup";
    public static final String ROUTER = "router";


    @Override
    public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined,
                            ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {
        className = className.replace("/", ".");
        if (methodMap.containsKey(className)) {// 判断加载的class的包路径是不是需要监控的类
            CtClass ctclass = null;

            ensureAdditionalJar( loader);
            try {
                ctclass = ClassPool.getDefault().get(className);// 使用全称,用于取得字节码类<使用javassist>
                List<String> methods = methodMap.get(className);


                if (methods != null){
                    for (String method : methods){
                        addAdditionMethod(ctclass,method,method);
                    }
                }


                return ctclass.toBytecode();
            } catch (Exception e) {
                System.out.println(e.getMessage());
                e.printStackTrace();
            }
        }
        return null;
    }

    private void ensureAdditionalJar( ClassLoader classLoader) {



        if ( !hasIn ){

            hasIn = true;
        }else {
            return ;
        }

        if (classLoader == dubboTransformClassLoader){

            return;
        }

        for (String className : Arrays.asList("com/alibaba/dubbo/config/ApplicationConfig.class","javassist/ClassPool.class")){


            URL url = classLoader.getResource(className);

            if ( url == null){

                System.err.println(" can not found dubbo.jar in " + classLoader);

                continue;
            }


            System.out.println(url);


            inst.appendToSystemClassLoaderSearch(convertUrl2jarFile(url));

        }



    }

    private JarFile convertUrl2jarFile(URL url) {

        String filePath = url.getPath();

        try {

            int index = filePath.indexOf("!");

            if (index > -1){

                filePath = filePath.substring(5,index);

                return new JarFile(filePath);
            }

            File file = new File( url.toURI());
            System.out.println("..");
        } catch (URISyntaxException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;

    }


    private CtClass addAdditionMethod(CtClass ctClass , String methodKey , String systemPropertyKey){


        String methodName = "get" + methodKey.substring(0,1).toUpperCase() + methodKey.substring(1);

        CtMethod method = null;


        try {

            CtMethod ctmethod = ctClass.getDeclaredMethod(methodName);
            if (ctmethod != null){

                System.err.println(ctClass + " has got " + method);
                return ctClass ;
            }

        }catch (Exception e){

            // no method
        }



        try {

            method = new CtMethod(ClassPool.getDefault().get("java.lang.String"), methodName, new CtClass[]{}, ctClass);
            method.setModifiers(Modifier.PUBLIC);
            String methodContent  = "{return System.getProperty(\"" + systemPropertyKey + "\");}";
            //methodContent  = "{return System.getProperty(\"hah\");}";
            method.setBody(methodContent);
            ctClass.addMethod(method);


        }catch (Exception e){

            System.err.println(" agent dynamic add method error");
            e.printStackTrace();

        }


        return ctClass;

    }
}

猜你喜欢

转载自jdkleo.iteye.com/blog/2420095