Windows Update 가 WSL 을 내렸는데 21시간 동안 다시 안 떴습니다 — 재시도 설정이 반응하지 않은 이유
고객사에 둔 윈도 서버 한 대에서 WSL 안에 서비스 두 개를 올려 운영하고 있었습니다. 서비스마다 엔진과 백업 작업이 하나씩 있고, 엔진 뒤에는 그래프 DB(Neo4j)와 벡터 DB(Qdrant)가 도커로 떠 있습니다.
WSL 이 계속 떠 있게 하려고 윈도 작업 스케줄러에 'WSL 을 깨워 두는 작업'을 하나 걸어 두었습니다. 실행 조건은 '부팅 시'와 '로그온 시' 두 가지였고, 실패하면 다시 시도하는 설정도 켜 두었습니다. 그래서 꺼져도 다시 뜬다고 믿고 있었습니다.
그 믿음이 21시간 동안 틀려 있었습니다. 이 글은 그 21시간과, 고친 뒤 일부러 꺼 보면서 나온 두 번째 문제의 기록입니다.
전날 11:59, 업데이트가 WSL 을 내렸습니다
전날 11:59 에 Windows Update 가 WSL 새 버전(3.0.3.0)을 설치했습니다. 설치하면서 WSL 을 내렸고, 깨워 두는 작업도 결과 코드 1 로 같이 끝났습니다.
그 뒤로 아무것도 WSL 을 다시 켜지 않았습니다. 두 서비스의 공개 주소는 다음 날 아침까지 약 21시간 동안 502 를 돌려줬습니다. 재시도 설정은 그 21시간 내내 한 번도 반응하지 않았습니다.
재시도 설정은 무엇을 실패로 보았나
다음 날 아침 작업 설정을 다시 열어 보고 원인을 찾았습니다. 재시도 설정은 '작업 시작에 실패했을 때'에만 걸려 있었습니다. 작업이 정상적으로 시작됐다가 업데이트 때문에 같이 끝난 것은 시작 실패가 아닙니다. 그래서 재시도 조건에 걸리지 않았습니다.
실행 조건도 같은 구멍이 있었습니다. '부팅 시'와 '로그온 시'는 둘 다 시작하는 순간만 받습니다. 이미 떠 있던 WSL 이 도중에 꺼지는 경우는 두 조건 어디에도 해당하지 않았습니다.
꺼진 경우 | 부팅 시·로그온 시 | 시작 실패 재시도 | 5분 반복 실행 |
|---|---|---|---|
서버 재부팅 | 받음 | - | 받음 |
작업이 처음부터 시작 못 함 | - | 받음 | 받음 |
업데이트로 도중에 꺼짐 | 못 받음 | 못 받음 | 받음 |
누가 손으로 끔 | 못 받음 | 못 받음 | 받음 |
표의 셋째 줄(업데이트로 도중에 꺼짐)이 이번 사건입니다. 재시도 설정을 보고 안심했지만, 그 설정이 실패로 세는 것은 넷 중 하나뿐이었습니다.

고친 것 하나: 5분마다 다시 실행합니다
재시도 조건을 넓히는 대신, 깨워 두는 작업에 '5분마다 반복 실행' 조건을 더했습니다. 꺼진 원인이 무엇이든 5분 안에 작업이 한 번은 다시 돕니다.
부작용을 막는 것은 작업의 중복 실행 규칙입니다. 이 작업은 '새 인스턴스 무시(IgnoreNew)'로 설정돼 있었습니다. 이미 돌고 있으면 그 회차는 그냥 넘어간다는 뜻입니다. 그래서 WSL 이 멀쩡히 떠 있는 동안에는 5분마다 아무 일도 일어나지 않습니다. 규칙이 '새로 하나 더 띄운다'였다면 5분마다 작업이 쌓였을 겁니다.
작업 시간은 25분이었습니다. 다만 설정을 바꾼 것만으로는 아무것도 확인되지 않습니다.
안전망은 실제로 쓰일 때까지 작동하는지 알려 주지 않습니다. 롤백 장치가 몇 달째 아무 일도 안 하고 있었던 다른 사례도 같은 구조였습니다.
저절로 켜졌는지 확인하려다 직접 켤 뻔했습니다
다음 날 09:11 에 `wsl --terminate`(WSL 배포판을 강제로 끄는 명령)로 일부러 껐습니다. 그리고 저절로 다시 켜지는지 기다렸습니다.
여기서 함정이 하나 있었습니다. WSL 은 안에 접속만 해도 그것만으로 켜집니다. '켜졌나' 보려고 WSL 안에 들어가 보면, 그 확인이 곧 켜는 행동이 됩니다. 그러면 작업 스케줄러가 켰는지 내가 켰는지 가를 수 없습니다.
그래서 WSL 안으로는 들어가지 않고 두 가지만 봤습니다. 하나는 바깥에서 상태 목록만 보여 주는 `wsl -l -v` 이고, 다른 하나는 공개 주소의 응답입니다. 09:16:41 에 WSL 이 저절로 켜졌고, 공개 주소는 200 을 돌려줬습니다. 끈 뒤 5분 41초였습니다.
검사를 고를 때는 '이게 아니라면 무엇이 보일까'를 먼저 묻습니다. 확인하는 행동이 결과를 바꾸면 그 검사는 아무것도 가르지 못합니다.
켜진 직후, 앱이 DB 보다 먼저 떴습니다
두 번째 문제는 '켜진 직후'에 있었습니다. 그날 아침 21시간 만에 WSL 을 처음 다시 올렸을 때(09:07) 메신저 알림이 울렸습니다. 엔진은 바로 뜨는데 그래프 DB 가 늦게 준비됐습니다. 그 사이에 돈 백업과 색인 회차가 DB 연결 실패를 냈습니다.
백업이 이 순간에 도는 데는 이유가 있습니다. 백업 타이머에 'Persistent'(꺼져 있는 동안 놓친 회차를 기동 직후 한 번 돌리는 systemd 타이머 옵션)가 걸려 있었습니다. 21시간 동안 놓친 회차가 WSL 이 켜지자마자 돌았고, 아직 준비 안 된 DB 에 붙으려다 실패했습니다. 09:16 에 일부러 끈 시험에서도 두 엔진 모두 연결 실패 로그를 남겼습니다.
포트를 보고 기다리게 하는 방법은 소용이 없었습니다. 도커가 포트를 먼저 받아 두기 때문입니다. DB 가 아직 준비되기 전에도 포트는 이미 연결을 받고 있었습니다. 포트가 응답한다는 것과 DB 가 질의를 받을 수 있다는 것은 다른 이야기였습니다.

