Devin.KR

장애 기록과 수료 설명

50분 안팎

학습 목표

관측 근거·복구·후속 테스트와 설계 선택을 설명합니다.

개념

다음 담당자가 재현할 수 있게 넘깁니다

신입 개발자의 수료 자료는 화면이 동작한다는 영상만으로 충분하지 않습니다. 다음 담당자는 도서와 회원이 어떻게 연결되고 어떤 요청을 거절하며 장애 때 어느 근거로 복원했는지 알아야 합니다. 이 레슨은 새 코드를 더하기보다 누적 구현의 설계 선택과 검증 범위를 설명하는 문서를 만듭니다. 제출물은 관계도·API 명세·권한 검사·동시 대여 근거·장애 타임라인·백업 복원 기록입니다. 각 주장 옆에는 파일이나 테스트 이름, 재실행 명령을 두어 기억이 아니라 증거로 대화하게 합니다.

사건의 영향부터 씁니다

장애 기록의 첫 문장은 기술 오류 이름보다 사용자에게 생긴 일을 설명합니다. 예를 들어 실습에서 조회 요청 한 건이 500으로 끝났고 해당 요청의 응답 ID로 로그를 찾았다고 적습니다. 표본이 한 건인데 모든 회원이 대여하지 못했다고 확대하지 않습니다. 실제 사고를 겪지 않았다면 주입된 DB 조회 실패의 리허설이라고 표시합니다. 영향받은 경로·요청 수·기간을 아는 범위에서 기록하고 모르는 부분은 확인 필요로 남깁니다. 확신의 정도를 분리하는 습관은 잘못된 원인 추정이 다음 변경으로 번지는 일을 줄입니다.

타임라인에 서로 다른 시계를 섞지 않습니다

발견·조사·복원 시작·검증 종료는 시간대가 포함된 달력 시각으로 정렬합니다. 한 요청의 처리 시간은 단조 시계 차이의 밀리초로 별도 열에 둡니다. 서버 로그의 시각과 다른 PC의 시각을 그냥 빼면 시계 차이가 섞일 수 있습니다. 이번 문서의 값은 본인이 실행해서 수집한 기록만 씁니다. 아직 실행하지 않은 Docker 점검에는 시각을 만들어 넣지 않습니다. 타임라인이 이어져 보이게 빈칸을 채우는 것보다 확인된 단계와 대기 중인 단계를 구별하는 편이 인계에 유용합니다.

관측과 가설을 문장으로 나눕니다

관측은 db-error ID의 완료 로그가 500과 INTERNAL_ERROR를 보였고 같은 ID의 예외 종류가 BadSqlGrammarException이라는 사실입니다. 없는 테이블 조회가 원인이라는 판단은 주입한 SQL과 재현 검사를 함께 보여 줄 때 설명할 수 있습니다. 운영에서도 같은 종류의 예외라면 조사 후보는 되지만 동일한 원인이라고 단정하지 않습니다. 메모리 값이 높았다는 관측을 누수라는 원인으로 곧장 바꾸지 않습니다. 가설 옆에는 이를 지지하거나 반박할 다음 검사를 적고 실행 후 결과를 덧붙입니다.

복구와 예방을 다른 칸에 둡니다

별도 DB 복원과 API 계약 검사는 상태를 되찾는 복구 작업입니다. 체크섬 검증 누락을 고치고 손상 파일 거절 테스트를 추가하는 것은 재발을 줄이는 후속 조치입니다. 두 항목을 섞으면 서비스가 정상화된 시점과 코드가 개선된 시점이 흐려집니다. 원본 DB를 유지하고 복원 DB에서 검사한 범위도 명시합니다. 실습에서 복원한 것을 실제 서비스 트래픽을 전환한 것처럼 쓰지 않습니다. 업무 전환은 DB 연결 변경·세션 상태·중복 쓰기·추가 검증을 포함한 별도 판단입니다.

관계도는 업무 규칙을 드러냅니다

