부하가 오르면 멀쩡하던 서버가 too many open files를 뱉거나, 연결이 받아들여지지 않고 떨어집니다. 애플리케이션 코드는 그대로인데 한계에 부딪힌다면, 커널 기본값이 현재 트래픽에 맞지 않는 경우가 많습니다. sysctl로 그 한계를 조정합니다.
증상 — 왜 기본값으로는 부족한가
리눅스 커널 기본값은 범용 안전값이라 고트래픽 서버에는 낮게 잡혀 있습니다. 동시 연결이 늘면 파일 디스크립터가 고갈되고, 연결 요청이 백로그 큐를 넘으면 커널이 조용히 패킷을 버립니다.
진단 — 지금 값과 한계 확인
sysctl fs.file-nr # 현재 사용/최대 파일핸들
sysctl net.core.somaxconn # accept 큐 한계
ulimit -n # 프로세스당 FD 한계
fs.file-nr 출력의 마지막 숫자가 fs.file-max이며, 첫 숫자가 그 한계에 근접하면 위험합니다. 누가 FD를 많이 쓰는지는 다음으로 봅니다.
ls /proc/$(pgrep -f myapp)/fd | wc -l # 특정 프로세스의 열린 FD 수
원인별 조정
런타임 임시 적용은 sysctl -w, 검증 후 /etc/sysctl.conf(또는 /etc/sysctl.d/99-tune.conf)에 적어 영구화합니다.
| 증상 | 파라미터 | 의미 |
|---|---|---|
| too many open files | fs.file-max | 시스템 전체 FD 상한 |
| accept 큐 넘침 | net.core.somaxconn | 완료된 연결 대기 큐 |
| SYN flood/대기 폭증 | net.ipv4.tcp_max_syn_backlog | 반쯤 열린 연결 큐 |
| TIME_WAIT 과다 | net.ipv4.tcp_tw_reuse | TIME_WAIT 소켓 재사용 |
| 포트 고갈 | net.ipv4.ip_local_port_range | 임시 포트 범위 |
sysctl -w fs.file-max=2097152
sysctl -w net.core.somaxconn=4096
sysctl -w net.ipv4.tcp_max_syn_backlog=8192
somaxconn을 올려도 애플리케이션의 listen() 백로그 인자가 작으면 소용없으니, 둘을 함께 맞춰야 합니다. 프로세스당 FD 한계(ulimit -n)는 sysctl이 아니라 /etc/security/limits.conf나 systemd 유닛의 LimitNOFILE로 올립니다.
영구 반영 체크리스트
# 1. 파일에 기록 (예: /etc/sysctl.d/99-tune.conf)
# fs.file-max = 2097152
# net.core.somaxconn = 4096
# net.ipv4.tcp_max_syn_backlog = 8192
sysctl -p /etc/sysctl.d/99-tune.conf # 2. 즉시 적용
sysctl fs.file-max # 3. 적용값 재확인
# 4. 프로세스 FD 한계는 LimitNOFILE / limits.conf로 별도 설정
# 5. 부하 재현 후 fs.file-nr·somaxconn 모니터링
값을 바꾼 뒤에는 반드시 부하를 다시 걸어보고 fs.file-nr와 드롭 카운터를 확인합니다. 추측으로 큰 값을 넣기보다, 측정 후 한 단계씩 올리는 것이 안전합니다.
sysctl로 커널 파라미터를 직접 조정하고 ulimit·limits.conf까지 연결해 실습하는 과정은 리눅스 트랙에서 회원가입 없이 무료로 익힐 수 있습니다.