Java Agent簡介

近期被梅芙和奧迪斯圈粉

這個(gè)是之前寫類加載器篇時(shí)候挖的坑祸轮,來填坑了。

引言

以前在做后臺服務(wù)開發(fā)的時(shí)候犬绒,SpringBoot每次改動(dòng)代碼都需要手動(dòng)重啟才能生效檩禾,感覺賊麻煩挂签,后來使用Spring提供的一款熱部署插件,它只是部分重啟盼产,相當(dāng)于重新加載了我們自己寫的代碼饵婆,效率提高很多。后來遇到了Jrebel戏售,它只重新加載我們修改的那個(gè)類侨核,比Springboot熱部署插件重啟速度更快,連改mybatis的xml文件都能熱部署灌灾,太方便了有不有4暌搿(順便安利一下同一家公司的另一個(gè)軟件XRebel,實(shí)時(shí)監(jiān)控服務(wù)請求)后來又接觸了BTrace锋喜,它可以線上調(diào)試代碼而不需要重啟項(xiàng)目些己,也是很吊的一個(gè)東西豌鸡。通過了解,上面所說的幾個(gè)東西都是通過Java Agent來實(shí)現(xiàn)的段标,那么Java Agent到底是啥涯冠,為啥這么吊?

簡介

先說一下它的用途逼庞,在JDK1.5以后蛇更,我們可以使用agent技術(shù)構(gòu)建一個(gè)獨(dú)立于應(yīng)用程序的代理程序(即為Agent),用來協(xié)助監(jiān)測赛糟、運(yùn)行甚至替換其他JVM上的程序械荷。使用它可以實(shí)現(xiàn)虛擬機(jī)級別的AOP功能。

Agent實(shí)例

Agent分為兩種虑灰,一種是在主程序之前運(yùn)行的Agent,一種是在主程序之后運(yùn)行的Agent(前者的升級版痹兜,1.6以后提供)穆咐,這兩種我們都會(huì)舉個(gè)??。

一字旭、在主程序運(yùn)行之前的代理程序

1对湃、首先寫一個(gè)agent程序

代碼很簡單,只有一個(gè)premain方法遗淳,顧名思義它代表著他將在主程序的main方法之前運(yùn)行拍柒,agentArgs代表傳遞過來的參數(shù),inst則是agent技術(shù)主要使用的API屈暗,我們可以使用它來改變和重新定義類的行為(這篇文章不會(huì)介紹拆讯,想了解的同學(xué)可以看文末的鏈接),這里我們簡單的進(jìn)行一下參數(shù)打印养叛。

2种呐、編寫MANIFEST.MF文件

MANIFEST.MF文件用于描述Jar包的信息,例如指定入口函數(shù)等弃甥。我們需要在該文件中加入如下配置爽室,指定我們編寫的含有premain方法類的全路徑,然后將agent類打成Jar包淆攻。

如果你是使用Maven來構(gòu)建的項(xiàng)目阔墩,在構(gòu)建的時(shí)候加入如下代碼,否則Maven會(huì)生成自己的MANIFEST.MF覆蓋掉你的瓶珊。

3啸箫、編寫我們的主程序

這里的程序就是我們要代理的程序,我們在主程序的VM options添加上啟動(dòng)參數(shù)

-javaagent: 你的路徑/test-1.0-SNAPSHOT.jar=hah

其中hah為上文中傳入permain方法的agentArgs參數(shù)艰毒。運(yùn)行我們的主程序

可以看到筐高,我們Jar包中premain方法中的的代碼在主函數(shù)運(yùn)行之前就已經(jīng)成功運(yùn)行了!

二、在主程序運(yùn)行之后的代理程序

在主程序運(yùn)行之前的agent模式有一些缺陷柑土,例如需要在主程序運(yùn)行前就指定javaagent參數(shù)蜀肘,premain方法中代碼出現(xiàn)異常會(huì)導(dǎo)致主程序啟動(dòng)失敗等,為了解決這些問題稽屏,JDK1.6以后提供了在程序運(yùn)行之后改變程序的能力扮宠。它的實(shí)現(xiàn)步驟和之前的模式類似

1、編寫agent類

我們復(fù)用上面的類狐榔,將premain方法修改為agentmain方法坛增,由于是在主程序運(yùn)行后再執(zhí)行,意味著我們可以獲取主程序運(yùn)行時(shí)的信息薄腻,這里我們打印出來主程序中加載的類名收捣。

2、修改MANIFEST.MF文件

添加Agent-Class參數(shù)庵楷,打成Jar包

3罢艾、啟動(dòng)主程序,編寫加載agent類的程序

在程序運(yùn)行后加載尽纽,我們不可能在主程序中編寫加載的代碼咐蚯,只能另寫程序,那么另寫程序如何與主程序進(jìn)行通信弄贿?這里用到的機(jī)制就是attach機(jī)制春锋,它可以將JVM A連接至JVM B,并發(fā)送指令給JVM B執(zhí)行差凹,JDK自帶常用工具如jstack期奔,jps等就是使用該機(jī)制來實(shí)現(xiàn)的。這里我們先用tomcat啟動(dòng)一個(gè)程序用作主程序B直奋,再來寫A程序代碼

