--- kind: CASE slug: a-startup-probe-that-never-runs title: startup probe가 production에서 한 번도 실행되지 않는다 topic: redis-command-admission project: clean-architecture-backend-template status: 게시 전 sourceRevision: 21234e38cdb9a926cbc92bb97a2aee2e4a7d2916 rootTreeNode: case:a-startup-probe-that-never-runs evidenceCapturedOn: 2026-09-02 assets: - key: a-startup-probe-that-never-runs file: ../../../final/evidence/rendered/a-startup-probe-that-never-runs.svg evidence: - ../../../final/evidence/raw/a-startup-probe-that-never-runs.txt source: - 분석 문서는 cache-redis 어댑터 편 §6 이다. 그 절이 탐침이 확인하는 넷을 나열하고, 넷째의 javadoc 을 인용하고, 두 탐침의 프로덕션 참조가 javadoc 링크 하나뿐이라는 것과 자동설정이 탐침을 부르지 않는다는 것을 기록한다. 판정은 P2 이고, 수정은 자동설정에 탐침을 실행하는 빈 하나를 더하는 것이다. - 같은 사고의 더 상세한 기록은 저장소 문서 쪽에 있다. 지원 매트릭스가 승격과 강등 시각을 초 단위로 적고, 운영 문서와 런북이 가드를 적용한 뒤 같은 승격에서 무엇이 달라졌는지 적는다. --- # startup probe가 production에서 한 번도 실행되지 않는다 기동 시 서버 능력을 확인하는 탐침이 있다. 그것을 만들거나 부르는 프로덕션 코드가 없어 한 번도 실행되지 않는다. ## 관계 - **@Bean이 있다는 것은 조립 증거가 아니다** 이 사례가 그 규칙의 형태다. - **시작 검증기가 도는지는 그 능력에 자동설정 루트가 있는지와 일치한다** 시작 검증기가 도는지를 자동설정 루트로 확인하는 절차다. - **하위 시스템 전체가 미배선인데 그것을 켜는 플래그는 시작 검사를 수행한다** 플래그와 실행의 어긋남이 반대 방향으로 나타난 사례다. ## 문제 기동 탐침은 서버가 실제로 무엇인지 묻는다. 그것이 확인하는 것은 넷이다. 서버 버전, 클러스터와 데이터베이스 번호, 명시적으로 켠 능력의 실재, 그리고 복제 배포의 쓰기 내구성이다. 넷째의 javadoc 이 이 저장소의 실측 사고 기록을 숫자째로 담고 있다. ## 결론 그 기동 실패는 일어나지 않는다. 두 탐침 클래스를 언급하는 프로덕션 코드는 다른 설정 클래스의 javadoc 링크 하나뿐이고, 확인 메서드를 부르는 프로덕션 코드는 0 이다. 자동설정이 만드는 빈 일곱에 탐침은 없다. 로직은 완성되어 있고 테스트 열여덟 케이스가 네 규칙을 고정한다. 없는 것은 호출 지점 하나다. ## 검증 환경 OpenJDK : 21.0.12 확인 방식 : 정적 도달성 확인 소스 수정 : x ## 재현 조건 1. 기동 탐침의 클래스 javadoc 과 확인 메서드 본문을 읽고, 무엇을 몇 가지 확인하는지 센다. 2. 넷째 항목의 javadoc 에 적힌 사고 기록과 결론, 그리고 검사가 두 겹인 이유를 읽는다. 3. 두 탐침 클래스를 언급하는 프로덕션 코드를 세고 그것이 무엇인지 확인한다. 4. 확인 메서드를 부르는 프로덕션 코드를 센다. 5. 자동설정이 만드는 빈을 나열하고 그중 탐침이 있는지 센다. 6. 두 테스트 파일의 케이스 수를 센다. ## 본문 기동 탐침은 서버가 실제로 무엇인지 한 번, 기동 시에 묻는다. 이 탐침이 무엇을 막는지부터 본다. 그것이 실행되지 않는다는 판정이 무엇을 잃는 것인지가 거기서 정해진다. ## 확인하는 것은 넷이다 :::evidence key="a-startup-probe-that-never-runs" alt="코드베이스에서 기동 탐침이 자기를 소개하는 문단과 확인 메서드 본문이 부르는 두 검사, 넷째 항목의 javadoc 이 담은 실측과 결론과 검사가 두 겹인 이유, 두 탐침을 언급하는 프로덕션 코드 하나와 그것이 javadoc 링크라는 것과 확인 메서드를 부르는 코드 수, 자동설정이 만드는 빈 일곱과 그중 탐침의 수, 그리고 로직을 고정하는 테스트 케이스 수를 뽑은 출력 70줄. 탐침을 부르는 프로덕션 코드가 0 이고 자동설정의 빈 일곱에 탐침이 없다는 것이 그 출력에 보인다." caption="탐침의 소개 문단과 두 검사 · 넷째의 실측과 두 겹 검사 · 언급 1(javadoc 링크) · 호출 0 · 빈 일곱에 탐침 없음 · 테스트 18케이스 — 70줄" zoom="true" ::: 확인 메서드가 두 호출로 넷을 덮는다. 앞의 호출이 서버 버전과 배포 모드와 데이터베이스 번호와 명령 목록으로 능력을 판정하고, 뒤의 호출이 복제 배포의 쓰기 내구성을 요구한다. 클래스 javadoc 이 왜 서버에 묻는지 적는다. 설정은 배포가 무엇을 의도하는지 말하고 서버만이 무엇이 참인지 말한다는 것, 관리형 Redis 가 광고하는 버전이 모듈의 존재를 뜻하지 않는다는 것, 그리고 복제 배포의 쓰기 내구성은 어떤 클라이언트도 보상할 수 없는 서버 설정이라는 것이다. 같은 문단이 시점의 값도 적는다. 빠진 능력을 첫 요청에서 발견하면 장애이고, 여기서 발견하면 실패한 배포다. ## 넷째 항목의 javadoc 은 실측을 숫자째로 담는다 그 javadoc 은 이것이 SDK 가 보상할 수 없는 유일한 서버 설정이라고 적는다. 승격으로 밀려난 주 노드는 그 사실을 즉시 알지 못한다. 아는 순간까지 쓰기에 계속 성공을 답하고, 새 주 노드에서 재동기화할 때 그 쓰기들이 버려진다. 센티널 레인이 그것을 쟀다. 11초 동안 2,086건이 승인된 뒤 폐기됐고, 같은 실행에서 호출자에게 실패로 보인 명령은 통틀어 하나뿐이었다. 그 아래 문장이 왜 아무도 못 보는지 적는다. 서버가 답했으므로 드라이버도, 이 SDK 도, 호출자도 전부 성공으로 기록한다. 더할 지표도, 재시도할 실패도, 그것을 서술할 확신 값도 없다. ## 그래서 경고가 아니라 기동 실패다 복제 최소 개수와 상한이 걸린 최대 지연이 그 상황을 호출자가 대응할 수 있는 거절로 바꾼다. 같은 승격이 그때는 2,086건 대신 한 건을 잃었다. 그래서 그 설정 없는 복제 배포는 경고가 아니라 기동 실패라고 적는다. 보증을 무의미하게 만드는 설정은 조용히 성능을 낮추는 대신 컨텍스트를 멈춘다는 것이 이 SDK 의 원칙이라는 것이다. 면제는 가능하다. 배포가 정말로 쓰기 하나를 잃어도 괜찮을 수 있고 이 SDK 가 서버를 소유하지 않기 때문이다. 다만 면제에는 명시적 설정이 필요해서, 그 거래가 사고 중에 발견되는 대신 기록으로 남는다. ## 그 검사 자체도 한 번 고쳐졌다 같은 javadoc 이 검사가 두 겹인 이유를 적는다. 복제 개수만으로는 몇 개가 연결되어 있어야 하는지만 정해진다. 얼마나 뒤처져도 되는지는 최대 지연이 정하고, Redis 는 그 값 0 을 지연 요구 없음으로 다룬다. 그래서 복제 둘을 요구하면서 지연 상한을 0 으로 둔 배포는, 임의로 뒤처진 복제 둘이 붙어 있기만 하면 쓰기를 받는다. 개수 요구가 없애려던 바로 그 노출이 그대로 남는다. 개수만 검사하던 동안 그 설정이 통과했다. 그러면서 실패 메시지는 운영자에게 지연 상한을 설정하라고 말하고 있었다. ## 그 기동 실패는 일어나지 않는다 두 탐침 클래스를 언급하는 프로덕션 코드가 하나뿐이다. 그것도 다른 설정 클래스의 javadoc 안에 있는 링크다. 확인 메서드를 부르는 프로덕션 코드는 0 이다. 자동설정은 빈 일곱을 만든다. 설정과 그 검증, 자격증명, 런타임 클라이언트와 소유자, 그리고 헬스 지표 둘이다. 그중 탐침은 0 이다. ## 없는 것은 호출 지점 하나다 로직은 완성되어 있다. 두 테스트 파일의 열여덟 케이스가 네 규칙을 고정한다. 탐침이 연결을 들고 있지 않은 것은 설계된 것이다. 서버 사실을 인자로 받아서, 같은 로직을 단위 테스트와 실제 레인이 함께 쓰고 어느 계정이 물을지를 호출자가 정한다. 그 사실 중 둘을 읽는 명령이 관리 평면이라 애플리케이션 계정은 거부된다. 그래서 조립은 관리 계정이 설정된 배포에서만 완전하다. ## 지금 남은 것은 장애 쪽이다 빠진 능력을 첫 요청에서 발견하면 장애이고 여기서 발견하면 실패한 배포다. 조립이 없으므로 남은 것은 앞쪽이다. 복제 내구성은 그마저도 아니다. 서버가 성공을 답하므로 장애로도 나타나지 않는다. ## 확인하지 못한 것 애플리케이션을 부팅해 탐침이 실행되지 않는 것을 관측하지 않았다. 정적으로 도달성만 확인했고, 위 실측값은 이 저장소의 센티널 레인이 잰 것을 javadoc 에서 인용한 것이지 이 기록을 위해 다시 잰 것이 아니다.