OK, eu finalmente consegui convencer o Jetty a jogar bem.
Só para recapitular, veja como minhas conexões estão agora, em toda a máquina:
24 LAST_ACK
36 CLOSING
117 FIN_WAIT_2
175 ESTABLISHED
351 FIN_WAIT_1
4725 TIME_WAIT
E entre o nginx e o Jetty
1 FIN_WAIT_2
3 LISTEN
14 ESTABLISHED
Eu já fechei a conexão inteira e EndPoint
(chamando close()
no EndPoint
fecha o SocketChannel
subjacente) usando este método de conveniência:
private void finishRequest(String message, Request baseRequest, HttpServletResponse response) throws IOException {
ByteArrayISO8859Writer writer = new ByteArrayISO8859Writer(1500);
writer.write(message);
writer.flush();
// set the content length
response.setContentLength(writer.size());
// write the response
OutputStream outputStream = response.getOutputStream();
writer.writeTo(outputStream);
// close the streams
outputStream.close();
writer.close();
baseRequest.getConnection().getEndPoint().close();
}
(Eu só envio no máximo uma linha para o cliente, então nada é necessário)
No entanto, isso ainda resultou no preenchimento de todo o servidor com LAST_ACK ... O que fez estes últimos desaparecerem foi habilitar SO_LINGER
(e fazê-lo fechar o socket imediatamente, sem tempo limite)
connector.setSoLingerTime(0);