MODEL.md를 기준으로 books와 members에 loans가 연결되고 active_loans가 현재 점유를 나타내는 구조를 설명합니다. active_loans의 book_id PK는 한 실물 도서에 현재 대여 한 건을 제한합니다. 복합 FK는 현재 대여의 책과 대여 이력이 맞는지 검사합니다. loan_requests의 회원·요청 키 PK는 멱등 범위를 정합니다. 이 테이블에 DB FK가 없는 관계는 논리 관계라고 표시하고 모든 선이 물리 제약이라고 그리지 않습니다. 반납 후 이력이 남는 이유와 현재 점유가 사라지는 이유도 각 테이블의 수명으로 설명합니다.

API 명세는 예쁜 목록보다 계약을 봅니다

API-SPEC.md에 메서드·경로·입력·성공 상태·거부 상태·인증·CSRF·Location을 대조합니다. POST /loans의 201만 적으면 같은 키 재생이나 다른 본문 충돌을 놓칩니다. 도서 조회는 공개이지만 대여 상세는 소유 회원만 읽습니다. 이 차이를 로그인하면 모든 자료를 볼 수 있다고 단순화하지 않습니다. 로그 ID는 응답 헤더에 있고 오류 JSON의 기존 형태를 유지했다는 결정도 적습니다. 문서가 구현과 다르면 문서만 그럴듯하게 남기지 말고 테스트가 어느 계약을 보장하는지 확인하여 수정합니다.

권한 증거는 거부 뒤 상태를 보여 줍니다

AccessSecurityTest의 타인 수정·일반 회원 도서 수정·CSRF 누락 검사를 선택하고 입력, 기대 상태, DB 불변 확인을 표로 적습니다. 403이 나왔다는 것만으로 쓰기가 없었다고 가정하지 않습니다. 테스트에서 제목·메모·대여 건수가 그대로인지 확인하는 부분을 함께 연결합니다. 복원 DB에서도 같은 경계를 확인한 BackupRestoreTest를 별도 근거로 둡니다. 테스트 이름과 실행 명령은 제출자가 실제 파일을 열어 대조한 값이어야 하며 실행하지 않은 검사에 통과 표시를 넣지 않습니다.

동시성과 재시도의 실패 순서를 설명합니다

ConcurrencyRetryTest에서 두 회원의 같은 책 경쟁은 성공 하나와 409 하나를 만들며 실패한 이력은 롤백됩니다. 같은 요청 키 경쟁은 같은 결과 ID를 돌려주고 응답 유실 후 같은 키 재시도도 새 대여를 만들지 않습니다. 키가 같아도 본문이 다르면 409입니다. 이 설명에는 트랜잭션 경계·DB 제약·회원별 키 범위를 함께 넣습니다. 한 스레드에서 synchronized를 사용했다는 설명만으로 여러 프로세스의 경합까지 해결했다고 쓰지 않습니다. 해결하려는 실패 종류가 무엇인지 먼저 밝힙니다.

재실행 경로와 산출물 식별자를 남깁니다

README-M10.md에는 압축을 푼 폴더, JDK·Boot·H2 버전, 캐시 준비, bash check.sh, 보고서 확인 경로를 적습니다. 실제 릴리스 jar를 제출한다면 그 파일의 해시와 어떤 테스트에서 사용했는지 연결합니다. 앞 모듈의 외부 컨테이너 리허설은 check-m09.sh로 보존되어 있지만 이번 로컬 검사로 실행했다고 쓰지 않습니다. PENDING은 외부 환경 확인을 기다리는 상태입니다. 작성한 Dockerfile을 읽어 확인한 것과 실제 이미지 빌드·HTTP 계약 검증은 다른 증거입니다.

비밀값은 증거 자료에도 넣지 않습니다

