Java Agent(上)
阿新 • • 發佈:2020-06-26
# 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了吧)
```xml
org.apache.maven.plugins
maven-jar-plugin
2.2
${project.name}
${project.version}
com.tuling.agent.Agent
true
true
javassist-3.18.1-GA.jar
true
```
外掛
![](https://img2020.cnblogs.com/blog/1601833/202006/1601833-20200625221947465-119853787.png)
打包之後
![](https://img2020.cnblogs.com/blog/1601833/202006/1601833-20200625221930904-575658473.png)
測試
![](https://img2020.cnblogs.com/blog/1601833/202006/1601833-20200625222230926-1822401398.png)
![](https://img2020.cnblogs.com/blog/1601833/202006/1601833-20200625222257257-313740919.png)
![](https://img2020.cnblogs.com/blog/1601833/202006/1601833-20200625222339959-1951717786.png)
![](https://img2020.cnblogs.com/blog/1601833/202006/1601833-20200625222442180-105532176.png)
問題二:如果有一個類已經被虛擬機器載入了,那麼我們的agent包裡面的邏輯就不能載入這個類。但是我就是想把這類替換掉,怎麼辦呢?(熱更新,虛擬機器不停的情況下,替換成使用者最新的程式碼)
外掛
![](https://img2020.cnblogs.com/blog/1601833/202006/1601833-20200625224544095-804993426.png)
agent程式碼的修改
![](https://img2020.cnblogs.com/blog/1601833/202006/1601833-20200625224616419-1598865435.png)
重新打包
![](https://img2020.cnblogs.com/blog/1601833/202006/1601833-20200625224701979-1986520145.png)
測試
![](https://img2020.cnblogs.com/blog/1601833/202006/1601833-20200625224809947-2144527101.png)
![](https://img2020.cnblogs.com/blog/1601833/202006/1601833-20200625224829129-222204175.png)
![](https://img2020.cnblogs.com/blog/1601833/202006/1601833-20200625224844578-44668966.png)
![](https://img2020.cnblogs.com/blog/1601833/202006/1601833-20200625225156620-288266716.png)
問題三:
當JVM已裝置某個類,但是我們想重新走一次premain方法,我們怎樣做呢?
外掛
![](https://img2020.cnblogs.com/blog/1601833/202006/1601833-20200625231111829-699939489.png)
修改agent程式碼
![](https://img2020.cnblogs.com/blog/1601833/202006/1601833-20200625231200820-167003360.png)
打包
測試
![](https://img2020.cnblogs.com/blog/1601833/202006/1601833-20200625231232604-54827950.png)
![](https://img2020.cnblogs.com/blog/1601833/202006/1601833-20200625231253936-1512161731.png)
![](https://img2020.cnblogs.com/blog/1601833/202006/1601833-20200625231333147-1419167037.png)
# 思考
看到這裡,細心的朋友,可能會帶有疑問,我在實踐的時候,發現這個類的位元組碼的生成並不簡單,如果讓我自己去手動去生成那就很麻煩呀?(麻煩--》複雜度高---》容易出錯----》上線容易出問題---》那就直接不考慮該技術)
----》為了解決這個問題,**java-ssist**就出現了。關於java-ssist,請點選。
> https://www.cnblogs.com/vingLiu/p/13193