阿里云 ARMS 应用监控重磅支持 Java 21

作者:牧思 & 山猎

前言

今年的 9 月 19 日,作为最新的 LTS (Long Term Support) Java 版本,Java 21 正式 GA,带来了不少重量级的更新,详情请参考 The Arrival of Java 21 [ 1] 。虽然目前 Java 11 和 Java 17 都还没有在国内大规模普及,Java 8 依然占据主流地位,但及时更新 JDK 版本可以为开发者带来许多重要的价值,包括应用程序性能和稳定性上的提升,以及可以帮助提升生产力的新功能。作为亚洲地区最有影响力的可观测以及 APM 服务提供方,阿里云 ARMS 团队也第一时间响应 Java 21 的 GA 发布,率先对 Java 21 进行了适配,帮助用户更好的观测 Java 21 应用!

Java 21 主要新特性

Java 21 带来了 15 个新特性,包括虚拟线程、分代式 ZGC 等重磅功能,以及其他方面的优化,让我们先睹为快,体验一下这些新特性:

1. 虚拟线程

虚拟线程 (Virtual Threads) 绝对是 Java 21 中最重量级的新特性,此前在 Java 版本中,每一个 java.lang.Thread 对象都只对应一个操作系统内核中的线程,而线程在操作系统又是一种相对昂贵的系统资源:线程的创建、切换、销毁等操作都需要进入到内核态。在高并发的场景下,如果创建大量线程来处理请求,将会导致多线程被频繁的挂起和切换,非常消耗系统资源。

虚拟线程则是一种轻量级的用户态线程,与传统线程由 OS 调度运行不同,虚拟线程是由 JDK 底层调度运行的,其创建、调度、销毁等操作全部由用户空间的库函数来完成,也就是说虚拟线程与内核中的线程的对应关系是 M:N 的,如图 1 所示:

图片

图 1:线程与虚拟线程关系图

因此,在高并发场景下,创建大量虚拟线程来处理请求的开销,相比创建大量线程来说将会降低很多。在 Java 程序中,线程与虚拟线程的对比如表 1 所示:

图片

表 1:线程与虚拟线程的对比表

在 Java 21 中,可以通过以下几种方法创建虚拟线程并运行:

// 方式一:
Thread vt = Thread.startVirtualThread(() -> {});
// 方式二:
Thread.ofVirtual().unstarted(() -> {});
vt.start();
// 方式三:
ThreadFactory tf = Thread.ofVirtual().factory();
Thread vt = tf.newThread(() -> {});
vt.start();
// 方式四:
ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor();
ThreadFactory tf = Thread.ofVirtual().factory();
Thread vt = tf.newThread(() -> {});
executor.submit(vt);

2. 分代式 ZGC

在 Java 21 中,增加了对 ZGC 的分代支持 (Generational ZGC) 以提高垃圾回收的性能。在此之前,ZGC 是没有分代概念的,每次运行时都会去收集所有的对象,不会考虑对象的年龄。但根据分代收集理论,绝大部分对象都是朝生夕灭的,并且熬过越多次垃圾收集过程的对象会越难死亡。清理年轻代对象需要的资源更少,能清理出更多的内存;反之,清理老年代对象需要的资源更多,能清理出的内存更少。这就意味着,ZGC 可以基于分代收集理论,更进一步的提升垃圾回收效率。于是在 Java 21,分代收集机制被引入,以更频繁的收集年轻代对象,这对于使用 ZGC 的 Java 应用的性能提升,有非常大的帮助。

在 Java 21 上使用 ZGC,首先需要在 Java 启动命令中加入 -XX:+UseZGC 选项开启 ZGC。默认情况下,添加该选项后启用的是非分代的 ZGC,如需使用分代式 ZGC,则需要再额外添加 -XX:+ZGenerational 选项。

# 使用分代式ZGC
$ java -XX:+UseZGC -XX:+ZGenerational ...

3. 其他特性

除了虚拟线程和分代 ZGC,Java 21 还引入了其他有意思的特性,比如:

  • 允许使用_字符声明未命名变量,类似 go 语言中的_。
  • 允许使用匿名类与匿名实例的 main 方法,可以利用如下所示的方式执行 main 函数。
void main() {System.out.println("Hello, World!");
}

具体的其它特性,可以参考:openjdk.org/projects/jdk/21/

使用 ARMS 监控 Java 21 应用

ARMS 最新的 3.1.0 版本探针中,我们对 Java 21 进行了支持,开发者可以参考此文开启 Java 21 应用的可观测之旅。

编写 Java 21 应用

首先需要下载安装 JDK 21,可以从 Oracle 等厂商的官网下载安装,也可以通过 sdkman 等三方工具进行下载安装。

