如何通过多个线程追逐 JFR 事件
How to chase a JFR event over multiple threads
我正在努力为使用自定义 JFR 事件的异步 servlet 请求处理建模。
我面临的挑战是,在异步处理中,一个请求可能会被 #dispatch()
ed 多次。这意味着整个请求处理链可能会执行多次,在不同的线程中间隔一段时间。我如何使用自定义 JFR 事件对其进行建模?
对我有帮助的是 "parent" 事件的概念(可能在不同的线程中)或事件的暂停和恢复。
编辑
稍微说明一下这个问题。异步请求可能需要 100 秒挂钟时间来处理。但是,在 Servlet#service()
方法中,实际处理可能只需要 4 秒的用户时间:
- 线程 A 中的秒 0-1,
Servlet#service()
方法 returns,AsyncContext
已启动
- 线程 B 中的第 10-11 秒,
Servlet#service()
方法 returns,AsyncContext
已启动
- 线程 A 中的第 80-81 秒,
Servlet#service()
方法 returns,AsyncContext
已启动
- 线程 C 中的第 99-100 秒,
Servlet#service()
方法 returns
我只对在这三个线程中为这四个持续时间生成事件感兴趣,然后将它们与单个请求相关联。
问题类似于如何在分布式跟踪器中将跨度和范围的 JFR 事件绑定在一起。
本文可能对您有所帮助:
http://hirt.se/blog/?p=1081
您可以在活动中添加线程字段
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 {
}
如果您不想重复自己的话,您可以将上述功能写在一个基类 class 的方法中,您可以为事件访问的每个新线程调用该方法。
abstract AbstractTransition extends Event {
@TransitionId
@Label("Transition Id")
private long id;
public void setTransitionId(long id) {
this.id = id;
}
}
没有其他方法可以做到这一点。
JVM 不可能知道事件对象在哪个线程中,或者应该记录哪些线程。用户需要为每个应该接触的线程提供至少一个方法调用(连同一些上下文)。
我正在努力为使用自定义 JFR 事件的异步 servlet 请求处理建模。
我面临的挑战是,在异步处理中,一个请求可能会被 #dispatch()
ed 多次。这意味着整个请求处理链可能会执行多次,在不同的线程中间隔一段时间。我如何使用自定义 JFR 事件对其进行建模?
对我有帮助的是 "parent" 事件的概念(可能在不同的线程中)或事件的暂停和恢复。
编辑
稍微说明一下这个问题。异步请求可能需要 100 秒挂钟时间来处理。但是,在 Servlet#service()
方法中,实际处理可能只需要 4 秒的用户时间:
- 线程 A 中的秒 0-1,
Servlet#service()
方法 returns,AsyncContext
已启动 - 线程 B 中的第 10-11 秒,
Servlet#service()
方法 returns,AsyncContext
已启动 - 线程 A 中的第 80-81 秒,
Servlet#service()
方法 returns,AsyncContext
已启动 - 线程 C 中的第 99-100 秒,
Servlet#service()
方法 returns
我只对在这三个线程中为这四个持续时间生成事件感兴趣,然后将它们与单个请求相关联。
问题类似于如何在分布式跟踪器中将跨度和范围的 JFR 事件绑定在一起。
本文可能对您有所帮助: http://hirt.se/blog/?p=1081
您可以在活动中添加线程字段
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 {
}
如果您不想重复自己的话,您可以将上述功能写在一个基类 class 的方法中,您可以为事件访问的每个新线程调用该方法。
abstract AbstractTransition extends Event {
@TransitionId
@Label("Transition Id")
private long id;
public void setTransitionId(long id) {
this.id = id;
}
}
没有其他方法可以做到这一点。
JVM 不可能知道事件对象在哪个线程中,或者应该记录哪些线程。用户需要为每个应该接触的线程提供至少一个方法调用(连同一些上下文)。