剖析单个网络会话

问题描述 投票:2回答:3

在寻找一个Java-web应用程序的性能问题时,我想对一个单一的web会话进行分析(通过采样)。该web应用部署在Java EE应用服务器上(JBoss或WLS,所以不可能有OpenJDK专用的东西)。

使用传统的采样器,比如JVisualVM或YourKit,只能让我一次对所有正在运行的线程进行分析,因此不能显示出web-session的CPU使用情况,它与服务器上的基本负载是分开的。部分问题是,web-session和单个线程之间没有技术上的联系,也就是说,每个请求都可能从应用服务器的线程池中得到一个不同的线程。

我的想法是实现一个采样器,每次从服务器接收到新的请求时,注册与观察到的web-session相关联的线程(一旦请求结束,就会取消注册线程)。

第一个问题。你是必须手工完成还是有工具可以帮你完成?

第二个问题(因为我没有找到,并且假设这是一个相当特殊的问题)。最好的方法是什么?

很明显,人们会尽量减少剖析对应用性能的影响。同样很明显,由于我需要将(技术)线程信息连接到特定于应用程序的数据(websession-ID),这似乎没什么,可以通过JVMTI来完成。

这就留下了一个选择,即编码一个应用内的profiler,线程通过Thread.stackTrace或ThreadMXBean.getThreadInfo进行采样。哪个更好?有没有其他更好的方案?

java multithreading profiling performance-testing
3个回答
3
投票

JProfiler 可以针对不同的URL或查询参数拆分调用树。

enter image description here

如果你能为此修改URL或查询参数,那么你就能将会话与后台加载分开。例如,你可以添加一个查询参数 profile=true 你只传递给那些应该被剖析的请求。

enter image description here

声明:我的公司开发了JProfiler。


1
投票

请看一下。

http:/messadmin.sourceforge.net。

这应该有助于你想要的资料。

还有: http:/www.appdynamics.comhttp:/newrelic.com 都是非常好的分析网络应用的工具。


0
投票

如果你没有JProfiler,"编写应用程序内的配置文件"当然是一种选择。在一个方法调用过程中,只需在特定的时间间隔内打印堆栈痕迹,就能提供一个很好的快照视图,了解正在发生的事情。

这里有一个帮助类的例子可以做到这一点。

import java.io.Closeable;
import java.io.IOException;
import java.lang.management.ManagementFactory;

public class StackDumper extends Thread implements Closeable {
    static final String pid = ManagementFactory.getRuntimeMXBean().getName().replaceFirst("@.*", "");
    final Thread t;
    final int step;

    public StackDumper(int timeStepMs) {
        setName("Profiler");
        this.t = Thread.currentThread();
        this.step = timeStepMs;
        start();
    }

    @Override
    public void run() {
        StringBuilder buf = new StringBuilder(4096);
        for (int i = 0;; i += step) {
            try {
                Thread.sleep(step);
            } catch (InterruptedException e) {
                break;
            }
            buf.setLength(0);
            for (StackTraceElement e : t.getStackTrace()) {
                buf.append("  ").append(e).append('\n');
            }
            System.out.print(pid + " @" + i + "ms: [" + t.getName() + "]:\n" + buf);
        }
    }

    @Override
    public void close() throws IOException {
        interrupt();
    }

}

用它来做:

    try (StackDumper p = new StackDumper(100)) { // prints stack every 100 ms ...
        methodUnderTest();
    }
© www.soinside.com 2019 - 2024. All rights reserved.