首页
/ 推荐使用 JfrUnit:JUnit 扩展,用于断言 JDK Flight Recorder 事件

推荐使用 JfrUnit:JUnit 扩展,用于断言 JDK Flight Recorder 事件

2024-05-21 12:50:20作者:蔡丛锟

性能测试的革新者

在软件开发中,单元测试已经成为保证功能正确性的标准实践。然而,通过自动化测试来发现性能退化(如增加延迟、降低吞吐量)却是一项更具挑战的任务。传统的基于具体请求运行时的断言方法在虚拟化或容器化的 CI 环境中容易受到其他任务并发负载的影响。

JfrUnit 正是为此场景而设计,它是一个 JUnit 的扩展,允许您对应用程序发出的 JDK Flight Recorder(JFR)事件进行断言。这个创新工具提供了一种全新的视角,不仅关注如延迟和吞吐量这样的直接性能指标,而是通过 JFR 事件来间接评估可能影响这些指标的因素,例如内存分配、数据库 I/O 和执行的 SQL 语句数量。从一个基准线出发,如果这些断言在未来失败,就可能是代码变更引入了更高的垃圾收集压力、不必要的数据检索,或者常见的 SQL 问题(如 N+1 个 SELECT 语句)导致的性能退化。

JfrUnit 使您能够在标准 JUnit 测试中以可靠且环境独立的方式识别并分析这些问题,从而在它们成为生产环境中的性能问题之前及时发现。

学习更多资源

以下是一些详细介绍 JfrUnit 及其性能回归测试方法的资源:

  1. 走向持续性能回归测试
  2. 推出 JfrUnit 1.0.0.Alpha1
  3. 使用 JfrUnit 断言 JDK Flight Recorder 事件
  4. JfrUnit 连续性能回归测试
  5. 用 Flight Recorder、JMC Agent 和 JfrUnit 保持 SQL 的检查

使用

JfrUnit 需要运行时环境为 OpenJDK 16 或更高版本。支持 JDK 11 的工作已经在路线图上,但在此版本下,JfrUnit 不再依赖 JFR 事件流,而是从磁盘上的记录文件读取 JFR 事件。欢迎贡献这一更改的 Pull Request。

您可以从 Maven 中央仓库获取 JfrUnit;只需将以下依赖添加到您的项目 pom.xml 文件中:

...
<dependency>
  <groupId>org.moditect.jfrunit</groupId>
  <artifactId>jfrunit-core</artifactId>
  <version>1.0.0.Alpha2</version>
  <scope>test</scope>
</dependency>
...

或者,您可以从源代码构建 JfrUnit(参见下文),以便拉取最新的变更。

然后,您可以像这样实现期望特定 JFR 事件的测试:

import org.moditect.jfrunit.*;

import static org.moditect.jfrunit.JfrEventsAssert.*;
import static org.moditect.jfrunit.ExpectedEvent.*;
import org.moditect.jfrunit.events.JfrEventTypes;

@JfrEventTest
public class JfrTest {

    public JfrEvents jfrEvents = new JfrEvents();

    @Test
    @EnableEvent(GarbageCollection.EVENT_NAME)
    @EnableEvent(ThreadSleep.EVENT_NAME)
    public void shouldHaveGcAndSleepEvents() throws Exception {
        System.gc();
        Thread.sleep(1000);

        jfrEvents.awaitEvents();

        assertThat(jfrEvents).contains(JfrEventTypes.GARBAGE_COLLECTION);
        assertThat(jfrEvents).contains(
                JfrEventTypes.THREAD_SLEEP.withTime(Duration.ofMillis(1000)));
    }
}

对于使用 @QuarkusTest 注解的 Quarkus 应用程序,不需要(甚至不应)添加 @JfrEventTest 注解。相反,Quarkus 测试框架会自动处理管理 JFR 录制所需的回调。

@EnableEvent 注解用于启用应捕获的一个或多个 JFR 事件类型。星号字符 (*) 可用作通配符匹配多个类型。

@Test
@EnableEvent("jdk.GC*")
@EnableEvent("jdk.G1*")
public void someTest() throws Exception { ... }