安装完 JDK 21 后,可以参考以下代码,编写一个简单的 SpringBoot 3.x 应用,该应用中使用了 Java 21 的 Record Patterns 特性,帮助用户用简洁的语法解构 Java 中的 record 对象:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.0.6</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>xxx</groupId><artifactId>xxx</artifactId><version>xxx</version><name>xxx</name><properties><java.version>21</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>
@SpringBootApplication
public class DemoApplication {public static void main(String[] args) {SpringApplication.run(DemoApplication.class, args);}record Point(int x, int y) {}@RestControllerstatic class DemoController {@RequestMapping("/demo")String demo(@RequestParam String type) {Object object = null;if ("record".equals(type)) {object = new Point(1, 2);} else {object = "object";}return solve(object);}private String solve(Object object) {if (object instanceof Point(int x, int y)) {return "Point: " + x + ":" + y;}return "Invalid Point";}}
}

接入 ARMS

对于 Java 应用,ARMS 提供了多种便捷接入方式,您可以参考应用监控接入概述 [ 2] 进行接入。对于运行在阿里云容器服务 ACK [ 3] 中的应用,可以拥有最简单的接入方式:基于 Pilot 模式实现探针的自动注入以及配置,无需修改镜像,只需要在应用 Yaml 中加入 2 个 Pod Label 就能接入 ARMS。

首先为 ACK 集群安装 ack-onepilot 组件,如图2所示:

图片

图 2:安装 ack-onepilot

安装完成之后,在 ACK 集群内创建 Java 应用,并在 pod 的 spec.template.metadata 字段中添加图 3 中的两个 Pod 标签。其中 armsPilotCreateAppName 代表接入到 ARMS 的应用名,可以和 Deployment 名保持一致,armsPilotAutoEnable 设置为 on 即可。您也可以直接编辑 Deployment 的 Yaml 文件添加 Pod 标签。

图片

图 3:添加标签

应用成功部署后,在 ACK 控制台上会展示 ARMS 控制台链接,如图 4 所示,点击就能跳转到 ARMS 控制台。

图片

图 4:ARMS 控制台操作选项

Java 启动应用后,应用也将会打印如图 5 所示的日志,说明应用已经挂载上 ARMS 的探针。

图片

图 5:JDK21 应用启动日志

说明:ARMS 对 Java 21 的支持依赖于 3.1.0 版本探针,截至本文发表之日,3.1.0 版本探针还没有正式发布,您可以钉钉扫码加入 ARMS 支持 Java 21 体验群,获取 3.1.0 版本探针。在 3.1.0 版本正式发布后,您就可以直接在 ARMS 官网下载最新版探针,或者通过通过 Pilot 模式自动获取 3.1.0 版本探针。

  • ARMS 支持 Java 21 体验钉钉群群号:54565000535*

查看监控数据

应用启动成功后,请求 /demo 接口,将会得到图 7 所示的响应:

图片

图 7:/demo 接口响应

在请求完 /demo 接口后,可前往 ARMS 控制台的应用列表页面点击进入应用的监控页面,如图 8 所示,或者直接在 ACK 控制台上通过转接跳转进入 ARMS 控制台。

图片

图 8:ARMS 控制台应用列表

可以看到,ARMS 已经成功识别到 Java 21 应用,并收集相关可观测数据,如图 9-11 所示,这些观测数据可帮助用户快速洞悉系统运行状况,加速线上问题排查效率,提升业务运行稳定性。更多 ARMS 应用监控的重要功能,比如智能洞察、调用链分析、CPU &内存诊断,请参考 ARMS 应用监控帮助文档 [ 4]

图片

图 9:ARMS 应用元信息

图片

图 10:ARMS 应用接口调用信息

图片

图 11:ARMS 应总览信息

ARMS 3.X 版本探针新特性一览

  • 大幅提升了对主流开源框架的埋点覆盖度,支持对 Reactor Netty 和 Vert.x 等异步框架的完整耗时统计,增加了 OceanBase 的组件支持,同时优化了PostgreSQL、Kafka 等组件的埋点设计,提供了更加精准、更加丰富的指标和 Span 数据。详情请参考 ARMS 支持的 Java 组件和框架 [ 5]
  • 性能优化,应用接入更加轻量化,更加无感;4C8G 规格的容器场景下,挂载探针带来的额外 CPU 开销相较过往版本降低 50%,使用异步框架的场景 CPU 开销优化幅度达到 65%,性能表现更加良好;启动时间大幅度优化,探针挂载启动耗时降低到 5 秒内,通过容器方式接入,init-container 启动耗时降低到 6 秒内,探针整体启动耗时缩减 10s+;
  • 支持代码热点功能。一般的 Tracing 系统由于只能对主流开源软件框架中的核心方法进行埋点,当耗时位置出现在 Tracing 埋点缺失的用户业务逻辑时,在最终的调用链中会出现一段较长的耗时无法对应到具体的代码执行方法,从而导致无法对业务逻辑耗时进行准确的判断的问题。

