영향 범위를 먼저 그린다
한 줄 요약
어떤 변경이든 하기 전에 누가·무엇이 영향을 받는지 종이에 그릴 수 있어야 합니다. 그릴 수 없다면 아직 그 변경을 할 준비가 안 된 것입니다. 그리고 그 그림은 추측이 아니라 로그, 소켓, 설정, 스케줄에서 캐낸 것이어야 합니다.
왜 이게 필요했나
주문 서버의 응답이 느려 커넥션 풀을 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분" 이라고 적을 수 있으면 그 변경은 해도 됩니다. 못 적으면 아직입니다. 적을 때 세 가지를 확인합니다.
cp -p로 백업합니다.-p없이 복사하면 백업은 복사한 계정의 소유가 되고 권한도 umask 를 따라 새로 정해집니다. 그 백업을mv로 제자리에 돌려놓으면 설정 파일의 소유자와 권한이 바뀌어, "되돌렸는데 서비스가 설정을 못 읽는다" 는 두 번째 사고가 납니다.-p는 권한, 소유자(권한이 있을 때), 수정 시각을 함께 보존합니다.reload가 정말 그 값을 다시 읽는지 확인합니다.systemctl reload는 서비스 자신의 설정을 다시 읽으라고 요청하는 것이고, 서비스가 reload 를 지원하지 않으면 실패합니다. 지원하더라도 어떤 값은 시작할 때만 읽습니다. 그럴 때는 재시작이 필요하고, 재시작은 열린 연결을 끊으므로 소요 시간과 영향이 달라집니다.- 되돌리기를 미리 한 번 돌려 봅니다. 사본에서 설정을 바꾼 뒤 되돌리기
스크립트를 실행하고, 결과가 원본과 같은지
diff나sha256sum으로 비교합니다. 한 번도 돌려 보지 않은 되돌리기는 계획이 아니라 희망입니다.
관찰 창을 정한다
변경 후 언제까지 지켜볼지 미리 정합니다. 5분 보고 자리를 뜨면, 10분 뒤에 터진 문제는 원인 후보에서 빠집니다. 반대로 무한정 붙어 있을 수도 없으니 "30분 관찰, 지표 세 개(에러율·지연·큐 길이)" 처럼 명시합니다.
그리고 변경 전의 값을 먼저 적어 둡니다. 에러율이 0.4% 라는 숫자는 평소가 0.1% 인지 0.5% 인지 알아야 판정할 수 있습니다. 관찰 창 안에 배치가 도는 시각이 끼어 있다면, 그 시각의 변화가 변경 때문인지 배치 때문인지 구별할 수 없으니 창을 옮깁니다.
현장에서 만나는 모습
- 타임아웃을 늘렸더니 하류 DB 커넥션이 고갈 → 하류를 안 봤다. 증상은 우리 서비스가 아니라 같은 DB 를 쓰는 다른 서비스의 연결 거부로 먼저 나타납니다.
- 야간에 배포했는데 그 시각에 정산 배치가 돌고 있었다 → 시점을 안 물었다. crontab 에는 시작 시각만 있고, 배치가 몇 시간 걸리는지는 적혀 있지 않았습니다.
- 롤백하려니 원본 설정을 아무도 모른다 → 백업을 안 뜨고 고쳤다.
- 백업으로 되돌렸는데 서비스가 설정을 못 읽음 →
-p없이 뜬 백업을mv로 돌려놓아 소유자와 권한이 바뀌었다. - 하루 한 번만 오는 호출자를 놓침 → 접근 로그를 한 시간치만 봤다. 상류를 찾을 때는 로그 보존 기간이 허락하는 만큼 넓게 봅니다.
이어지는 실습에서 할 것
구성도도 위키도 없는 고객사 시스템을 받습니다. 설정 파일 둘, 접근 로그, 로테이션 설정, crontab — 이게 전부입니다.
여기서 상류·하류·공유 상태·배치 창을 이 절의 명령으로 직접 캐내고, 되돌리기를 먼저 쓴 변경 계획을 만듭니다. 채점기가 설정을 일부러 바꾼 뒤 여러분의 되돌리기 스크립트를 돌려 원본으로 돌아오는지 확인하므로, 제출하기 전에 위에서 말한 대로 사본에서 한 번 돌려 보십시오.