这将捕获 jdk.GCHeapSummaryjdk.GCPhasePausejdk.G1GarbageCollection 等事件。所有内置 JFR 事件类型的完整列表可以在此处找到。

另外,您还可以使用 @EnableConfiguration 注解指定 JFR 配置文件的名称,例如 "default" 或 "profile":

@Test
@EnableConfiguration("default")
public void someTest() throws Exception { ... }

JFR 配置文件位于 $JAVA_HOME/bin/jfr 目录下。

使用 Spock 框架

您也可以使用 Spock 框架 编写 JfrUnit 测试:

import org.moditect.jfrunit.JfrEvents
import spock.lang.Specification

import java.time.Duration

class JfrSpec extends Specification {

    JfrEvents jfrEvents = new JfrEvents()

    @EnableEvent('jdk.GarbageCollection')
    @EnableEvent('jdk.ThreadSleep')
    def 'should Have GC And Sleep Events'() {
        when:
        System.gc()
        sleep(1000)

        then:
        jfrEvents['jdk.GarbageCollection']
        jfrEvents['jdk.ThreadSleep'].withTime(Duration.ofMillis(1000))
    }
}

正如您所见,您可以使用自定义 DSL 来检查预期状态。

构建

该项目的构建要求 OpenJDK 16 或更高版本。使用 Apache Maven 进行构建。运行以下命令以构建项目:

mvn verify

运行以下命令将 JAR 安装到本地 Maven 仓库:

mvn install

许可证

此代码库遵循 Apache 许可证 2.0 版发布。


JfrUnit 提供了一个强大的工具,可以帮助开发者在早期阶段发现潜在的性能问题,并确保代码质量。结合其易用性和灵活性,无论是 Java 标准测试还是采用 Spock 框架的测试,都值得您的团队尝试。立即加入我们的行列,让性能回归测试变得更加简单和高效!

登录后查看全文
热门项目推荐

热门内容推荐

最新内容推荐

项目优选

收起
openHiTLS-examplesopenHiTLS-examples
本仓将为广大高校开发者提供开源实践和创新开发平台,收集和展示openHiTLS示例代码及创新应用,欢迎大家投稿,让全世界看到您的精巧密码实现设计,也让更多人通过您的优秀成果,理解、喜爱上密码技术。
C
53
465
kernelkernel
deepin linux kernel
C
22
5
openHiTLSopenHiTLS
旨在打造算法先进、性能卓越、高效敏捷、安全可靠的密码套件,通过轻量级、可剪裁的软件技术架构满足各行业不同场景的多样化要求,让密码技术应用更简单,同时探索后量子等先进算法创新实践,构建密码前沿技术底座!
C
349
381
nop-entropynop-entropy
Nop Platform 2.0是基于可逆计算理论实现的采用面向语言编程范式的新一代低代码开发平台,包含基于全新原理从零开始研发的GraphQL引擎、ORM引擎、工作流引擎、报表引擎、规则引擎、批处理引引擎等完整设计。nop-entropy是它的后端部分,采用java语言实现,可选择集成Spring框架或者Quarkus框架。中小企业可以免费商用
Java
7
0
openGauss-serveropenGauss-server
openGauss kernel ~ openGauss is an open source relational database management system
C++
132
185
RuoYi-Vue3RuoYi-Vue3
🎉 (RuoYi)官方仓库 基于SpringBoot,Spring Security,JWT,Vue3 & Vite、Element Plus 的前后端分离权限管理系统
Vue
876
517
Cangjie-ExamplesCangjie-Examples
本仓将收集和展示高质量的仓颉示例代码,欢迎大家投稿,让全世界看到您的妙趣设计,也让更多人通过您的编码理解和喜爱仓颉语言。
Cangjie
336
1.1 K
ohos_react_nativeohos_react_native
React Native鸿蒙化仓库
C++
179
264
cherry-studiocherry-studio
🍒 Cherry Studio 是一款支持多个 LLM 提供商的桌面客户端
TypeScript
610
59
note-gennote-gen
一款跨平台的 Markdown AI 笔记软件,致力于使用 AI 建立记录和写作的桥梁。
TSX
83
4