로그 파일 전체를 붙이기 전에 허용 필드와 요청 ID를 중심으로 필요한 부분만 고릅니다. 계정 해시·세션 쿠키·CSRF 토큰·실제 DB URL을 인계 문서에 넣지 않습니다. 백업 아카이브는 계정 정보와 회원 자료를 담을 수 있으므로 공개 저장소의 첨부물로 사용하지 않습니다. 이번 테스트는 가짜 회원을 사용하고 임시 폴더를 정리합니다. 운영 증거라면 보관 권한·기간·삭제 책임도 담당자와 합의해야 합니다. 안전한 자료 공유는 코드에서 비밀값을 제외하는 정책의 연장입니다.

동료가 물을 질문으로 리뷰합니다

왜 파일 저장소에서 JDBC로 바꿨는지, 왜 대여 상태와 이력을 분리했는지, 왜 다른 회원에게 404를 주는지에 대해 선택과 대안을 짧게 씁니다. 대안의 단점만 강조하기보다 이번 요구에서 얻은 이점과 남은 제한을 함께 설명합니다. 테스트는 의도한 계약을 확인하는 도구이고 운영의 모든 조건을 증명하지는 않습니다. 작은 MockMvc 관측에서 네트워크 지연을 제외했고 작은 복원 DB에서 대규모 복구 시간을 확인하지 못했다는 범위를 스스로 밝힐 수 있어야 합니다.

후속 작업은 검증 가능한 완료 기준을 둡니다

모니터링 강화라는 말 대신 실제 네트워크 경계 지연과 연결 획득 시간을 분리해 수집하고 표본 기간을 정한다는 작업을 적습니다. 백업 강화라면 권한이 제한된 보관소, 정기 별도 복원, 손상 파일 거절, 복구 소요 시간의 관측을 완료 기준으로 둡니다. 각 후속에는 담당 역할과 확인 방법을 쓰며 담당자를 임의로 지명하지 않습니다. 마지막으로 다른 사람이 README만 읽고 검사를 실행하여 같은 계약을 확인할 수 있는지 검토합니다. 재현되지 않는 성공 기록은 수료 설명의 근거로 사용하지 않습니다.

따라하기

증거 파일을 대조합니다

미션 solution 또는 완성한 starter에서 MODEL.md, API-SPEC.md, README-M10.md를 읽습니다. 물리 제약과 논리 관계를 구분하고 표에 테스트 이름을 연결합니다.

cat MODEL.md
cat API-SPEC.md
cat README-M10.md

실행 근거를 수집합니다

미션에서 검사를 실행하고 최종 보고서와 target/metrics 결과를 읽습니다. 본인 실행 시각과 환경을 기록하며 다른 사람의 출력이나 합성 지연값을 실제 관측으로 쓰지 않습니다.

bash check.sh

장애 기록을 작성합니다

HANDOFF-M10.md의 양식을 채웁니다. 영향, 요청 ID, 관측, 가설, 재현, 복구, 손실 경계, 검증 결과, 후속 순서로 작성하고 백업·토큰·해시는 공개 첨부하지 않습니다.

동료에게 설명할 준비를 합니다

관계도·API 메서드와 상태·권한 거절 후 불변·경합과 멱등·복원 범위를 각각 2~3문장으로 씁니다. 실행 환경에서 오류를 추적하는 순서를 증거 파일과 함께 말해 봅니다. 외부 Docker 리허설은 실제 실행 전까지 PENDING으로 남깁니다.

확인 문제

실습

미션 폴더의 HANDOFF-M10.md를 채워 제출합니다. 관계도·API 계약·권한 거부 뒤 DB 불변·경합과 멱등·요청 추적·복원 기록을 실제 테스트 이름과 명령으로 연결합니다. 주입한 장애의 영향·시각·관측과 가설·복구·손실 경계·후속 완료 기준을 적습니다. 외부 Docker PENDING과 로컬 통과를 구분하며 비밀값과 백업 내용을 첨부하지 않습니다.

더 읽기

면접 질문

  • 도서와 대여 기록의 테이블 관계를 설명합니다.
  • 인증에 성공했지만 수정 요청을 거부해야 하는 사례를 설명합니다.
  • 대여 처리의 트랜잭션 범위를 설명합니다.