济南正规企业站seo,网络促销分类 网站促销,网站更改建设方案模板,网站开发快递文件java 使用本机代理在安装代理之前应了解的内容及其对代码的影响 在构建可伸缩的服务器端应用程序时#xff0c;我们花费大量时间思考如何在生产中监视#xff0c;操作和更新代码。 已经开发出一种新的工具来帮助Java和Scala开发人员做到这一点。 它们中的许多都是建立在最强大… java 使用本机代理 在安装代理之前应了解的内容及其对代码的影响 在构建可伸缩的服务器端应用程序时我们花费大量时间思考如何在生产中监视操作和更新代码。 已经开发出一种新的工具来帮助Java和Scala开发人员做到这一点。 它们中的许多都是建立在最强大的方式之一上的即外部代码可以在运行时与JVM集成的Java代理 。 代理是OS本机或Java库我们将在下面描述它们之间的差异JVM提供的这些功能是普通应用程序代码所不具备的。 为了了解它们的基本原理让我们看一下我们使用的依赖它们的一些工具– 探查器使用Java代理修改目标框架的代码以注入收集性能指标的新代码。 这包括独立或托管服务例如NewRelic或YourKit。 Play框架 V1使用Java代理在运行时启用类的热交换。 JRebel通过构建一种可以在运行时提供平滑的类热交换而无需重新启动JVM的技术将其带入了一个新的高度。 在Takipi我们利用JVM提供给本机代理的低级功能来显示导致错误的实际源代码和变量值。 代理商可以做什么 正如我上面提到的有两种代理-Java和本机。 两者以几乎相同的方式使用特殊的JVM启动参数加载到JVM中时它们的构建方式和用途几乎完全不同。 让我们看一下两个– Java代理 Java代理是.jar文件它们定义了一个特殊的premain静态函数在调用应用程序的主函数之前JVM将先调用该静态函数。 神奇的部分来自Instrumentation对象该对象由主机JVM作为参数传递给该函数。 通过保留该对象代理程序的代码否则其行为就像由根类加载器加载的任何Java代码一样可以做一些真正强大的事情。 public static void premain(String agentArgs, Instrumentation inst) {
myInst inst; //grab a reference to the inst object for use later
} 他们做什么 。 赋予代理程序最强大的功能是在运行时类字段结构是不可变的上动态重写目标类方法内容的能力。 此过程称为字节码检测使代理能够在代码运行时实质上重写方法的内容。 一些示例包括添加对特定方法的调用以概要分析性能例如结束时间–开始时间或记录参数值例如传递给Servlet的URL。 另一个示例将是重新加载类的新版本而不用像JRebel那样重新启动JVM。 怎么做的 。 对于代理修改代码或已加载的类它实际上触发了JVM重新加载类的过程其中该类的字节码被替换为新版本。 这就要求代理能够为JVM提供可验证的新字节码即符合JVM规范。 不幸的是在运行时生成正确的字节码并不是一件容易的事–有很多要求和边缘情况。 对于这种代理通常使用一个库来读取和写入字节码从而使他们能够将现有类的字节码加载到类似DOM的结构中通过添加性能分析调用之类的东西对其进行修改然后将DOM保存回原始字节码。 ASM对此很受欢迎。 如此流行以至于Sun的一些内部代码实际上已使用它来解析Java中的字节码。 本地代理 本地代理人是完全不同的野兽。 如果您认为Java代理可以让您做一些很酷的事情那么请坚持一下因为本机代理在不同的层次上运行。 本机代理不是用Java编写的而是大多数用C 编写的并且不受常规Java代码操作的规则和限制的约束。 不仅如此它们还具有称为JVM工具接口JVMTI的极其强大的功能集。 他们做什么 。 jvmti.h公开的这组API实质上使JVM动态加载的C 库能够获得对JVM实时工作的极高可见性。 这涵盖了广泛的领域包括GC锁定代码操作同步线程管理编译调试等等。 JVM TI旨在使JVM尽可能透明同时仍保持设计灵活性以允许JVM供应商提供不同的基础实现。 这套API非常广泛实际上包含了数百个JVM回调和函数。 您可以使用它们来执行Java代理无法完成的极其强大的功能例如编写您自己的调试器或构建底层的实时错误分析工具 Takipi就是这样。 例如这是JVMTI提供给代理的回调因此只要在JVM内部的任何地方引发异常代理都会收到引发异常的字节码位置所有者线程异常对象和如果/在哪里被捕获。 确实功能强大。 void JNICALL ExceptionCallback(jvmtiEnv *jvmti,
JNIEnv *jni, jthread thread, jmethodID method,
jlocation location, jobject exception,
jmethodID catch_method, jlocation catch_location) 缺点 。 如果我描述的所有内容听起来都像桃子一样您可以问为什么不是所有代理都写成本地代理 没有什么理由可以知道因此这里是没有特定的顺序。 复杂性 。 首先是JVMTI API非常复杂带有许多小的移动轮子。在大多数情况下如果您不连接需要非常低级功能的代理则可以使用Java代理API很好。更直接可以帮助您更快地完成工作。 可移植性 。 由于本机代理是作为本机库.so / .dll编写和编译的因此需要在要支持的任何数量的操作系统上进行编译和测试。 如果您查看WindowsOSX和Linux带来的不同风格则可以转化为大量工作。 将其与Java代理由JVM作为Java代码执行因此在设计上具有固有的可移植性进行比较。 字节码操作。 由于本机代理程序通常是用C 编写的这意味着它们不能直接使用经过尝试的真正的Java字节码操作库例如ASM而不必使用JNI返回JVM这确实会带来一些乐趣。 稳定性 。 JVM提供了强有力的保护措施以防止代码执行可能导致愤怒的OS终止进程的事情。 在正常情况下内存访问冲突会导致SIGSEV并使程序崩溃请给我们包装一个不错的NullPointerException。 由于本机代理程序在JVM的相同级别上运行与Java代理程序由其执行代码相同因此它们所犯的任何错误都可能会终止JVM。 希望这有助于突出两种之间的某些区别。 了解什么是代理以及它们是如何构建的这是很好的即使您从未最终编写过代理也可能依靠其中的一个或多个来为您的应用程序提供动力。 参考 Java与本地代理– Takipi博客上我们JCG合作伙伴 Iris Shoor 的强大功能 。 翻译自: https://www.javacodegeeks.com/2014/01/java-vs-native-agents-the-powerful-things-they-do.htmljava 使用本机代理