
실제로 저는 현재 Java/Tomcat 기반 웹 애플리케이션의 장기 실행 연결을 조사하고 있습니다. 내부 또는 애플리케이션 기반 이유를 배제한 후 이제 네트워크 계층으로 이동합니다. 제가 이 문제를 조사하는 이유는 응답 시간 모니터링에 무작위 스파이크가 발생하는 것처럼 보이기 때문입니다. 조사하는 동안 이 동작이 전혀 무작위가 아니라 특정 클라이언트 HTTP 요청에 의해 발생한다는 사실을 발견했습니다. 이러한 연결의 특별한 점은 x-bluecoat-via HTTP 헤더가 표시되기 때문에 모두 동일한 IP 주소에서 시작되고 Bluecoat 프록시를 사용하는 것처럼 보인다는 것입니다.
앞서 말했듯이 애플리케이션 자체는 정상적으로 작동하지만 (Tomcat의 관점에서는) 연결 종료만 다소 지연되는 것 같습니다. 서버는 클라이언트와 직접 통신하지 않지만 실제로 응답을 캐시해야 하는 F5 Loadbalancer 뒤에 있습니다(인코딩 승인 ID 헤더와 실제 응답이 버퍼에 비해 너무 크기 때문에 발생하지 않을 수 있음).
불행한 실수로 인해 현재는 LB에서 앱 서버로의 패키지만 볼 수 있고 앱 서버에서 보낸 실제 패키지는 볼 수 없어 TCP 덤프를 받았습니다.
덤프에는 F5에서 수행한 연결 풀링으로 인해 동일한 TCP/IP 연결에 대한 여러 요청이 포함되어 있습니다. 이 연결의 마지막 HTTP 요청은 로깅에서 장기 실행(925836.442ms)으로 표시된 실제 연결입니다. 내가 보는 것은 요청 패킷, 즉 앱 서버가 응답을 작성하고 있다고 믿게 만드는 일련의 ACK와 마지막으로 두 개의 FIN, ACK 패키지와 F5가 보낸 마지막 패킷인 RST, ACK입니다.
타이밍 관점에서 볼 때 이 모든 일은 250ms 동안 발생하며, 마지막 패킷은 Tomcat에 의해 응답이 완료된 것으로 간주된 후에 작성된 앱 서버의 응답 로그를 보기 전 15분 13초 전에 전송됩니다.
현재 아이디어가 부족하여 몇 가지 질문이 있습니다.
Linux가 RST를 수신한 연결을 열어두고 애플리케이션 계층에 알리지 않는 이유가 있습니까?
이 동작으로 이어질 수 있는 다른 시간 초과가 있습니까? 이것이 TCP 재전송 시간 초과라면 LB에서 더 많은 RST를 볼 수 있습니다.
와이어에서 닫힌 연결이 애플리케이션 계층에서 여전히 열린 연결로 이어지는 다른 이유는 무엇입니까?
애플리케이션 계층(특수 HTTP 요청)에서 발생하는 일이 어떻게 전송 계층에서 재현 가능한 동작으로 이어질 수 있습니까?
아마도 제가 완전히 잘못된 길을 가고 있는 것 같습니다. 이것은 Tomcat 내부의 연결 유지 문제입니까?
답변1
네트워킹 계층에 대해서는 실제로 도움을 드릴 수 없지만 Tomcat에는 이를 구성할 수 있는 여러 장소가 있습니다.http://tomcat.apache.org/connectors-doc/reference/workers.html. 시간 초과를 덮어쓰고 일정 시간이 지나면 연결을 닫도록 구성할 수 있습니다.
링크에는 시나리오에 도움이 될 수 있는 로드 밸런서 구성도 있습니다.