本文是《容器中的Java》系列文章的第3篇,欢迎关注后续系列:)。1背景随着越来越多的云原生微服务应用的大规模部署,对微服务治理能力的需求也越来越强烈。JavaAgent技术使业务能够专注于业务逻辑。同时,中间件支持通过JavaAgent对程序行为进行无创修改,提供微服务治理能力。另外,JavaAgent支持通过环境变量注入,中间件和云产品团队可以通过设置环境变量来支持。因此,基于JavaAgent的云原生可观察性和微服务治理能力目前正在被越来越多的人采用。比如开源的Skywalking、OpenTelemetry、商用的阿里云MSE都支持JavaAgent接入。问题我们以MSE微服务demo[1]为例。首先在Kubernetes集群中安装ack-onepilot,然后部署上面的demo。首先,您可以访问demo中的网关,验证其是否可以正常工作:您也可以参考MSE帮助文档[2],体验全链路灰度等微服务治理能力。当我们登录容器时,可以看到注入的agent:但是结果是容器内的所有JVM都会挂载Agent。比如java-version:比如jstack:java/jps/jstack/jcmd等JDK自带的排错工具会从环境变量中加载JavaAgent。因为JavaAgent是在JVM的前期加载的,所以JavaAgent会先消耗6-7s来加载agent逻辑。但是作为JDK工具,它不具备任何业务逻辑,不需要微服务治理能力。我们可以在不加载JavaAgent的情况下想象这样一个场景:线上应用出现了问题,运维同学想抓现场,所以要jstack上去拉stacktrace信息。导致必须先加载java代理,不仅浪费CPU和内存,也容易错过排错现场。但是,一方面需要通过环境变量无侵入的方式注入JavaAgent,另一方面也不能在某些进程中注入。似乎无解?MSE携手Dragonwell,让微服务治理更加友好。首先,是否注入JavaAgent是由JVM决定的。我们只需要修改JVM。在这一点上,龙之井团队有着丰富的经验。其次,让我们看看JVM的行为。现有的开源行为如下:JDK相关的命令会从JAVA_TOOL_OPTIONS加载JavaAgent。OpenJDK9之后引入了JDK_JAVA_OPTIONS。此环境变量将仅由java命令使用。jps/jstack之类的命令不会加载。一些JDK制造商有自己的扩展环境变量。比如IBM会读取IBM_JAVA_OPTIONS[3],OpenJ9开源后开始使用OPENJ9_JAVA_OPTIONS[4],Oracle/OpenJDK使用_JAVA_OPTIONS。本来JDK_JAVA_OPTIONS就可以很好的满足需求,但是作为一个“随便发帖,我用Java8”的业务开发同学,稳定性是第一位的,所以必须支持Java8。(si)与Dragonwell(bi)讨论后,确定如下修改:DRAGONWELL_JAVA_OPTIONS,类似于IBM_JAVA_OPTIONS[3],只为Dragonwell设置一些Java参数。DRAGONWELL_JAVA_TOOL_OPTIONS_JDK_ONLY,类似于JDK_JAVA_OPTIONS。如果DRAGONWELL_JAVA_TOOL_OPTIONS_JDK_ONLY=true,JAVA_TOOL_OPTIONS只会被java命令加载。jps/jstack不会加载环境变量和JavaAgent。意图方面:如果需要为java、jps等运维工具设置参数,而这些参数是java通用的,则应该设置到环境变量JAVA_TOOL_OPTIONS中。如果需要为javaj、jps等运维工具设置参数,并且这些参数与jvm厂商相关,比如dragonwell专用的开关,则需要设置DRAGONWELL_JAVA_OPTIONS。如果需要为java设置参数,运维工具不需要设置参数,且参数是java通用的,则需要设置环境变量JAVA_TOOL_OPTIONS,设置DRAGONWELL_JAVA_TOOL_OPTIONS_JDK_ONLY=true。3.1.如果是jdk9及以上,应该使用比较标准的JDK_JAVA_OPTIONS。如果需要为java设置参数,而运维工具不需要设置参数,且参数与jvm厂商有关,则应设置环境变量DRAGONWELL_JAVA_OPTIONS,设置DRAGONWELL_JAVA_TOOL_OPTIONS_JDK_ONLY=true。经过上述修改后,可以只为业务Java进程加载JavaAgent。同时不影响jps/jstack等JDK自带的运维命令。当然,Dragonwell是一个开源项目,讨论的整体过程是在GitHubIssue[5]上完成的。欢迎围观、吃瓜、吐槽。**最终效果让我们使用最新的Dragonwell版本,运行业务应用,模拟运维场景:可以看到JDK运维工具不会加载JavaAgent。业务流程加载JavaAgent(也可以在MSE微服务管理控制台看到应用);也避免JavaAgent影响java-version等运维脚本。5MSE为您带来更强大的微服务治理能力。阿里云微服务引擎(MSE)通过JavaAgent/SDK/ServiceMesh等方式治理能力,为您带来零接入成本、无侵入、全生命周期的微服务。通过MSE微服务治理,您无需更改一行代码,即可享受全链路灰度化、线上线下无损、服务测试等微服务治理能力,为您的开发、测试、上线、运维保驾护航。相关链接[1]MSE微服务demohttps://github.com/aliyun/ali...[2]MSE帮助文档https://mp.weixin.qq.com/s/95...[3]IBM_JAVA_OPTIONShttps://www.ibm.com/docs/en/z...[4]OPENJ9_JAVA_OPTIONShttps://www.eclipse.org/openj...[5]GitHub问题https://github.com/alibaba/dragonwell8/issues/330#issuecomment-1138083844点此查看微服务引擎详情