고친 것 둘: 포트가 아니라 실제 응답을 기다립니다
'DB 준비 대기' 스크립트를 만들어 엔진과 백업 서비스가 시작하기 전에 돌게 했습니다. 준비 판정은 포트가 아니라 그 DB 의 실제 응답으로 합니다.
Neo4j — Bolt 프로토콜(Neo4j 의 접속 프로토콜) 핸드셰이크가 실제로 성립하는지 본다
Qdrant — `/readyz`(준비 상태를 알려 주는 엔드포인트)가 준비 완료를 돌려주는지 본다
최대 300초까지 기다리고, 그래도 안 되면 실패로 끝낸다
서비스 설정 파일은 건드리지 않고 systemd drop-in(원래 유닛 파일 옆에 덧붙이는 설정 조각)으로 붙였습니다. 엔진은 기다리는 시간 때문에 시작 제한 시간(`TimeoutStartSec`)을 360초로 늘렸습니다.
[Service]
ExecStartPre=<DB 준비 대기 스크립트> # 최대 300초
TimeoutStartSec=360작업 시간은 30분이었습니다. 확인은 두 단계로 했습니다. 먼저 스크립트만 따로 돌려, 떠 있는 DB 에는 통과하고 없는 포트에는 실패하는 것을 봤습니다. 그다음 WSL 을 다시 일부러 껐다 켰습니다.
고치기 전 (09:16) | 고친 뒤 (09:24) | |
|---|---|---|
엔진 기동 | DB 보다 먼저 뜸 | 약 30초 기다린 뒤 뜸 |
연결 실패 로그 | 두 엔진 모두 남음 | 0건 |
공개 주소 | - | 200 |
그날 실패한 백업 두 건은 손으로 다시 돌려 둘 다 성공했습니다. 두 가지를 고치는 데 합쳐서 55분 정도 들었습니다. 장애는 21시간이었습니다.

아직 확인 못 한 것
확인된 것은 두 가지입니다. WSL 이 꺼지면 5분 안에 다시 켜진다는 것, 그리고 켜진 뒤 엔진이 DB 를 기다렸다가 뜬다는 것입니다. 둘 다 실제로 꺼 보고 봤습니다.
밀린 백업이 WSL 기동 직후에 도는 경로는 설정만 넣었습니다. 다음 업데이트 때 'db ready after N초' 로그 뒤에 백업이 성공하는지를 봐야 합니다. 거기서 실패하면 이 글의 결론 일부가 바뀝니다.
하나 더 남은 것이 있습니다. drop-in 설정 파일이 저장소 밖에 있어서 이번 변경도 그 서버에만 있습니다. 서버를 다시 만들면 이 변경이 사라집니다. 이 점은 아직 해결하지 않았습니다.
같은 구성을 운영하고 있다면
윈도 위의 WSL 로 상시 서비스를 돌리고 있다면 아래를 확인해 보세요.
재시도 설정이 어떤 종료를 실패로 세는지 본다. 정상 종료·외부 종료·업데이트로 인한 종료는 대개 실패가 아니다
'꺼지면 다시 켠다'가 목적이면 주기 실행을 건다. 이때 중복 실행 규칙이 '이미 돌고 있으면 넘어간다'인지 같이 확인한다
5분 주기는 최대 5분 남짓의 장애를 받아들이는 선택이다. 더 짧아야 하면 주기를 줄이거나 다른 감시 방식을 붙인다
DB 준비는 포트가 아니라 프로토콜 응답이나 준비 확인 엔드포인트로 본다. 도커 앞의 포트는 DB 보다 먼저 응답한다
자동 복구는 일부러 꺼서 확인한다. 확인하는 행동이 상태를 바꾸지 않는지 먼저 본다
이번 일은 재시도 설정이 없어서 생긴 장애가 아니었습니다. 설정이 있었고, 그 설정이 이번 꺼짐을 실패로 세지 않았습니다. 둘 다 일부러 꺼 보기 전에는 보이지 않았습니다.