Java
与 Pyroscope 集成的 Java Profiler 为 Java 应用程序中的性能分析提供了一个全面的解决方案。它提供实时的洞察力,使开发人员能够有效地理解和优化其 Java 代码库。此工具对于提高应用程序响应速度、降低资源消耗以及确保 Java 环境中的顶级性能至关重要。
注意
请参阅可用性能剖析类型,查看每种语言支持的性能剖析类型列表。
开始之前
要捕获和分析性能剖析数据,您需要一个托管的 Pyroscope OSS 服务器或一个托管的 带有 Grafana Cloud Profiles 的 Pyroscope 实例(需要一个免费的 Grafana Cloud 帐户)。
Pyroscope 服务器可以是用于开发的本地服务器,也可以是用于生产的远程服务器。
将 Java 性能剖析添加到您的应用程序
Java 集成以单个 jar 文件 (pyroscope.jar
) 或 Maven 包的形式分发。支持的平台包括
- Linux on x64
- Linux on ARM64
- MacOS on x64
- MacOS on ARM64
访问 GitHub releases 页面下载最新版本的 pyroscope.jar
。
最新版本也可在 Maven Central 上获取。
配置 Java 客户端
您可以从应用程序的代码启动 Pyroscope,也可以将其作为 javaagent 附加。
从应用程序的 Java 代码启动 Pyroscope
首先,添加 Pyroscope 依赖项
<dependency>
<groupId>io.pyroscope</groupId>
<artifactId>agent</artifactId>
<version>0.17.0</version>
</dependency>
implementation("io.pyroscope:agent:0.17.0")
将以下代码添加到您的应用程序
PyroscopeAgent.start(
new Config.Builder()
.setApplicationName("ride-sharing-app-java")
.setProfilingEvent(EventType.ITIMER)
.setFormat(Format.JFR)
.setServerAddress("http://pyroscope-server:4040")
.build()
);
import io.pyroscope.javaagent.PyroscopeAgent;
import io.pyroscope.javaagent.config.Config;
import io.pyroscope.javaagent.EventType;
import io.pyroscope.http.Format;
@PostConstruct
public void init() {
PyroscopeAgent.start(
new Config.Builder()
.setApplicationName("ride-sharing-app-java")
.setProfilingEvent(EventType.ITIMER)
.setFormat(Format.JFR)
.setServerAddress("http://pyroscope-server:4040")
// Optionally, if authentication is enabled, specify the API key.
// .setBasicAuthUser("<User>")
// .setBasicAuthPassword("<Password>")
// Optionally, if you'd like to set allocation threshold to register events, in bytes. '0' registers all events
// .setProfilingAlloc("0")
.build()
);
}
您还可以选择性地替换某些 Pyroscope 组件
PyroscopeAgent.start(
new PyroscopeAgent.Options.Builder(config)
.setExporter(snapshot -> {
// Your custom export/upload logic may go here
// It is invoked every 10 seconds by default with snapshot of
// profiling data
})
.setLogger((l, msg, args) -> {
// Your custom logging may go here
// Pyroscope does not depend on any logging library
System.out.printf((msg) + "%n", args);
})
.setScheduler(profiler -> {
// Your custom profiling schedule logic may go here
})
.build()
);
将 Pyroscope 作为 javaagent
启动
要开始分析 Java 应用程序,请使用 pyroscope.jar
javaagent
运行您的应用程序
export PYROSCOPE_APPLICATION_NAME=my.java.app
export PYROSCOPE_SERVER_ADDRESS=http://pyroscope-server:4040
java -javaagent:pyroscope.jar -jar app.jar
将性能剖析标签添加到 Java 应用程序
您可以将动态标签(labels)添加到性能剖析数据。这些标签可以在 UI 中过滤数据。
动态添加标签
Pyroscope.LabelsWrapper.run(new LabelsSet("controller", "slow_controller"), () -> {
slowCode();
});
您还可以将静态标签(labels)添加到性能剖析数据
Pyroscope.setStaticLabels(Map.of("region", System.getenv("REGION")));
// or with Config.Builder if you start pyroscope with PyroscopeAgent.start
PyroscopeAgent.start(new Config.Builder()
.setLabels(mapOf("region", System.getenv("REGION")))
// ...
.build()
);
配置选项
当您将 Pyroscope 作为 javaagent
启动或通过 Config.build()
获取配置时,Pyroscope 会在多个来源中搜索配置:系统属性、环境变量和 pyroscope.properties
。属性键的名称与环境变量相同,但均为小写,并且下划线 (_
) 替换为句点 (.
)。例如,PYROSCOPE_FORMAT
变为 pyroscope.format
Java 集成支持 JFR 格式,以便能够支持多个事件(JFR 是唯一支持 async-profiler
中的多个事件 的输出格式)。有几个环境变量定义了多事件配置的工作方式
标志 | 描述 |
---|---|
PYROSCOPE_AGENT_ENABLED | 启用代理。默认为 true 。 |
PYROSCOPE_APPLICATION_NAME | 设置应用程序名称。如果未提供,将使用生成的名称。 |
PYROSCOPE_PROFILING_INTERVAL | 设置 CPU 性能剖析的性能剖析采样间隔。默认为 10ms 。 |
PYROSCOPE_FORMAT | 设置性能剖析器输出格式。默认为 collapsed ,但为了支持多种格式,必须将其设置为 jfr 。 |
PYROSCOPE_PROFILER_EVENT | 设置性能剖析器事件。启用 JFR 格式后,此事件指的是可能的 CPU 性能剖析事件之一:itimer 、cpu 、wall 。默认为 itimer 。 |
PYROSCOPE_PROFILER_ALLOC | 设置注册分配事件的阈值,以字节为单位(等效于 async-profiler 中的 --alloc= )。默认值为 "" - 空字符串,表示禁用分配性能剖析。将其设置为 0 将注册每个事件,从而导致显著的 CPU 和网络开销,使其不适合生产环境。我们建议设置 512k 的起始值,并根据需要进行调整。 |
PYROSCOPE_PROFILER_LOCK | 设置注册锁定事件的阈值,以纳秒为单位(等效于 async-profiler 中的 --lock= )。默认值为 "" - 空字符串,表示禁用锁定性能剖析。将其设置为 0 将注册每个事件,从而导致显著的 CPU 和网络开销,使其不适合生产环境。我们建议设置 10 毫秒的起始值,并根据需要进行调整。 |
PYROSCOPE_UPLOAD_INTERVAL | 设置上传性能剖析数据的时间间隔。默认为 10s 。 |
PYROSCOPE_JAVA_STACK_DEPTH_MAX | 设置最大堆栈深度。默认为 2048 。 |
PYROSCOPE_SERVER_ADDRESS | Pyroscope 服务器的地址。默认为 https://127.0.0.1:4040 |
PYROSCOPE_CONFIGURATION_FILE | 设置其他属性配置文件。默认值为 pyroscope.properties 。 |
PYROSCOPE_BASIC_AUTH_USER | HTTP 基本身份验证用户名。默认值为 "" - 空字符串,无身份验证。 |
PYROSCOPE_BASIC_AUTH_PASSWORD | HTTP 基本身份验证密码。默认值为 "" - 空字符串,无身份验证。 |
PYROSCOPE_TENANT_ID | pyroscope 租户 ID,作为 X-Scope-OrgID http 标头传递。默认值为 "" - 空字符串,无租户 ID。 |
PYROSCOPE_HTTP_HEADERS | JSON 格式的额外 HTTP 标头,例如:{"X-Header": "Value"} 。默认值为 {} - 无额外标头。 |
PYROSCOPE_LABELS | 以逗号分隔的 key=value 对的形式设置静态标签。默认值为 "" - 空字符串,无标签。 |
PYROSCOPE_LOG_LEVEL | 确定 Pyroscope 记录器的详细程度。可用选项包括 debug 、info 、warn 和 error 。默认值设置为 info 。 |
PYROSCOPE_PUSH_QUEUE_CAPACITY | 指定摄取队列的大小,该队列在网络中断期间临时将性能剖析数据存储在内存中。默认值设置为 8。 |
PYROSCOPE_INGEST_MAX_TRIES | 设置在发生故障时重试摄取 API 调用的最大次数。值 -1 表示重试将无限期地继续。默认值设置为 8 。 |
PYROSCOPE_EXPORT_COMPRESSION_LEVEL_JFR | 设置应用于上传的 JFR 文件的 GZIP 压缩级别。此选项接受 NO_COMPRESSION 、BEST_SPEED 、BEST_COMPRESSION 和 DEFAULT_COMPRESSION 值。 |
PYROSCOPE_EXPORT_COMPRESSION_LEVEL_LABELS | 操作类似于 PYROSCOPE_EXPORT_COMPRESSION_LEVEL_JFR ,但适用于动态标签部分。默认值设置为 BEST_SPEED 。 |
PYROSCOPE_ALLOC_LIVE | 仅保留具有活动对象的分配样本(在性能剖析会话结束时尚未被收集的对象)。对于查找 Java 堆内存泄漏很有用。默认值为 false |
PYROSCOPE_GC_BEFORE_DUMP | 一个布尔值,当设置为 true 时,在转储性能剖析之前执行 System.gc() 命令。此选项对于实时性能剖析可能很有用,但默认情况下处于禁用状态。 |
将数据发送到 Pyroscope OSS 或 Grafana Cloud Profiles
将以下代码添加到您的应用程序
PyroscopeAgent.start(
new Config.Builder()
.setApplicationName("test-java-app")
.setProfilingEvent(EventType.ITIMER)
.setFormat(Format.JFR)
.setServerAddress("<URL>")
// Set these if using Grafana Cloud:
.setBasicAuthUser("<User>")
.setBasicAuthPassword("<Password>")
// Optional Pyroscope tenant ID (only needed if using multi-tenancy). Not needed for Grafana cloud.
// .setTenantID("<TenantID>")
.build()
);
要配置 Java SDK 以将数据发送到 Pyroscope,请将 <URL>
占位符替换为相应的服务器 URL。这可以是 Grafana Cloud URL 或您自己的自定义 Pyroscope 服务器 URL。
如果您需要将数据发送到 Grafana Cloud,则必须配置 HTTP 基本身份验证。将 <User>
替换为您的 Grafana Cloud 堆栈用户,并将 <Password>
替换为您的 Grafana Cloud API 密钥。
如果您的 Pyroscope 服务器启用了多租户,您将需要配置租户 ID。将 <TenantID>
替换为您的 Pyroscope 租户 ID。
配置示例
以下配置设置了应用程序名称、Pyroscope 格式、性能剖析间隔、事件和锁定。此示例摘自 Pyroscope 存储库中提供的 rideshare
Dockerfile。
ENV PYROSCOPE_APPLICATION_NAME=rideshare.java.push.app
ENV PYROSCOPE_FORMAT=jfr
ENV PYROSCOPE_PROFILING_INTERVAL=10ms
ENV PYROSCOPE_PROFILER_EVENT=itimer
ENV PYROSCOPE_PROFILER_LOCK=10ms
此配置摘录启用了分配和锁定性能剖析
PYROSCOPE_PROFILER_ALLOC=512k
PYROSCOPE_PROFILER_LOCK=10ms
Java 性能剖析示例
查看以下资源以了解有关 Java 性能剖析的更多信息