我們使用VirtualMachine attach到目標(biāo)進(jìn)程能庆,其中78256為tomcat進(jìn)程的PID,可以使用jps命令獲得脚线,也可以使用VirtualMachine.list方法獲取本機(jī)上所有的Java進(jìn)程搁胆,再來判斷tomcat進(jìn)程,loadAgent方法第一個(gè)參數(shù)為Jar包在本機(jī)中的路徑邮绿,第二個(gè)參數(shù)為傳入agentmain的args參數(shù)渠旁,此處為null,運(yùn)行程序

然而什么都沒有打印按顾腊!是不是什么地方寫錯(cuò)了呢?仔細(xì)想想就會(huì)發(fā)現(xiàn)挖胃,我們是將進(jìn)程attach到了tomcat進(jìn)程上杂靶,agent其實(shí)是在主程序B中運(yùn)行的梆惯,所以程序A中自然就不會(huì)進(jìn)行打印,我們跳回tomcat程序的控制臺吗垮,查看結(jié)果辫封。

由于是真實(shí)公司項(xiàng)目羡宙,項(xiàng)目名打碼了

可以看到鸠删,agentmain方法中的代碼已經(jīng)在主程序中順利運(yùn)行了易阳,并且打印出了程序中加載的類!

總結(jié)

以上就是Java Agent的倆個(gè)簡單小栗子了饵沧,Java Agent十分強(qiáng)大锨络,它能做到的不僅僅是打印幾個(gè)監(jiān)控?cái)?shù)值而已,還包括使用Transformer(推薦觀看等高級功能進(jìn)行類替換狼牺,方法修改等羡儿,要使用Instrumentation的相關(guān)API則需要對字節(jié)碼等技術(shù)有較深的認(rèn)識。

最后是钥,繼續(xù)給自己挖坑失受,以后有機(jī)會(huì)寫字節(jié)碼相關(guān)的東西。咏瑟。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市痪署,隨后出現(xiàn)的幾起案子码泞,更是在濱河造成了極大的恐慌,老刑警劉巖狼犯,帶你破解...
    沈念sama閱讀 206,378評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件余寥,死亡現(xiàn)場離奇詭異,居然都是意外死亡悯森,警方通過查閱死者的電腦和手機(jī)宋舷,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來瓢姻,“玉大人祝蝠,你說我怎么就攤上這事』眉睿” “怎么了绎狭?”我有些...
    開封第一講書人閱讀 152,702評論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長褥傍。 經(jīng)常有香客問我儡嘶,道長,這世上最難降的妖魔是什么恍风? 我笑而不...
    開封第一講書人閱讀 55,259評論 1 279
  • 正文 為了忘掉前任蹦狂,我火速辦了婚禮誓篱,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘凯楔。我一直安慰自己窜骄,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,263評論 5 371
  • 文/花漫 我一把揭開白布啼辣。 她就那樣靜靜地躺著啊研,像睡著了一般。 火紅的嫁衣襯著肌膚如雪鸥拧。 梳的紋絲不亂的頭發(fā)上党远,一...
    開封第一講書人閱讀 49,036評論 1 285
  • 那天,我揣著相機(jī)與錄音富弦,去河邊找鬼沟娱。 笑死,一個(gè)胖子當(dāng)著我的面吹牛腕柜,可吹牛的內(nèi)容都是我干的济似。 我是一名探鬼主播,決...
    沈念sama閱讀 38,349評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼盏缤,長吁一口氣:“原來是場噩夢啊……” “哼砰蠢!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起唉铜,我...
    開封第一講書人閱讀 36,979評論 0 259
  • 序言:老撾萬榮一對情侶失蹤台舱,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后潭流,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體竞惋,經(jīng)...
    沈念sama閱讀 43,469評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,938評論 2 323
  • 正文 我和宋清朗相戀三年灰嫉,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了拆宛。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,059評論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡讼撒,死狀恐怖浑厚,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情根盒,我是刑警寧澤瞻颂,帶...
    沈念sama閱讀 33,703評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站郑象,受9級特大地震影響贡这,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜厂榛,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,257評論 3 307
  • 文/蒙蒙 一盖矫、第九天 我趴在偏房一處隱蔽的房頂上張望丽惭。 院中可真熱鬧,春花似錦辈双、人聲如沸责掏。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽换衬。三九已至,卻和暖如春证芭,著一層夾襖步出監(jiān)牢的瞬間瞳浦,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工废士, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留叫潦,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,501評論 2 354
  • 正文 我出身青樓官硝,卻偏偏與公主長得像矗蕊,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子氢架,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,792評論 2 345

推薦閱讀更多精彩內(nèi)容