java 使用本机代理_Java与本机代理–他们所做的强大功能
java 使用本機(jī)代理
在安裝代理之前應(yīng)了解的內(nèi)容及其對(duì)代碼的影響
在構(gòu)建可伸縮的服務(wù)器端應(yīng)用程序時(shí),我們花費(fèi)大量時(shí)間思考如何在生產(chǎn)中監(jiān)視,操作和更新代碼。 已經(jīng)開(kāi)發(fā)出一種新的工具來(lái)幫助Java和Scala開(kāi)發(fā)人員做到這一點(diǎn)。 它們中的許多都是建立在最強(qiáng)大的方式之一上的,即外部代碼可以在運(yùn)行時(shí)與JVM集成的Java代理 。
代理是OS本機(jī)或Java庫(kù)(我們將在下面描述它們之間的差異),JVM提供的這些功能是普通應(yīng)用程序代碼所不具備的。 為了了解它們的基本原理,讓我們看一下我們使用的依賴它們的一些工具–
- 探查器使用Java代理修改目標(biāo)框架的代碼,以注入收集性能指標(biāo)的新代碼。 這包括獨(dú)立或托管服務(wù),例如NewRelic或YourKit。
- Play框架 V1使用Java代理在運(yùn)行時(shí)啟用類的熱交換。
- JRebel通過(guò)構(gòu)建一種可以在運(yùn)行時(shí)提供平滑的類熱交換而無(wú)需重新啟動(dòng)JVM的技術(shù),將其帶入了一個(gè)新的高度。
- 在Takipi,我們利用JVM提供給本機(jī)代理的低級(jí)功能來(lái)顯示導(dǎo)致錯(cuò)誤的實(shí)際源代碼和變量值。
代理商可以做什么?
正如我上面提到的,有兩種代理-Java和本機(jī)。 兩者以幾乎相同的方式(使用特殊的JVM啟動(dòng)參數(shù))加載到JVM中時(shí),它們的構(gòu)建方式和用途幾乎完全不同。
讓我們看一下兩個(gè)–
Java代理
Java代理是.jar文件,它們定義了一個(gè)特殊的premain靜態(tài)函數(shù),在調(diào)用應(yīng)用程序的主函數(shù)之前,JVM將先調(diào)用該靜態(tài)函數(shù)。 神奇的部分來(lái)自Instrumentation對(duì)象,該對(duì)象由主機(jī)JVM作為參數(shù)傳遞給該函數(shù)。 通過(guò)保留該對(duì)象,代理程序的代碼(否則,其行為就像由根類加載器加載的任何Java代碼一樣)可以做一些真正強(qiáng)大的事情。
public static void premain(String agentArgs, Instrumentation inst) { myInst = inst; //grab a reference to the inst object for use later }他們做什么 。 賦予代理程序最強(qiáng)大的功能是在運(yùn)行時(shí)類(字段結(jié)構(gòu)是不可變的)上動(dòng)態(tài)重寫(xiě)目標(biāo)類方法內(nèi)容的能力。 此過(guò)程稱為字節(jié)碼檢測(cè),使代理能夠在代碼運(yùn)行時(shí)實(shí)質(zhì)上重寫(xiě)方法的內(nèi)容。
一些示例包括添加對(duì)特定方法的調(diào)用以概要分析性能(例如,結(jié)束時(shí)間–開(kāi)始時(shí)間)或記錄參數(shù)值(例如,傳遞給Servlet的URL)。 另一個(gè)示例將是重新加載類的新版本,而不用像JRebel那樣重新啟動(dòng)JVM。
怎么做的 。 對(duì)于代理修改代碼或已加載的類,它實(shí)際上觸發(fā)了JVM重新加載類的過(guò)程,其中該類的字節(jié)碼被替換為新版本。 這就要求代理能夠?yàn)镴VM提供可驗(yàn)證的新字節(jié)碼(即符合JVM規(guī)范)。 不幸的是,在運(yùn)行時(shí)生成正確的字節(jié)碼并不是一件容易的事–有很多要求和邊緣情況。 對(duì)于這種代理,通常使用一個(gè)庫(kù)來(lái)讀取和寫(xiě)入字節(jié)碼,從而使他們能夠?qū)F(xiàn)有類的字節(jié)碼加載到類似DOM的結(jié)構(gòu)中,通過(guò)添加性能分析調(diào)用之類的東西對(duì)其進(jìn)行修改,然后將DOM保存回原始字節(jié)碼。 ASM對(duì)此很受歡迎。 如此流行,以至于Sun的一些內(nèi)部代碼實(shí)際上已使用它來(lái)解析Java中的字節(jié)碼。
本地代理
本地代理人是完全不同的野獸。 如果您認(rèn)為Java代理可以讓您做一些很酷的事情,那么請(qǐng)堅(jiān)持一下,因?yàn)楸緳C(jī)代理在不同的層次上運(yùn)行。 本機(jī)代理不是用Java編寫(xiě)的,而是大多數(shù)用C ++編寫(xiě)的,并且不受常規(guī)Java代碼操作的規(guī)則和限制的約束。 不僅如此,它們還具有稱為JVM工具接口(JVMTI)的極其強(qiáng)大的功能集。
他們做什么 。 jvmti.h公開(kāi)的這組API實(shí)質(zhì)上使JVM動(dòng)態(tài)加載的C ++庫(kù)能夠獲得對(duì)JVM實(shí)時(shí)工作的極高可見(jiàn)性。 這涵蓋了廣泛的領(lǐng)域,包括GC,鎖定,代碼操作,同步,線程管理,編譯調(diào)試等等。
JVM TI旨在使JVM盡可能透明,同時(shí)仍保持設(shè)計(jì)靈活性,以允許JVM供應(yīng)商提供不同的基礎(chǔ)實(shí)現(xiàn)。 這套API非常廣泛,實(shí)際上包含了數(shù)百個(gè)JVM回調(diào)和函數(shù)。 您可以使用它們來(lái)執(zhí)行Java代理無(wú)法完成的極其強(qiáng)大的功能,例如編寫(xiě)您自己的調(diào)試器或構(gòu)建底層的實(shí)時(shí)錯(cuò)誤分析工具( Takipi就是這樣)。
例如,這是JVMTI提供給代理的回調(diào),因此,只要在JVM內(nèi)部的任何地方引發(fā)異常,代理都會(huì)收到引發(fā)異常的字節(jié)碼位置,所有者線程,異常對(duì)象和如果/在哪里被捕獲。 確實(shí)功能強(qiáng)大。
void JNICALL ExceptionCallback(jvmtiEnv *jvmti, JNIEnv *jni, jthread thread, jmethodID method, jlocation location, jobject exception, jmethodID catch_method, jlocation catch_location)缺點(diǎn) 。 如果我描述的所有內(nèi)容聽(tīng)起來(lái)都像桃子一樣,您可以問(wèn)為什么不是所有代理都寫(xiě)成本地代理? 沒(méi)有什么理由可以知道,因此這里是(沒(méi)有特定的順序)。
復(fù)雜性 。 首先是JVMTI API非常復(fù)雜,帶有許多小的移動(dòng)輪子。在大多數(shù)情況下,如果您不連接需要非常低級(jí)功能的代理,則可以使用Java代理API很好。更直接,可以幫助您更快地完成工作。
可移植性 。 由于本機(jī)代理是作為本機(jī)庫(kù)(.so / .dll)編寫(xiě)和編譯的,因此需要在要支持的任何數(shù)量的操作系統(tǒng)上進(jìn)行編譯和測(cè)試。 如果您查看Windows,OSX和Linux帶來(lái)的不同風(fēng)格,則可以轉(zhuǎn)化為大量工作。 將其與Java代理(由JVM作為Java代碼執(zhí)行,因此在設(shè)計(jì)上具有固有的可移植性)進(jìn)行比較。
字節(jié)碼操作。 由于本機(jī)代理程序通常是用C ++編寫(xiě)的,這意味著它們不能直接使用經(jīng)過(guò)嘗試的真正的Java字節(jié)碼操作庫(kù)(例如ASM),而不必使用JNI返回JVM,這確實(shí)會(huì)帶來(lái)一些樂(lè)趣。
穩(wěn)定性 。 JVM提供了強(qiáng)有力的保護(hù)措施,以防止代碼執(zhí)行可能導(dǎo)致憤怒的OS終止進(jìn)程的事情。 在正常情況下,內(nèi)存訪問(wèn)沖突會(huì)導(dǎo)致SIGSEV并使程序崩潰,請(qǐng)給我們包裝一個(gè)不錯(cuò)的NullPointerException。 由于本機(jī)代理程序在JVM的相同級(jí)別上運(yùn)行(與Java代理程序由其執(zhí)行代碼)相同,因此它們所犯的任何錯(cuò)誤都可能會(huì)終止JVM。
希望這有助于突出兩種之間的某些區(qū)別。 了解什么是代理以及它們是如何構(gòu)建的,這是很好的,即使您從未最終編寫(xiě)過(guò)代理,也可能依靠其中的一個(gè)或多個(gè)來(lái)為您的應(yīng)用程序提供動(dòng)力。
翻譯自: https://www.javacodegeeks.com/2014/01/java-vs-native-agents-the-powerful-things-they-do.html
java 使用本機(jī)代理
總結(jié)
以上是生活随笔為你收集整理的java 使用本机代理_Java与本机代理–他们所做的强大功能的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 京东、阿里重回战场,社区团购为何让大厂们
- 下一篇: Java:使用Toxiproxy模拟各种