먼저 측정하라
ss -s
cat /proc/sys/fs/file-nr
nstat -az TcpExtListenOverflows TcpExtListenDropsListenOverflows 상승은 수락 큐가 가득 차 커널이 완료된 핸드셰이크를 버리고 있음을 의미한다. 이는 특정 문제이며 특정 해결책이 있다. 다른 대부분의 증상은 sysctl로 전혀 해결되지 않으며, 압력을 받지 않는 머신을 튜닝하는 것은 결국 실패를 찾기 더 어려운 곳으로 옮길 뿐이다.
자리를 지키는 설정
# /etc/sysctl.d/90-connections.conf
fs.file-max = 2097152
net.core.somaxconn = 65535
net.core.netdev_max_backlog = 32768
net.ipv4.tcp_max_syn_backlog = 65535
net.ipv4.ip_local_port_range = 10240 65535
net.ipv4.tcp_fin_timeout = 15
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_slow_start_after_idle = 0
net.ipv4.tcp_mtu_probing = 1
net.core.default_qdisc = fq
net.ipv4.tcp_congestion_control = bbrsysctl --system
sysctl net.ipv4.tcp_congestion_control각각이 하는 일:
somaxconn은 수신 백로그를 제한하며, 애플리케이션이 여전히 요청해야 한다. nginx에서는listen ... backlog=65535이고, 대부분의 언어에서는listen()의 두 번째 인자다.ip_local_port_range은 클라이언트 측에서 중요하다. 한 대상으로 아웃바운드 연결을 여는 프록시는 기본 범위에서 약 2만 8천 개에서 임시 포트를 소진한다.tcp_tw_reuse은 커널이 새 아웃바운드 연결에 TIMEWAIT 소켓을 재사용하게 한다. 안전하다. 그 사촌 `tcptw_recycle`은 Linux 4.12에서 제거되었으며, 여전히 권장하는 가이드는 2017년 이전에 작성된 것이다.fq과bbr은 길거나 손실이 많은 경로에서 실제 개선이며, 짧고 깨끗한 경로에서는 차이가 없다. 둘 다 기본 커널에 있다.
연결 추적
상태 저장 방화벽은 모든 연결에 conntrack 항목을 부여하며, 테이블에는 상한이 있다. 도달하면 패킷을 버리고 nf_conntrack: table full을 커널 로그에 기록한다.
sysctl net.netfilter.nf_conntrack_max net.netfilter.nf_conntrack_count메모리가 있다면 올리십시오 — 각 항목은 수백 바이트를 차지한다:
net.netfilter.nf_conntrack_max = 1048576워크로드가 상태 없는 공개 서비스라면, 더 나은 답은 추적하지 않는 것이다:
table inet raw {
chain prerouting {
type filter hook prerouting priority raw;
tcp dport 443 notrack
}
}systemd가 무시하는 제한
/etc/security/limits.conf은 PAM을 통한 로그인에 적용된다. systemd가 시작한 서비스에는 전혀 영향을 미치지 않으며, 그래서 nofile을 올리고 nginx를 재시작해도 정확히 아무것도 바뀌지 않는다. 유닛에 설정하십시오:
mkdir -p /etc/systemd/system/nginx.service.d
cat > /etc/systemd/system/nginx.service.d/limits.conf <<EOF
[Service]
LimitNOFILE=1048576
EOF
systemctl daemon-reload
systemctl restart nginx방금 작성한 파일이 아닌 실행 중인 서비스에 대해 확인하십시오:
systemctl show nginx -p LimitNOFILE하지 말아야 할 세 가지
- 포럼에서 50줄짜리 sysctl 파일을 붙여넣지 마십시오. 절반은 10년 전에 배포되지 않은 커널을 대상으로 하며, 한 줄이 조용히 경로 MTU 발견을 깨뜨릴 것이다.
- 길고 두꺼운 경로가 정당화되지 않는데
tcp_rmem과tcp_wmem을 올리지 마십시오. 1밀리초 경로에서 더 큰 버퍼는 지연 시간과 메모리 압력을 산다. tcp_timestamps을 비활성화하지 마십시오. 왕복 시간 추정과 PAWS를 잃고, 성능에 대한 소문만 얻는다.
각 변경 후 다시 측정하고, 한 번에 하나씩 변경하며, 다음 사람이 무엇을 왜 했는지 볼 수 있도록 파일을 버전 관리에 유지하십시오.