TT Lab
시작하기
배우기 러닝패스 코스

낯선 시스템 앞에서

영향 범위를 먼저 그린다

TT Lab 에서 이어서 보기

한 줄 요약

어떤 변경이든 하기 전에 누가·무엇이 영향을 받는지 종이에 그릴 수 있어야 합니다. 그릴 수 없다면 아직 그 변경을 할 준비가 안 된 것입니다. 그리고 그 그림은 추측이 아니라 로그, 소켓, 설정, 스케줄에서 캐낸 것이어야 합니다.

왜 이게 필요했나

주문 서버의 응답이 느려 커넥션 풀을 10 에서 30 으로 늘렸다고 합시다. 설정 한 줄이고, 되돌리기도 쉬워 보입니다. 그런데 이 서버는 네 대가 떠 있었고, 네 대가 모두 같은 데이터베이스를 씁니다. 풀 합계가 40 에서 120 이 됩니다. PostgreSQL 의 max_connections 기본값은 보통 100 이고, 이 값은 서버를 다시 시작해야만 바뀝니다. 새 연결은 sorry, too many clients already 로 거절되기 시작하고, 가장 먼저 쓰러지는 것은 주문 서버가 아니라 같은 DB 를 쓰던 정산 배치입니다. 구성도에는 정산 배치가 그려져 있지 않았습니다.

"설정 한 줄만 바꾸면 됩니다" 로 시작해 서비스가 멎는 일이 반복되는 이유는, 그 한 줄이 무엇에 닿는지 아무도 확인하지 않기 때문입니다. 낯선 시스템에서는 특히 그렇습니다 — 우리에겐 새 시스템이지만 고객에겐 10년 된 시스템이고, 그 사이에 아무도 기록하지 않은 의존이 쌓여 있습니다.

영향 범위를 그리는 네 가지 질문

1. 이 구성 요소를 누가 호출하는가 (상류) 설정 파일 하나를 고칠 때도, 그 프로세스에 요청을 보내는 쪽이 누구인지 알아야 합니다. 접근 로그의 소스 IP 분포가 지난 기간의 호출자를, 지금 붙어 있는 소켓이 현재의 호출자를 보여 줍니다.

awk '{print $1}' access.log | sort | uniq -c | sort -rn | head
ss -tn state established '( sport = :8080 )'

첫 명령은 IP 별 요청 수를 많은 순으로 보여 줍니다. 몇 건 안 되는 IP 를 무시하지 마십시오. 하루 한 번 도는 배치나 월말에만 오는 외부 기관일 수 있습니다. 둘째 명령에서는 로컬 포트가 서비스 포트인 연결의 상대 주소가 상류입니다.

2. 이것이 무엇을 호출하는가 (하류) 바꾼 결과로 하류에 부하가 몰릴 수 있습니다. 타임아웃을 늘리는 변경이 대표적입니다 — 우리는 여유를 줬다고 생각하지만 하류에서는 커넥션이 오래 잡혀 있게 됩니다. 풀 크기, 재시도 횟수, 동시성도 같은 방향으로 하류를 누릅니다.

grep -nE '[a-z0-9.-]+:[0-9]{2,5}' /etc/app/*.yml
ss -tnp state established '( dport = :5432 )'

설정에서 host:port 모양을 모두 뽑으면 하류 후보가 나오고, 지금 그 포트로 나가는 연결이 몇 개인지 세면 변경 뒤의 연결 수를 어림할 수 있습니다. 인스턴스가 여러 대라면 한 대의 값에 대수를 곱해야 한다는 것을 잊지 마십시오.

3. 상태를 공유하는가 같은 DB, 같은 파일시스템, 같은 캐시를 쓰는 다른 시스템이 있는지. 공유 상태는 구성도에 잘 안 그려지는데 사고는 여기서 납니다. 서로 다른 서비스의 설정 파일에서 같은 값이 나오는지 비교하는 것이 빠른 방법입니다.

grep -hE 'db|dsn|path|dir|cache' service-a.yml service-b.yml | sort | uniq -d

uniq -d 는 두 번 이상 나온 줄만 보여 줍니다. 여기에 나온 DB 주소나 디렉터리가 두 서비스가 함께 쓰는 자원입니다.

4. 언제가 안전한가 배치가 도는 시간, 마감이 걸린 날, 정산일. 기술적으로 안전해도 시점이 틀리면 사고입니다. 스케줄은 한 곳에만 있지 않습니다.

crontab -l; ls /etc/cron.d /etc/cron.daily
systemctl list-timers --all

crontab 의 앞 다섯 칸은 분, 시, 일, 월, 요일 순서입니다. 30 23 * * 5 는 "매주 금요일 23시 30분" 입니다. systemd 타이머는 다음 실행 시각(NEXT)과 지난 실행 시각(LAST)을 함께 보여 줍니다. 다만 배치가 몇 시에 시작하는지 는 여기서 보여도 몇 시에 끝나는지 는 보이지 않습니다. 그것은 로그나 고객에게 물어야 알 수 있습니다.

되돌리기를 먼저 쓴다

변경 계획서의 첫 줄은 변경 내용이 아니라 되돌리는 방법이어야 합니다.

변경:   /etc/app/config.yml 의 pool_size 10 → 30
백업:   cp -p config.yml config.yml.2026-08-20
되돌림: cp -p config.yml.2026-08-20 config.yml && systemctl reload app
확인:   curl -s localhost:8080/healthz 가 200, 에러율 5분간 관찰
소요:   되돌림 2분

"되돌림: 2분" 이라고 적을 수 있으면 그 변경은 해도 됩니다. 못 적으면 아직입니다. 적을 때 세 가지를 확인합니다.

관찰 창을 정한다

변경 후 언제까지 지켜볼지 미리 정합니다. 5분 보고 자리를 뜨면, 10분 뒤에 터진 문제는 원인 후보에서 빠집니다. 반대로 무한정 붙어 있을 수도 없으니 "30분 관찰, 지표 세 개(에러율·지연·큐 길이)" 처럼 명시합니다.

그리고 변경 전의 값을 먼저 적어 둡니다. 에러율이 0.4% 라는 숫자는 평소가 0.1% 인지 0.5% 인지 알아야 판정할 수 있습니다. 관찰 창 안에 배치가 도는 시각이 끼어 있다면, 그 시각의 변화가 변경 때문인지 배치 때문인지 구별할 수 없으니 창을 옮깁니다.

현장에서 만나는 모습

이어지는 실습에서 할 것

구성도도 위키도 없는 고객사 시스템을 받습니다. 설정 파일 둘, 접근 로그, 로테이션 설정, crontab — 이게 전부입니다.

여기서 상류·하류·공유 상태·배치 창을 이 절의 명령으로 직접 캐내고, 되돌리기를 먼저 쓴 변경 계획을 만듭니다. 채점기가 설정을 일부러 바꾼 뒤 여러분의 되돌리기 스크립트를 돌려 원본으로 돌아오는지 확인하므로, 제출하기 전에 위에서 말한 대로 사본에서 한 번 돌려 보십시오.