写点什么

让 Java Agent 在 Dragonwell 上更好用

  • 2023-01-09
    浙江
  • 本文字数:2065 字

    阅读完需:约 7 分钟

本文是《容器中的 Java》系列文章之 3/n,欢迎关注后续连载 :) 。1

背景

随着越来越多的云原生微服务应用的大规模部署,大家对微服务治理的能力需求越来越强。


Java Agent 技术能够让业务专注于业务逻辑,与此同时,中间件通过 Java Agent 支持无侵入修改程序行为,提供微服务治理能力。


此外,Java Agent 支持通过环境变量的方式注入,中间件、云产品团队可以通过设置环境变量来支持


所以目前基于 Java Agent 实现的云原生可观测、微服务治理能力被越来越多的采用。比如开源的 Skywalking、OpenTelemetry,商业化的阿里云 MSE 等,都支持 Java Agent 接入。

问题

我们以**MSE 微服务 demo [ 1] **为例。


先在一个 Kubernetes 集群中安装好 ack-onepilot,然后部署上述 demo。


先可以访问 demo 中的 gateway,验证下可以正常工作:


1.png


您也可以参考**MSE 的帮助文档 [ 2] **体验下全链路灰度等微服务治理能力。


我们登陆容器时,就能看到注入的 agent:


2.png


但这样的结果是容器中所有的 JVM,都会挂载 Agent。


比如 java -version:


3.png


比如 jstack:


4.png


  1. java/jps/jstack/jcmd 等 JDK 自带的问题排查工具,都会去从环境变量加载 Java Agent

  2. 因为 Java Agent 是在 JVM 初期加载的,所以 Java Agent 会先耗费 6-7s 来加载 agent 逻辑。

  3. 但作为 JDK 工具,其实没有任何业务逻辑,不需要微服务治理能力。可以不用加载 Java Agent 的


我们设想下这个场景:线上应用出现问题了,运维同学要抓现场,上去就想 jstack 拉一下 stacktrace 信息。


结果先要加载 java agent,不但浪费了 CPU 和内存,更容易错过问题排查的现场。


但,一边要通过环境变量无侵入注入 Java Agent,一边又要不在某些进程内注入。看起来无解了?

MSE 携手 Dragonwell,让微服务治理更友好

首先,注入 Java Agent 与否,是 JVM 确定的。我们只需要修改 JVM 即可。


在这一点上,Dragonwell 团队有着丰富的经验。


其次,我们看下 JVM 的行为,现有的开源行为如下:


  • JDK 相关命令,都会从 JAVA_TOOL_OPTIONS 加载 Java Agent

  • 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”的业务开发同学,稳定为先,所以 Java 8 是一定要支持的。


经过和 Dragonwell 的讨(si)论(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 不会加载环境变量、不会加载 Java Agent。


从意图上来说:


  1. 如果需要给 java 和 jps 等运维工具设置参数,而且这些参数是 java 通用的,那么应该设置给环境变量 JAVA_TOOL_OPTIONS。

  2. 如果需要给 javaj 和 jps 等运维工具 j 设置参数,而且这些参数是 jvm 厂商相关 j 的,比如是 dragonwell 特有的开关,那么应该设置 DRAGONWELL_JAVA_OPTIONS。

  3. 如果需要给 java 设置参数,但是不给运维工具设置,而且参数是 java 通用的,那么应该设置环境变量 JAVA_TOOL_OPTIONS,并设置 DRAGONWELL_JAVA_TOOL_OPTIONS_JDK_ONLY=true。

  4. 3.1. 如果是 jdk9 及以上,则应该使用更加标准的 JDK_JAVA_OPTIONS。

  5. 如果需要给 java 设置参数,但是不给运维工具设置,而且参数是 jvm 厂商相关的,那么应该设置环境变量 DRAGONWELL_JAVA_OPTIONS,并设置 DRAGONWELL_JAVA_TOOL_OPTIONS_JDK_ONLY=true。


经过上面的改造,就可以做到只对业务 Java 进程加载 Java Agent。同时不影响 jps/jstack 等 JDK 自带的运维命令。


当然,Dragonwell 作为开源项目,讨论的整体流程都是在**GitHub Issue [ 5] 上完成的,欢迎围观、吃瓜、吐槽。

最终效果

让我们使用最新的 Dragonwell 版本,跑一下业务应用,模拟一下运维场景:


5.png


可以看到,JDK 运维工具不会加载 Java Agent 了。


业务进程加载了 Java Agent(您也可以在 MSE 微服务治理控制台上看到应用);也避免了 Java Agent 影响了 java -version 等运维脚本。

5MSE 给你带来更强大的微服务治理能力

阿里云微服务引擎(MSE)通过 Java Agent/SDK/Service Mesh 等方式,给您带来零接入成本、无侵入的、全生命周期的微服务治理能力。


通过 MSE 微服务治理,不用改一行代码即可享受全链路灰度、无损上下线、服务测试等微服务治理能力,为您的开发、测试、上线、运维保驾护航。

相关链接

[1]MSE 微服务 demo


https://github.com/aliyun/alibabacloud-microservice-demo/tree/master/mse-simple-demo/helm/mse-simple-demo


[2]MSE 的帮助文档


https://mp.weixin.qq.com/s/95WZHL0HhFtzxMlfK-8jkg


[3]IBM_JAVA_OPTIONS


https://www.ibm.com/docs/en/zos/2.3.0?topic=runtime-java-options


[4]OPENJ9_JAVA_OPTIONS


https://www.eclipse.org/openj9/docs/cmdline_specifying/#precedence


[5]GitHub Issue


https://github.com/alibaba/dragonwell8/issues/330#issuecomment-1138083844


点击此处查看微服务引擎详情

发布于: 刚刚阅读数: 4
用户头像

阿里云云原生 2019-05-21 加入

还未添加个人简介

评论

发布
暂无评论
让 Java Agent 在 Dragonwell 上更好用_Java_阿里巴巴云原生_InfoQ写作社区