图片**

图 12: Tracing 监控盲区示例图

ARMS 代码热点功能在业界知名的开源持续剖析工具 Async Profiler [ 6] 基础上,通过关联调用链中的 TraceId & SpanId 信息提供了调用链级别的 On & Off-CPU 火焰图,可有效对 Tracing 的监控盲区细节进行还原,帮助用户诊断各类常见的慢调用链问题。

图片**

图 13: ARMS 支持代码热点功能效果图

更多功能介绍和使用细节请参考慢调用链诊断利器-ARMS 代码热点。

ARMS 代码热点体验交流钉钉群群号:22560019672

更多 ARMS 产品家族的详细介绍,请参考 ARMS 官方帮助文档 [ 7]

参考资料:

[1] https://openjdk.org/projects/jdk/21/

[2] https://openjdk.org/jeps/439

[3] https://openjdk.org/jeps/440

[4] https://blogs.oracle.com/java/post/the-arrival-of-java-21

相关链接:

[1] The Arrival of Java 21

https://blogs.oracle.com/java/post/the-arrival-of-java-21

[2] 应用监控接入概述

https://help.aliyun.com/zh/arms/application-monitoring/getting-started/overview

[3] 容器服务 ACK

https://www.aliyun.com/product/kubernetes**

[4] ARMS 应用监控帮助文档

https://help.aliyun.com/zh/arms/application-monitoring/product-overview/functional-characteristics

[5] ARMS 支持的 Java 组件和框架

https://help.aliyun.com/zh/arms/application-monitoring/developer-reference/java-components-and-frameworks-supported-by-arms

[6] Async Profiler

https://github.com/async-profiler/async-profiler

[7] ARMS 官方帮助文档

https://help.aliyun.com/zh/arms/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/241670.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Hugging Face】解决BART模型调用时KeyError: ‘new_zeros‘的问题

错误代码&#xff1a; tokenizer AutoTokenizer.from_pretrained("philschmid/bart-large-cnn-samsum") model AutoModelForSeq2SeqLM.from_pretrained("philschmid/bart-large-cnn-samsum")model.eval() model.to("cuda") loss 0 for i in …

前缀和+单调双队列+贪心:LeetCode2945:找到最大非递减数组的长度

本文涉及知识点 C算法&#xff1a;前缀和、前缀乘积、前缀异或的原理、源码及测试用例 包括课程视频 单调双队列 贪心 题目 给你一个下标从 0 开始的整数数组 nums 。 你可以执行任意次操作。每次操作中&#xff0c;你需要选择一个 子数组 &#xff0c;并将这个子数组用它所…

python脚本 ssh工具 ssh上传文档 选择文档并上传到ssh服务器

此文分享一个python脚本,用于快速的定位、选择文档,并将其上传到指定的ssh服务器。 效果演示 🔥完整演示效果 👇第一步,显然,我们需要选择功能 👇第二步,我们需要定位并选择需要上传的文档 👇第三步,确认我们需要上传文档的ssh服务器 👇第四步,定位、选择…

Socket与Server通讯

ByteArrayOutputStream 对byte类型数据进行写入的类 &#xff0c;自动扩容&#xff0c;相当于一个中间缓冲层&#xff0c;将类写入到文件等其他outputStream。它是对字节进行操作&#xff0c;属于内存操作流 import java.io.ByteArrayOutputStream; import java.io.OutputStrea…

gulp和webpack的区别

Gulp和Webpack都是前端开发中常用的工具&#xff0c;但它们在功能和定位上存在一些差异。 首先&#xff0c;Gulp是一个工具链和构建工具&#xff0c;强调的是前端开发流程。它可以配合各种插件进行js压缩、css压缩、less编译等操作&#xff0c;实现自动化工作。在Gulp中&#…

Qt的简单游戏实现提供完整代码

文章目录 1 项目简介2 项目基本配置2.1 创建项目2.2 添加资源 3 主场景3.1 设置游戏主场景配置3.2 设置背景图片3.3 创建开始按钮3.4 开始按钮跳跃特效实现3.5 创建选择关卡场景3.6 点击开始按钮进入选择关卡场景 4 选择关卡场景4.1场景基本设置4.2 背景设置4.3 创建返回按钮4.…

2024 十大AI预测

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

偏最小二乘法中的“偏”的含义

问&#xff1a;偏最小二乘法中的“偏”是指什么意思&#xff1f; 答&#xff1a;偏最小二乘法&#xff08;Partial Least Squares&#xff0c;简称PLS&#xff09;中的“偏”指的是这种方法部分地考虑了响应变量的信息来进行预测变量的提取。与传统的最小二乘法相比&#xff0c…

