让 Java Agent 在 Dragonwell 上更好用

本文涉及的产品
可观测可视化 Grafana 版,10个用户账号 1个月
应用实时监控服务-用户体验监控,每月100OCU免费额度
函数计算FC,每月15万CU 3个月
简介: 本文是《容器中的Java》系列文章之 3/n,欢迎关注后续连载 :) 。

本文是《容器中的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。
    3.1. 如果是jdk9及以上,则应该使用更加标准的JDK_JAVA_OPTIONS。
  4. 如果需要给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


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

相关实践学习
基于MSE实现微服务的全链路灰度
通过本场景的实验操作,您将了解并实现在线业务的微服务全链路灰度能力。
相关文章
|
1月前
|
Arthas 监控 Java
拥抱 OpenTelemetry:阿里云 Java Agent 演进实践
本文介绍了阿里云 Java Agent 4.x 版本在基于 OTel Java Agent 二次开发过程中的实践与思考,并重点从功能、性能、稳定性、兼容性四个方面介绍了所做的工作。同时也介绍了阿里云可观测团队积极参与开源建设取得的丰厚成果。
193 5
拥抱 OpenTelemetry:阿里云 Java Agent 演进实践
|
5月前
|
Java 关系型数据库 MySQL
GraalVM 静态编译下 OTel Java Agent 的自动增强方案与实现
在 2024 OpenTelemetry Community Day 会议中,阿里云可观测工程师张乎兴(望陶)和饶子昊(铖朴)为大家带来了《GraalVM 静态编译下 OTel Java Agent 的自动增强方案与实现》的演讲分享,介绍阿里云在相关领域的探索方案,本文是相关分享对应的中文整理。
272 19
|
4月前
|
数据采集 人工智能 监控
【Azure 应用程序见解】Application Insights Java Agent 3.1.0的使用实验,通过修改单个URL的采样率来减少请求及依赖项的数据采集
【Azure 应用程序见解】Application Insights Java Agent 3.1.0的使用实验,通过修改单个URL的采样率来减少请求及依赖项的数据采集
|
7月前
|
监控 Java Maven
揭秘Java Agent技术:解锁Java工具开发的新境界
作为JDK提供的关键机制,Java Agent技术不仅为Java工具的开发者提供了一个强大的框架,还为性能监控、故障诊断和动态代码修改等领域带来了革命性的变革。本文旨在全面解析Java Agent技术的应用场景以及实现方式,特别是静态加载模式和动态加载模式这两种关键模式。
1391 0
|
7月前
|
监控 Java 数据库
Zabbix【部署 05】 Docker部署Zabbix Server Agent Agent2 Web interface及 Java-Gate-Way(详细启动脚本及踩坑记录)不定时更新
Zabbix【部署 05】 Docker部署Zabbix Server Agent Agent2 Web interface及 Java-Gate-Way(详细启动脚本及踩坑记录)不定时更新
574 0
|
Java 安全
JavaAgent 简单例子
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/catoop/article/details/51034739 JavaAgent 是JDK 1.5 以后引入的,也可以叫做Java代理。
911 0
|
7天前
|
安全 Java API
java如何请求接口然后终止某个线程
通过本文的介绍,您应该能够理解如何在Java中请求接口并根据返回结果终止某个线程。合理使用标志位或 `interrupt`方法可以确保线程的安全终止,而处理好网络请求中的各种异常情况,可以提高程序的稳定性和可靠性。
37 6
|
22天前
|
设计模式 Java 开发者
Java多线程编程的陷阱与解决方案####
本文深入探讨了Java多线程编程中常见的问题及其解决策略。通过分析竞态条件、死锁、活锁等典型场景,并结合代码示例和实用技巧,帮助开发者有效避免这些陷阱,提升并发程序的稳定性和性能。 ####
|
20天前
|
存储 监控 小程序
Java中的线程池优化实践####
本文深入探讨了Java中线程池的工作原理,分析了常见的线程池类型及其适用场景,并通过实际案例展示了如何根据应用需求进行线程池的优化配置。文章首先介绍了线程池的基本概念和核心参数,随后详细阐述了几种常见的线程池实现(如FixedThreadPool、CachedThreadPool、ScheduledThreadPool等)的特点及使用场景。接着,通过一个电商系统订单处理的实际案例,分析了线程池参数设置不当导致的性能问题,并提出了相应的优化策略。最终,总结了线程池优化的最佳实践,旨在帮助开发者更好地利用Java线程池提升应用性能和稳定性。 ####
|
22天前
|
缓存 Java 开发者
Java多线程编程的陷阱与最佳实践####
本文深入探讨了Java多线程编程中常见的陷阱,如竞态条件、死锁和内存一致性错误,并提供了实用的避免策略。通过分析典型错误案例,本文旨在帮助开发者更好地理解和掌握多线程环境下的编程技巧,从而提升并发程序的稳定性和性能。 ####
下一篇
DataWorks