
poll()
최근에 저는 프로덕션에서 데이터베이스 서버가 중단되면 연결된 클라이언트가 최대 2시간 동안 중단되는 문제( libpq 클라이언트 라이브러리의 호출에 대한 긴 대기 시간)를 추적하는 데 꽤 많은 시간을 보냈습니다 . 문제를 더 깊이 파고들면서, 중단된 TCP 연결을 적시에 확인하려면 이러한 커널 매개변수를 아래쪽으로 조정해야 한다는 것을 깨달았습니다.
net.ipv4.tcp_keepalive_time = 7200 net.ipv4.tcp_keepalive_probes = 9 net.ipv4.tcp_keepalive_intvl = 75 net.ipv4.tcp_retries2 = 15
위의 네 가지 값은 Ubuntu 12.04 시스템에서 가져온 것이며 이러한 기본값은 현재 버전에서 변경되지 않은 것 같습니다Linux 커널 기본값.
설정은 기존 연결을 열린 상태로 유지하는 쪽으로 크게 편향되어 있고 연결 유지 프로브에 대해 극도로 인색한 것으로 보입니다. AIUI, 기본 tcp_keepalive_time
2시간은 원격 호스트의 응답을 기다리는 동안 2시간 동안 인내심을 갖고 기다린 다음 연결 유지 프로브를 시작하여 연결이 여전히 유효한지 확인한다는 의미입니다. 그런 다음 원격 호스트가 keepalive 프로브에 응답하지 않으면 이러한 keepalive 프로브를 tcp_keepalive_probes
75초 간격( )으로 9번( tcp_keepalive_intvl
) 재시도하므로 연결이 실제로 끊어졌는지 확인하기 전에 추가로 11분을 기다려야 합니다.
이는 현장에서 본 것과 일치합니다. 예를 들어 psql
원격 PostgreSQL 인스턴스에 연결된 세션을 시작하면 일부 쿼리가 응답을 기다리고 있습니다.
SELECT pg_sleep(30);
그런 다음 원격 서버가 끔찍하게 죽게 되면서(예: 해당 컴퓨터에 대한 트래픽이 끊어짐) psql 세션이 연결이 끊긴 것을 발견하기 전에 최대 2시간 11분 동안 기다리는 것을 보았습니다. 상상할 수 있듯이 이러한 기본 설정은 데이터베이스 장애 조치 이벤트 중에 데이터베이스와 통신하는 코드에 심각한 문제를 야기합니다. 손잡이를 낮추면 많은 도움이 됩니다! 나는 내가 있다는 것을 알았다.혼자가 아니야이러한 기본값을 조정하는 것이 좋습니다.
그래서 내 질문은 다음과 같습니다
- 이 기본 상태가 얼마나 오랫동안 지속되었나요?
- 이러한 TCP 설정을 기본값으로 설정한 원래 이유는 무엇입니까?
- Linux 배포판에서 이러한 기본값을 변경했습니까?
이러한 설정에 대한 근거에 대한 다른 기록이나 관점은 크게 감사하겠습니다.
답변1
RFC 1122섹션 4.2.3.6에 명시된 연결 유지 시간은 기본적으로 2시간 미만으로 설정되어서는 안 됩니다.