LabHub

낯선 시스템 앞에서 · 가설과 검증 · 이론

반증 가능한 가설이 아니면 짐작이다

LabHub 에서 이어서 보기

한 줄 요약

디버깅은 가능한 것을 하나 만들어 내는 일이 아니라 가능한 원인들을 하나만 남을 때까지 지우는 일이고, 지우려면 틀렸을 때 무엇이 보일지가 미리 정해져 있어야 한다.

왜 이게 필요했나

"가끔 느려요" 는 진단할 수 없습니다. 진단할 수 있는 것은 측정값뿐입니다. 그래서 고객의 말을 받은 다음 첫 작업은 원인을 찾는 것이 아니라 증상을 명령 하나로 고정하는 것입니다.

# 20회 반복해 실패율을 잰다for i in $(seq 1 20); do  curl -s -o /dev/null -w "%{http_code}\n" http://127.0.0.1:8001/quotedone | sort | uniq -c

20번 중 5번이 실패한다면, 장애는 전해 들은 이야기에서 수치로 바뀝니다. 그리고 이 명령은 이후 모든 단계에서 수리 여부를 판정하는 잣대로 재사용됩니다. 고쳤다고 말하려면 같은 잣대로 다시 재서 0 이 나와야 합니다.

재현이 안 되는 것도 정보입니다. 특정 사용자, 특정 시간대, 특정 경로에서만 난다는 뜻이고 질문이 그만큼 좁혀집니다.

어떻게 동작하나

숫자가 손에 들어오면 다음은 가설입니다. 그런데 대부분의 사람이 여기서 가설이라고 부르는 것은 가설이 아닙니다.

"네트워크 문제인 것 같다" 는 가설이 아닙니다. 틀렸을 때 무엇이 보일지가 정해져 있지 않기 때문에, 무슨 결과가 나와도 이 문장은 살아남습니다. 살아남는 추측은 후보를 줄여 주지 않습니다.

쓸 수 있는 가설은 세 줄짜리입니다.

가설:   요청이 게이트웨이와 애플리케이션 사이에서 끊긴다맞다면: 게이트웨이 로그에 5초 타임아웃, 앱 로그에 해당 요청 아이디 없음틀리면: 앱 로그에 요청이 들어와 있고 처리 중 실패한 흔적이 있음

차이는 뒤쪽 두 줄에 있습니다. 확인할 것이 지정되어 있고, 예상과 다르게 나오면 가설이 죽습니다. 죽는 가설만이 후보를 줄여 줍니다.

세 줄을 적는 데 1분이 걸립니다. 그 1분이 아까워 보이지만, 적지 않으면 30분 뒤에 자기가 이미 배제한 것을 다시 확인하고 있게 됩니다. 여러 사람이 붙은 장애에서는 효과가 더 큽니다. 배제 목록이 공유되지 않으면 세 사람이 같은 것을 세 번 확인합니다.

현장에서 만나는 모습

가설을 좁히는 가장 신뢰할 만한 절차는 계층을 절반씩 자르는 것입니다. 요청이 통과하는 층을 순서대로 적고 — 클라이언트, DNS, 로드밸런서, 게이트웨이, 애플리케이션, 캐시, 데이터베이스, 외부 연동 — 정확히 가운데를 골라 "여기까지는 정상인가" 를 묻습니다.

여덟 개 층을 순서대로 훑으면 평균 네 번을 봐야 하고, 절반씩 자르면 세 번 안에 끝납니다. 층이 스무 개로 늘면 격차는 열 번 대 다섯 번이 됩니다. 실제 장애에서 한 번 확인하는 데 몇 분이 걸리므로, 이 차이가 곧 복구 시간입니다.

여기서 핵심은 정상 여부를 판정할 수 있는 지점을 고르는 것입니다. 판정이 불가능한 지점에서 자르면 절반을 못 지웁니다. 계층 분리의 목적은 정답을 맞히는 것이 아니라 보지 않아도 되는 곳을 확정하는 것입니다.

한 가지 예외가 있습니다. 서비스가 지금 죽어 있는 동안에는 진단보다 완화가 먼저입니다. 롤백하거나 트래픽을 돌려 출혈을 멈춘 뒤에 좁히세요. 가설을 예쁘게 적는 것은 사용자가 기다리지 않을 때 할 일입니다.

다음 실습에서 할 것

"가끔 안 된다" 는 신고가 들어온 견적 API 를 상대로, 실패율을 숫자로 고정하고, 세 줄짜리 가설을 문서로 쓰고, 배제한 계층을 근거와 함께 기록한 뒤, 같은 잣대로 다시 재서 비율이 안정적인지 확인합니다.