首页 > 解决方案 > Java 飞行记录中的读/写计数究竟代表什么?

问题描述

所以,我在高层的情况是调查 SNAT 端口耗尽的来源。在我们的日志中没有任何问题的迹象,我们设法使用 JFR 分析找到的唯一线索是这个读取计数(来自 JDK Mission Control 的屏幕截图)。这是在大约 20 分钟的时间范围内记录的。

在此处输入图像描述

根据我们的日志,我们只做了大约 70 个 HTTP 请求;Azure 中的 SNAT 连接计数指标在同一时期显示每分钟大约 1.4k。

在此处输入图像描述

我如何解释 JFR 中的这个计数?就 TCP 而言,它究竟代表什么?我找不到任何好的解释。

我们使用 Jersey HTTP 客户端,带有 ApacheConnector,PoolingHttpClientConnectionManagerBuilder每条路由最多 10 个连接。

标签: javatcpazure-load-balancerjfr

解决方案


计数是发出的事件数,即 Socket Read 或 Socket Write。默认情况下,仅发出超过 20 毫秒的事件。您可以将阈值设置为 0 毫秒以获取所有事件,但请注意开销可能很大并且文件可能会变得很大。

有两种方法可以更改设置:

1.使用江铃

在录制向导中设置 I/O 阈值,或使用 Window -> Template Manager 创建自定义 .jfc 并在命令行中启动它:

$ java -XX:StartFlightRecording:settings=my.jfc ...

或者

$ jcmd <pid> JFR.start settings=my.jfc ...

2. 手动编辑 .jfc 文件。

如果您不使用 JMC 开始录制,请将 JAVA_HOME/lib/jfr 中的 default.jfc 文件复制到 custom.jfc 文件中,并将 jdk.SocketRead 和 jdk.SocketWrite 事件的阈值设置为 0 毫秒。

<event name="jdk.SocketRead">
  <setting name="enabled">true</setting>
  <setting name="stackTrace">true</setting>
  <setting name="threshold" control="socket-threshold">0 ms</setting>
</event>

<event name="jdk.SocketWrite">
  <setting name="enabled">true</setting>
  <setting name="stackTrace">true</setting>
  <setting name="threshold" control="socket-threshold">0 ms</setting>
</event>

JDK 17

如果您使用的是 JDK 17 或更高版本,您还可以使用 JAVA_HOME/bin/jfr 工具。

$ jfr configure --interactive

按 Enter 直到向导询问 Socket I/O Threshold,键入 0 ms 并按 Enter 直到写入 custom.jfc 文件。然后像这样使用它:

$ java -XX:StartFlightRecording:settings=custom.jfc ..

或直接在命令行上指定 I/O 阈值:

$ java -XX:StartFlightRecording:socket-threshold=0ms ...

$ jcmd <pid> JFR.start socket-threshold=0m 

推荐阅读