java-11 - 如何在多个线程上追逐 JFR 事件
问题描述
我正在努力使用自定义 JFR 事件对异步 servlet 请求处理进行建模。我面临的挑战是,在异步处理中,一个请求可能会被#dispatch()
编辑多次。这意味着整个请求处理链可能会被执行多次,有时会在不同的线程中执行。如何使用自定义 JFR 事件对此进行建模?
对我有帮助的是“父”事件的概念(可能在不同的线程中)或事件的暂停和恢复。
编辑
稍微说明一下这个问题。处理异步请求可能需要 100 秒的挂钟时间。然而,在一个方法中,实际处理可能仅在 4 秒的用户时间内发生Servlet#service()
:
- 线程A中的第二个0-1,
Servlet#service()
方法返回,AsyncContext
开始 - 线程 B 中的第二个 10-11,
Servlet#service()
方法返回,AsyncContext
开始 - 线程 A 中的第二个 80-81,
Servlet#service()
方法返回,AsyncContext
开始 - 线程 C 中的第二个 99-100,
Servlet#service()
方法返回
我只对在这三个线程中为这四个持续时间生成事件感兴趣,然后将它们与单个请求相关联。
解决方案
您可以将线程字段添加到事件
public class MyEvent extends Event [
@Label("Start Thread")
@TransitionFrom
private final Thread startThread;
MyEvent(Thread thread) {
this.startThread = thread;
}
]
当您提交事件时,将存储结束线程。
如果您想通过多个线程跟踪事件,则需要为每个线程创建一个事件并具有一个 id,以便您可以了解流程。
class MyEvent extends Event {
@Label("Transition id");
long id;
}
如果您愿意,您可以创建一个关系 id 来描述关系,并且 JMC 应该能够提示(在上下文菜单等中)事件之间存在关系。
@Label("Transition Id")
@Relational
@Target({ ElementType.FIELD })
@Retention(RetentionPolicy.RUNTIME)
@interface TransitionId {
}
如果您不想重复自己,可以在基类的方法中编写上述功能,您可以为事件访问的每个新线程调用该方法。
abstract AbstractTransition extends Event {
@TransitionId
@Label("Transition Id")
private long id;
public void setTransitionId(long id) {
this.id = id;
}
}
没有其他方法可以做到这一点。
JVM 不可能知道事件对象在哪个线程中,或者应该记录哪些线程。用户需要为每个应该被触及的线程提供至少一个方法调用(连同一些上下文)。
推荐阅读
- c# - chromedriver 中的视频缓冲
- api - 将基于角色的访问控制 (RBAC) 方法置于 API 网关层之外
- ios - AVAssetWriter 编解码器类型 hevc
- python - 如何使用返回列表作为另一个函数的输入的函数?
- javascript - 如何使用 i18nextBrowserLanguageDetector 的结果
- scala - Scala中的矩阵乘法
- jenkins - 自动部署 Jenkins,Payara
- javascript - 调用服务将未翻译的文本保存在 ngx-translate 库中时,但我错了
- android - 如何使用 bigquery 选择列拆分的最后一个索引
- html - 闪亮应用的导航栏干扰 rmarkdown 网页的导航栏