Python 时间处理与数据分析利器:深入剖析 Arrow 模块的优势

写在开头 时间在数据分析中扮演着至关重要的角色&#xff0c;而选择适当的时间处理模块对于提高代码效率和可读性至关重要。本文将深入介绍 Arrow 模块&#xff0c;探讨其相对于其他时间处理模块的优势&#xff0c;以及在数据分析中的实际应用。 1. Arrow 模块概览 Arrow 模…

模式识别与机器学习(十一):Bagging

1.原理 Bagging [Breiman, 1996a] 是井行式集成学习方法最著名的代表.从名字即可看出&#xff0c;它直接基于自助采样法(bootstrap sampling)。给定包含m 个样本的数据集&#xff0c;我们先随机取出一个样本放入采样集中&#xff0c;再把该样本放回初始数据集&#xff0c;使得…

【JAVA】分布式链路追踪技术概论

目录 1.概述 2.基于日志的实现 2.1.实现思想 2.2.sleuth 2.2.可视化 3.基于agent的实现 4.联系作者 1.概述 当采用分布式架构后&#xff0c;一次请求会在多个服务之间流转&#xff0c;组成单次调用链的服务往往都分散在不同的服务器上。这就会带来一个问题&#xff1a;…

编程语言学习目录

文章目录 一篇入门系列C#Fortranerlang/elixirR语言Go语言Rust语言 一篇入门系列 文本处理神器awkbash shellclojure极简教程F#语言入门教程量子编程初步——Q#入门1小时快速入门Python如何用两个晚上教会妹纸PythonVIM使用进阶&#xff1a;VIM脚本初步写给Matlab用户的Python…

网络基础知识制作网线了解、集线器、交换机与路由器

目录 一、网线的制作 1.1、材料 1.2、网线的标准类别 二、集线器、交换机介绍 2.1、概念&#xff1a; 2.2、OSI七层模型 2.3、TCP/IP四层 三、路由器的配置 3.1、概念 3.2、四个模块 1、 网络状态 2、设备管理 3、应用管理 无人设备接入控制 无线桥接 信号调节…

7-8 旅行售货员

7-8 旅行售货员 某售货员要到若干城市去推销商品&#xff0c;已知各城市之间的路程(或旅费)。他要选定一条从驻地出发&#xff0c;经过每个城市一遍&#xff0c;最后回到驻地的路线&#xff0c;使总的路程&#xff08;或总旅费&#xff09;最小。 输入格式: 第一行为城市数n…

VS(Visual Studio)更改文件编码

vs默认编码是GB2312,更改为UTF-8 工具->自定义

【数据结构入门精讲 | 第十篇】考研408排序算法专项练习(二)

在上文中我们进行了排序算法的判断题、选择题的专项练习&#xff0c;在这一篇中我们将进行排序算法中编程题的练习。 目录 编程题R7-1 字符串的冒泡排序R7-1 抢红包R7-1 PAT排名汇总R7-2 统计工龄R7-1 插入排序还是堆排序R7-2 龙龙送外卖R7-3 家谱处理 编程题 R7-1 字符串的冒…

Java进阶(第六期): Arrays类(数组工具)、冒泡排序、选择排序、二分查找、【正则表达式】、Java正则爬取信息

文章目录 一、Arrays1.1代码示例&#xff1a; 二、冒泡排序2.1 代码示例 三、选择排序3.1 代码示例 四、二分查找4.1 代码示例 &#xff08;这里采用乱序数组&#xff09; 五、正则表达式5.1 正则表达式的基本使用5.2 正则表达式爬取信息练习 Java进阶&#xff08;第六期&#…

吉利银河L6 车机等问题交流/记录

车机低电量重启问题 动力电池低电量(2km) 时,播放视频,会大概5min的周期,做周期性的车机重启,我点了停车发电,让发动机发电才避免重启. app闪退 app不可见 你只能安装他应用商店少的可怜的app 自己安装的他不显示,就算你把他显示了,也可能播放视频中出现app闪退现象 车机…

OpenCV学习笔记 - 使用 OpenCV 检测运动的最简单方法

一、运动检测 运动检测是检测视频序列中移动对象的过程。在计算机视觉中,它是检测视频帧中像素级变化的过程。我们可以用它来发现现实世界中的新对象,甚至执行与类无关的对象检测,这在地理空间分析、客户分析、监视、自治和其他相关领域非常有用。 如何检测视频中的运动?这…

Git的总体认知与具体实现

GIt概念 是一种分布式控制管理器 tips:敏捷开发 -> 先上线&#xff0c;后续开发再继续开发 集中式和分布式 集中式的版本控制系统每次在写代码时都需要从服务器中拉取一份下来&#xff0c;并且如果服务器丢失了&#xff0c;那么所有的就都丢失了&#xff0c;你本机客户端仅…