Como medir o tempo de execução da solicitação sem o tempo de transferência da rede?
-
29-10-2019 - |
Pergunta
Na minha válvula, obtenho o tempo de execução da minha consulta http assim:
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;
...
}
Eu suspeito que o tempo que fico assim, não só me dá o tempo de execução do lado do servidor, mas também o tempo da rede.É possível?
(Porque dependendo do cliente que faz a requisição o tempo médio medido não é o mesmo de um ip tenho média de 70ms e outro ip 270ms)
Escrevi exatamente o mesmo código em um filtro:
long before = System.currentTimeMillis();
chain.doFilter(request, response);
long after = System.currentTimeMillis();
, mas no meu teste o tempo de execução na válvula e no filtro é o mesmo ...
Estou mais interessado em obter apenas o tempo de execução do meu servlet. Mas se eu também pudesse obter a hora em que o último byte é enviado, ficaria interessado.
Muito obrigado por me esclarecer o que é possível saber com válvulas e filtros.
Solução
Suspeito que o tempo que fico assim, não só me dá o tempo de execução do lado do servidor, mas também o tempo da rede. Isso é possível?
Correto. Pelo menos uma parte do tempo da rede envolvendo a transferência do corpo da solicitação é incluída no tempo total dessa forma. O código da válvula / filtro / servlet é chamado diretamente assim que os cabeçalhos da solicitação forem totalmente lidos e analisados. O corpo da solicitação não é necessariamente lido completamente nesse ponto. O corpo da solicitação contém tudo o que o cliente envia pela rede como parte da solicitação (por exemplo, dados do formulário enviado). Somente quando o filtro / servlet começa a ler e analisar todo o corpo da solicitação, por exemplo, getParameter()
, getReader()
, getInputStream()
, etc, todos os bytes do corpo da solicitação serão realmente transferidos.
Você pode querer reescrever a medição do tempo de execução de forma que ela só comece depois que o corpo da solicitação for totalmente lido. Isso significa que você realmente precisa medir dentro do 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);
}
(observe que usei System#nanoTime()
, pois tem uma precisão muito melhor )