如何在没有网络传输时间的情况下测量请求的执行时间

时间:2011-09-12 15:59:08

标签: tomcat servlets servlet-filters tomcat-valve

在我的阀门中,我得到了我的http查询的执行时间:

public void invoke(Request request, Response response) 
throws IOException, ServletException {
long t1 = System.currentTimeMillis();
getNext().invoke(request, response);
long t2 = System.currentTimeMillis();
long time = t2 - t1;
...
}

我怀疑我得到这种方式的时间,不仅给我服务器端执行时间,还给我网络时间?有可能吗?

(因为取决于执行请求的客户端,从一个ip测量的平均时间不同,我有70ms的平均时间和另一个ip 270ms)

我在过滤器中编写了完全相同的代码:

long before = System.currentTimeMillis();
chain.doFilter(request, response);
long after = System.currentTimeMillis();

,但在我的测试中,Valve和过滤器中的执行时间是相同的......

我更感兴趣的是只获取servlet的执行时间。 但如果我还能得到发送最后一个字节的时间,我会感兴趣的。

非常感谢我澄清了阀门和过滤器可以了解的内容。

1 个答案:

答案 0 :(得分:3)

  

我怀疑我得到这种方式的时间,不仅给我服务器端执行时间,还给网络时间?有可能吗?

这是对的。至少,涉及转移请求主体的网络时间的一部分包括在这样的总时间中。一旦完全读取并解析了请求 headers ,就会直接调用valve / filter / servlet代码。此时请求正文未必完全读取。请求主体包含客户端通过网络发送的任何内容作为请求的一部分(例如,提交的表单数据)。仅当过滤器/ servlet开始读取并解析完整的请求体时,例如getParameter()getReader()getInputStream()等,然后实际传输请求正文的所有字节。

您可能希望重写执行时间测量,使其仅在请求主体完全读取后才开始。这意味着您必须在servlet内部进行测量。

@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    // Read the request body.
    String foo = request.getParameter("foo");
    String bar = request.getParameter("bar");
    // ...

    // Now, start the stopwatch.
    long startTime = System.nanoTime();

    // Now, do the business job.
    someService.process(foo, bar, ...);
    // ...

    // Now, stop the stopwatch.
    long elapsedTime = System.nanoTime() - startTime;

    // I don't think that you want to include JSP rendering in total time, right?
    request.getRequestDispatcher("/WEB-INF/some.jsp").forward(request, response);
}

(请注意,我使用了System#nanoTime(),因为它具有更好准确度)