我正在努力为带有自定义JFR事件的异步servlet请求处理建模。我面临的挑战是,在异步处理中,一个请求可能会被#dispatch()
多次。这意味着整个请求处理链可能会多次执行,在不同的线程中会相隔一段时间。如何使用自定义JFR事件对此进行建模?
对我有帮助的要么是“父”事件的概念(可能在不同的线程中),要么是事件的暂停和恢复。
编辑
来说明一下这个问题。异步请求可能需要100秒的挂钟时间来处理。然而,在Servlet#service()
方法中,实际的处理可能只需要4秒的用户时间:
Servlet#service()
方法返回,AsyncContext
startedServlet#service()
方法返回,AsyncContext
80-81在线程A中,方法返回,<代码>D15 started
我只对在这三个线程中为这四个持续时间生成事件,然后将它们与单个请求关联起来感兴趣。
发布于 2019-05-21 03:30:18
您可以向事件中添加线程字段
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不可能知道事件对象在哪个线程中,或者应该记录哪些线程。用户需要为每个应该接触的线程提供至少一个方法调用(连同一些上下文)。
发布于 2019-05-21 03:09:59
这个问题类似于如何在分布式跟踪器中将跨度和作用域的JFR事件绑定在一起。
这篇文章可能会有所帮助:http://hirt.se/blog/?p=1081
https://stackoverflow.com/questions/56221655
复制相似问题