天天看點

Java Agent(上)

1、java agent是什麼?

---》對使用者透明,不侵入使用者業務代碼。讓java虛拟機加載agent jar

2、java agent有什麼用?

--->應用場景例如:調用鍊追蹤項目,在使用者無感覺的情況下,記錄日志。目前業内使用該技術的有,SkyWalking,Pinpoint(這個監控的粒度更小)

-各個 Java IDE 的調試功能,例如 eclipse、IntelliJ ;

-熱部署功能,例如 JRebel、XRebel、 spring-loaded;

-各種線上診斷工具,例如 Btrace、Greys,還有阿裡的 Arthas;

-各種性能分析工具,例如 Visual VM、JConsole 等

3、java agent的實作原理?

https://zhuanlan.zhihu.com/p/147375268

4、 入門案例

4.1、 如何制造自己第一個java agent jar包

4.1.1、 第一步:我們需要一個插件來幫助我們生成帶特定格式的MAINIFEST.MF的jar

4.1.2、 第二步:在啟動項目的時候,在jvm參數中添加 -javaagent: *\ving-agent-0.0.1-SNAPSHOT.jar (在jvm上先加載agent包)

(偷偷地問)特定格式的MAINIFEST.MF是怎樣的?需要包括下面的内容

Manifest-Version: 1.0
Can-Redefine-Classes: true
Can-Retransform-Classes: true
Premain-Class: cn.think.in.java.clazz.loader.asm.agent.PreMainTraceAgent
           

(再偷偷地問),難度每次都讓我手動去弄這個檔案,我覺得很麻煩呀,有沒一個工具能幫我們将agent項目打包成包含MAINIFEST.MF的jar?

-----》對,你猜對了,真的有這個工具。那就是maven插件。(說到打包,肯定要想到maven或者gradle了吧)

<plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <version>2.2</version>
                <configuration>
                    <archive>
                        <manifestEntries>
                            <Project-name>${project.name}</Project-name>
                            <Project-version>${project.version}</Project-version>
                            <Premain-Class>com.tuling.agent.Agent</Premain-Class>
                            <Can-Redefine-Classes>true</Can-Redefine-Classes>
                            <Can-Retransform-Classes>true</Can-Retransform-Classes>
                            <Boot-Class-Path>javassist-3.18.1-GA.jar</Boot-Class-Path>
                        </manifestEntries>
                    </archive>
                    <skip>true</skip>
                </configuration>
            </plugin>
           

插件

Java Agent(上)

打包之後

Java Agent(上)

測試

Java Agent(上)
Java Agent(上)
Java Agent(上)
Java Agent(上)

問題二:如果有一個類已經被虛拟機加載了,那麼我們的agent包裡面的邏輯就不能加載這個類。但是我就是想把這類替換掉,怎麼辦呢?(熱更新,虛拟機不停的情況下,替換成使用者最新的代碼)

Java Agent(上)

agent代碼的修改

Java Agent(上)

重新打包

Java Agent(上)
Java Agent(上)
Java Agent(上)
Java Agent(上)
Java Agent(上)

問題三:

當JVM已裝置某個類,但是我們想重新走一次premain方法,我們怎樣做呢?

Java Agent(上)

修改agent代碼

Java Agent(上)

打包

Java Agent(上)
Java Agent(上)
Java Agent(上)

思考

看到這裡,細心的朋友,可能會帶有疑問,我在實踐的時候,發現這個類的位元組碼的生成并不簡單,如果讓我自己去手動去生成那就很麻煩呀?(麻煩--》複雜度高---》容易出錯----》上線容易出問題---》那就直接不考慮該技術)

----》為了解決這個問題,java-ssist就出現了。關于java-ssist,請點選。

https://www.cnblogs.com/vingLiu/p/13193517.html