Thread 8 is about to kill the process.
cpu_ns: poll=<값> now=<값> diff=<값>
HAProxy 의 watchdog 이 특정 스레드가 정해진 시간 안에 이벤트 루프로 돌아오지 않는 것을 감지하고 프로세스를 종료시키는 상황이다. 정상 종료가 아니라 멈춘 상태를 강제로 끊는 것이며, 함께 찍히는 cpu_ns 는 마지막 polling 이후 얼마나 시간이 지났는지를 나노초로 보여 준다. diff 가 클수록 그 스레드가 오래 묶여 있었다는 뜻이다.
이 로그는 보통 다음 순서로 진행된다.
"가끔 접속이 안 되는데 새로고침하면 된다", "특정 시간대만 느리다" 같은 사용자 증상과 이 로그가 함께 보이면 같은 사건으로 본다.
| 분류 | 확인 |
|---|---|
| CPU 고갈 · 스로틀링 | top, vmstat 1, 컨테이너면 cgroup 제한 |
| 메모리 부족 | dmesg -T | grep -i oom |
| 파일 디스크립터 고갈 | ulimit -n, ss -s |
| 블로킹 작업 | Lua 스크립트, 외부 인증 · DNS 조회 |
| 버전 버그 | haproxy -vv 로 버전 확인 후 릴리스 노트 대조 |
컨테이너 · 쿠버네티스 환경에서는 CPU limit 에 걸려 스로틀링이 일어나는 경우가 특히 많다. 호스트에서는 여유가 있어 보이는데 파드 안에서는 멈추는 형태다.
# 스로틀 여부
cat /sys/fs/cgroup/cpu.stat 2>/dev/null | grep throttled
kubectl describe pod <haproxy-pod> | egrep -A3 'Limits|Requests'
# 1) 종료 직전 로그 전체
journalctl -u haproxy --since "30 min ago" --no-pager | egrep -i 'watchdog|kill|panic|segfault|cpu_ns'
# 2) 커널 쪽 흔적
dmesg -T | tail -100
# 3) 버전
haproxy -vv | head -5
# 4) 리소스
ulimit -n
ss -s
vmstat 1 5
pidstat -p "$(pidof haproxy)" 1 5
dmesg 에 OOM 기록이 있으면 메모리 문제로 확정된다. 아무 흔적 없이 watchdog 만 남는다면 CPU 고갈이나 블로킹 작업 쪽을 본다.
global
maxconn 20000
nbthread 4
tune.bufsize 16384
maxconn 을 과도하게 크게 잡으면 연결당 버퍼 때문에 메모리를 많이 쓴다. 실제 동시 연결 수를 보고 정한다.nbthread 는 기본적으로 사용 가능한 CPU 수에 맞춰진다. 원인 분리를 위해 잠시 nbthread 1 로 두고 재현되는지 보는 것은 디버깅에 유용하다.# systemd 유닛
# [Service]
# LimitCORE=infinity
coredumpctl list haproxy
# 로그에 watchdog 이 찍히면 알림
journalctl -u haproxy -f | grep --line-buffered -i 'about to kill'
프로세스 재시작 횟수와 5xx 비율을 함께 지표로 걸어 두면 사용자 신고보다 먼저 감지된다.