자가 복구
Arkvory는 운영자 없이 실패한 서비스를 스스로 다시 시작하고 중단된 작업을 재개합니다. 이 페이지는 무엇이 다시 시작되는지, 각 복구에 얼마나 걸리는지, 어떤 문제에 여전히 사람이 필요한지를 정리합니다. 서버 한 대는 고가용성 시스템이 아닙니다. 재시작은 짧은 시간 동안 연결을 끊고, 클라이언트는 전송을 재개합니다.
스스로 다시 시작하는 것
모든 서비스는 플랫폼의 서비스 관리자 아래에서 실행됩니다. API, 워커, 백업 에이전트는 안전하게 계속할 수 없을 때 자체 프로세스를 종료합니다. 그러면 서비스 관리자가 새 프로세스를 시작합니다.
| 상황 | Linux(systemd) | Windows 서비스 | Docker Compose |
|---|---|---|---|
| 충돌, 강제 종료, 메모리 부족 | 10초 후 다시 시작 | 10초 후 다시 시작 | 엔진이 점점 늘어나는 일시 중지와 함께 컨테이너를 다시 시작 |
| 중지 요청 없이 종료, 종료 코드 0인 경우도 포함 | 다시 시작 | 런처가 종료를 코드 1로 바꾸고 10초 후 다시 시작 | 다시 시작 |
| 스토리지 소유권 또는 임대 상실 | 종료 1, 다시 시작 | 종료 1, 다시 시작 | 종료 1, 다시 시작 |
| 메인 스레드 멈춤 | 워치독이 프로세스를 종료, 다시 시작 | 동일 | 동일 |
| 시작할 때 데이터베이스 연결 불가 | 종료 1, 10초마다 재시도 | 종료 1, 10초마다 재시도 | 종료 1, 점점 늘어나는 일시 중지와 함께 재시도 |
| 머신 재시작 | 서비스가 multi-user.target에서 활성화됨 | 자동(지연된 시작) | 컨테이너 엔진과 함께. Docker Desktop: 사용자가 로그인한 후 |
| 직접 서비스를 중지 | 다음 부팅까지 중지 상태 유지 | 다음 부팅까지 중지 상태 유지 | docker compose stop은 중지 상태 유지 |
스스로 실패한 준비 상태 확인은 서비스를 다시 시작하지 않습니다. 중지 전에 프로세스가 드레이닝 중이거나, 스토리지 디렉터리의 폴더가 없기 때문에 실패할 수 있습니다. 재시작으로는 이런 원인이 해결되지 않습니다.
Windows 서비스
그래픽 설치 프로그램과 install.ps1은 NT AUTHORITY\LocalService 계정을 공유하는 Arkvoryapi, Arkvoryworker, Arkvorybackup과 관리형 데이터베이스용 데이터베이스 서비스 Arkvorydatabase를 등록합니다. Windows를 참조하세요.
- 시작 유형. API, 워커, 백업 에이전트는 자동(지연된 시작)을 사용합니다. 데이터베이스는 자동을 사용합니다. 지연된 시작은 서비스가 부팅 직후가 아니라 부팅 후 어느 정도 시간이 지나서 올라온다는 뜻입니다.
- 복구 동작. 실패 후 Windows는 10초 뒤에 서비스를 다시 시작합니다. 같은 동작이 이후 모든 실패에 반복됩니다. 실패 카운터는 한 시간 후에 초기화됩니다. 복구 동작은 프로세스가 오류 코드로 종료될 때도 적용됩니다.
- 중지 시간 초과. 실행 중인 요청이 끝날 수 있도록 120초입니다.
- 로그. 모든 서비스의 출력은
logs\로 가며 20 MiB에서 회전하고 이전 파일 5개를 유지합니다.
서비스의 복구 동작을 표시하세요:
sc.exe qfailure Arkvoryapi그래픽 설치 프로그램을 다시 실행하면 시작 유형과 복구 동작이 복원됩니다. 직접 중지한 서비스는 중지 상태로 유지됩니다.
Linux systemd 유닛
패키지와 install.sh는 arkvory-api, arkvory-worker, arkvory-backup을 만들고, 데이터베이스가 관리형이면 arkvory-database도 만듭니다.
Restart=always와RestartSec=10은 요청하지 않은 모든 종료 후에 API, 워커, 백업 에이전트를 다시 시작합니다. 종료 코드 0도 포함됩니다.StartLimitIntervalSec=0은 재시작 시도 제한을 제거하므로 systemd는 실패하는 서비스를 절대 포기하지 않습니다. 잘못된 설정 같은 영구적인 결함은 고칠 때까지 10초마다 재시작을 일으킵니다.- 데이터베이스 유닛은 같은 10초로
Restart=on-failure를 사용합니다. TimeoutStopSec=120은 중지하는 서비스에 2분을 줍니다.- 유닛은
multi-user.target에 대해 활성화됩니다.
systemctl is-enabled arkvory-api arkvory-worker arkvory-backup
systemctl status arkvory-api arkvory-worker arkvory-backup네이티브 서비스에는 systemd만 지원됩니다. 다른 init 시스템을 사용하는 시스템에서는 Docker Compose를 사용하세요.
Docker Compose
프로젝트 proanima-arkvory의 모든 서비스는 restart: unless-stopped를 사용합니다. 일회성 단계인 initialize와 migrate는 다시 시작하지 않습니다.
- API 컨테이너에는 상태 확인이 있습니다. 10초마다 상태 키로
/health/ready를 요청하며, 시작 기간은 20초입니다. 비정상 컨테이너는 표시되지만 Docker가 다시 시작하지는 않습니다. 워커는 시작할 때 정상 API를 기다립니다. - 컨테이너에는 중지할 120초가 주어집니다.
- 컨테이너 엔진은 부팅 시 시작해야 합니다. Linux에서는
systemctl is-enabled docker를 확인하세요. Arkvory는 엔진을 변경하지 않습니다. - Windows의 Docker Desktop은 한 사용자의 애플리케이션입니다. 사용자가 로그인하고 Docker Desktop이 시작되기 전에는 컨테이너가 실행되지 않습니다. Start Docker Desktop when you sign in을 켜세요. 설치 프로그램과
arkvory status는 이것이 꺼져 있으면 경고합니다. 로그인 없이 시작해야 하는 서버에는 네이티브 Windows 서비스를 사용하세요.
응답 중단 후 다시 시작
프로세스는 종료되지 않은 채로 작동을 멈출 수 있습니다. 무한 루프, 차단 호출, 네이티브 코드의 응답 중단 등입니다. 프로세스가 아직 존재하기 때문에 서비스 관리자는 이를 보지 못합니다. 따라서 API, 워커, 백업 에이전트 각각에는 워치독이 있습니다.
- 메인 스레드가 1초에 한 번 카운터를 올립니다.
- 두 번째 스레드가 1초에 한 번 카운터를 확인합니다.
- 카운터가
ARKVORY_WATCHDOG_SECONDS번 연속 확인 동안 움직이지 않으면(기본 60), 워치독은 필드stalledSeconds와 함께 레코드process.stalled를 표준 오류에 기록하고 프로세스를 종료합니다. - 서비스 관리자는 충돌 후처럼 프로세스를 다시 시작합니다.
워치독은 시계 시간이 아니라 자체 틱을 셉니다. 호스트가 절전 상태가 되거나 가상 머신이 일시 중지되면 두 스레드가 모두 멈추고, 깨어난 뒤에 없는 응답 중단이 감지되지 않습니다. 따라서 응답 중단은 최대 60초에 재시작의 10초를 더한 만큼 걸립니다.
ARKVORY_WATCHDOG_SECONDS는 10~3600을 받습니다. 값 0은 워치독을 끕니다. 제한보다 오래 일시 중지된 프로세스는 다시 시작되므로, 디버거가 프로세스를 일시 중지할 때만 사용하세요. 긴 차단 작업도 응답 중단으로 간주됩니다. 워치독 자체가 시작할 수 없으면 서비스는 process.watchdog_failed를 기록하고 워치독 없이 계속 실행합니다. 관리형 PostgreSQL에는 워치독이 없습니다. 충돌 후에는 서비스 관리자가 다시 시작합니다. 환경 변수를 참조하세요.
데이터베이스 세션 또는 스토리지 소유권 상실
API는 데이터베이스 세션으로 자신이 스토리지 디렉터리의 유일한 기록자임을 증명합니다. 세션은 2초마다 확인되며, 8초 안에 응답하지 않는 확인은 상실로 간주됩니다. 워커도 같은 방식으로 자신의 역할을 증명합니다. 두 번째 프로세스가 넘겨받았을 수 있으므로 소유권은 실행 중인 프로세스 안에서 복원되지 않습니다.
소유권을 상실하면, 예를 들어 PostgreSQL 재시작 후에 프로세스는:
api.ownership_lost또는worker.ownership_lost를 기록하고,- 작업 수락을 중단하고 전송을 취소하며,
- 코드 1로 종료합니다.
서비스 관리자는 새 프로세스를 시작하고, 이 프로세스는 모든 것을 처음부터 다시 확인합니다. 데이터베이스가 중단된 동안 새 프로세스는 시작할 수 없으며, PostgreSQL이 응답할 때까지 API는 10초마다 종료하고 다시 시작합니다. 이는 예상된 동작입니다. 그동안 클라이언트는 Retry-After와 함께 503 unavailable을 받습니다. 실행 중인 백업 에이전트는 데이터베이스가 없어도 종료하지 않습니다. 오류를 기록하고 폴링 간격(기본 15초) 후에 다시 시도합니다.
진행 중인 작업은 어떻게 되는가
충돌은 열려 있는 연결을 끊습니다. 승인된 데이터는 남습니다. 다음에 무슨 일이 일어나는지는 작업 종류에 따라 다릅니다.
| 작업 | 재시작 후 |
|---|---|
| 다운로드 | 클라이언트가 범위 요청으로 재개합니다. SDK와 명령줄 클라이언트는 이를 스스로 수행합니다 |
| 멀티파트 업로드 | 기록된 파트는 서버에 남습니다. 클라이언트가 어떤 파트가 있는지 묻고 없는 파트를 보냅니다. 세션은 생성 시점부터 7일 동안 열린 상태로 유지됩니다 |
| 전체 파일을 단일 요청으로 업로드 | 클라이언트가 파일을 첫 바이트부터 다시 보냅니다 |
| 워커에 의한 업로드 완료 | 아래 참조 |
| 백업 | 아래 참조 |
| 미러 동기화 | 워커는 적용된 모든 변경 후에 위치를 저장하고, 첫 번째 누락된 파트부터 파일을 복사합니다. 실패 후에는 2초를 기다리고, 시도 사이의 간격을 두 배로 늘려 최대 5분까지 기다립니다 |
| 업데이트 | 설치 프로그램은 잠금과 저널을 유지합니다. 스스로 계속하지 않습니다. 문제 해결을 참조하세요 |
SDK와 명령줄 클라이언트는 네트워크 실패와 408, 429, 502, 503, 504 응답을 제한된 횟수만큼 반복합니다. 다른 클라이언트는 자체 재시도가 필요합니다. 전송을 참조하세요.
완료 작업. 큰 업로드는 워커가 마무리합니다(SDK와 명령줄 클라이언트는 16 GiB부터 이렇게 합니다). 워커는 작업에 대해 30초의 임대를 보유하고 2초마다 갱신합니다. 워커가 충돌하면 임대는 30초 안에 만료되고, 다시 시작된 워커가 작업을 다시 가져갑니다. 작업은 최대 5번 실행됩니다. 실패 후에는 2초를 기다리고, 두 배로 늘려 최대 60초까지 기다립니다. 다음 오류는 작업을 즉시 끝냅니다: forbidden, invalid_input, integrity_mismatch, not_found. 모든 시도를 다 쓴 작업은 레코드 completion.attempts_exhausted를 받습니다. 같은 업로드의 완료를 다시 요청하면 작업이 다시 대기열에 들어갑니다. 완료는 저장된 바이트를 검사하므로 반복해도 안전합니다.
같은 데이터베이스의 두 번째 워커는 대기 상태(worker.standby)로 기다리며, 첫 번째 워커가 사라졌는지 5초마다 확인합니다.
백업 에이전트. 에이전트는 60초의 임대(ARKVORY_BACKUP_LEASE_SECONDS)를 보유하고 20초마다 갱신합니다. 충돌 후에는 다른 에이전트나 다시 시작된 에이전트가 임대가 만료될 때 가져가므로, 백업은 최대 1분을 기다립니다. 중단된 작업은 같은 키로 최대 5번 다시 실행됩니다. 새 캡처는 죽은 캡처의 잠금을 해제합니다. 하트비트 없이 2분이 지나면 경고 agent_offline이 나타납니다. 업데이트 중에 설치 프로그램은 에이전트를 먼저 중지하고, 실행 중이던 백업은 interrupted로 끝나 다시 대기열에 들어갑니다.
속도 제한. 주소별 로그인 카운터는 프로세스에 있으며 재시작 시 초기화됩니다. 계정의 백오프는 데이터베이스에 있으며 유지됩니다.
시작할 때 확인
각 프로세스는 서비스를 제공하기 전에 환경을 확인합니다. 확인이 실패하면 프로세스는 종료 코드 1과 startup.failed(API) 또는 worker.unavailable(워커) 한 줄로 끝납니다. reason은 시크릿 없이 원인을 나타냅니다.
| 프로세스 | 확인하는 내용 |
|---|---|
| API | 모든 설정에 유효한 값이 있습니다. 메시지는 값이 아니라 변수 이름을 알려 줍니다. 키 파일은 최대 1 MiB까지 JSON으로 읽힙니다. 내장 TLS: 인증서와 키를 읽을 수 있고, 일치하며, 만료되지 않았습니다. HTTP로의 폴백은 없습니다. 스토리지 디렉터리에 쓸 수 있습니다. 데이터베이스가 응답하고 이 릴리스의 모든 마이그레이션이 있으며 더 새로운 릴리스의 마이그레이션은 없습니다. 스토리지 디렉터리의 파일 storage-id가 데이터베이스에 저장된 ID와 일치합니다. 다른 기록자가 데이터베이스를 보유하지 않습니다 |
| 워커 | 같은 설정, 데이터베이스, 스토리지 ID, 그리고 단일 워커의 잠금. 두 번째 워커는 대기 상태로 기다립니다 |
| 백업 에이전트 | 스토리지 ID, 스키마 번호, 그리고 백업 보관소가 스토리지 디렉터리와 겹치지 않는지. 없거나 마운트되지 않은 백업 보관소는 치명적이지 않습니다. 에이전트는 이를 경고로 보고합니다 |
업데이트 후 설치 프로그램은 세 번 연속 성공한 준비 상태 응답과 실행 중인 워커를 기다립니다. 그런 다음 백업 에이전트의 하트비트를 약 90초 동안 기다립니다. 에이전트가 없으면 경고일 뿐이며 업데이트를 롤백하지 않습니다.
여전히 사람이 필요한 것
자가 복구는 프로세스의 실패를 다룹니다. 다음은 운영자가 필요합니다:
- 영구적인 결함. 잘못된 설정, 연결할 수 없는 데이터베이스, 가득 찬 디스크, 잘못된 권한은 서비스가 성공하지 못한 채 10초마다 다시 시작되게 합니다.
startup.failed를 읽고 원인을 고치세요. 문제 해결을 참조하세요. - 실패한 업데이트. 중단된 업데이트는
recover를 실행할 때까지 잠금과 저널을 유지합니다. - 손상된 백업.
verify_failed와vault_unavailable은 사람이 필요합니다. 에이전트는 백업 보관소를 변경하지 않고 유지합니다. - 인증서. Arkvory는 재시작 없이 갱신된 인증서 파일을 읽지만(기본 300초마다), 도구가 인증서를 갱신해야 합니다.
- 중지된 서비스. 직접 중지한 서비스는 중지 상태로 유지됩니다.
- 플랫폼. Docker는 부팅 시 시작해야 합니다. PostgreSQL 주 버전, Node.js, 운영 체제는 직접 업데이트해야 합니다.
- 서버 또는 디스크 상실. 장애 조치가 없습니다. 백업에서 복원하세요. 백업을 참조하세요.