在我的阀门中,我得到了我的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的执行时间。 但如果我还能得到发送最后一个字节的时间,我会感兴趣的。
非常感谢我澄清了阀门和过滤器可以了解的内容。
答案 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()
,因为它具有更好准确度)