ICA — Istio Certified Associate
The response failed, but the business operation committed
한국어 원문으로 표시합니다.
목표
실제 Istio 재시도와 업무 기록을 비교하고, 응답 시간 초과·프로세스 종료가 생겨도 동일 업무의 중복을 막는 트랜잭션 경계를 구현합니다.
왜 중요한가
200은 업무 한 번의 증명이 아니고 504는 롤백의 증명이 아닙니다. 같은 주문의 전송 시도마다 새 업무 키를 만들면 중복 방지 장치도 무력해집니다. 반대로 내용이 같은 다른 주문을 합쳐도 오류입니다. 이 실습은 실제 메시의 합성 HTTP 업무와 별도 트랜잭션 코드 수정을 함께 다룹니다. 학생 코드 수정은 임시 SQLite 시험에 적용되며 HTTP 서버 코드를 자동 교체하는 기능은 아닙니다.
단계
- python3 /opt/fixtures/ica-retry/runtime.py inventory의 출력 전체를 /root/ica-retry/inventory.json에 저장합니다. namespace는 ica-retry이며 client와 upstream의 실제 프록시가 준비되어야 합니다.
- /root/ica-retry/routes.yaml에 networking.istio.io/v1 VirtualService retry-lab을 만듭니다. namespace는 ica-retry, hosts와 모든 목적지는 upstream.ica-retry.svc.cluster.local, 포트는 8080입니다. 첫 라우트 flaky는 /flaky·/naive exact 두 match, timeout 1s, attempts 2, perTryTimeout 1s, retryOn '503', retryIgnorePreviousHosts false입니다. 두 번째 lost는 /lost exact, timeout 500ms, attempts 0입니다. 마지막 control은 match 없이 같은 목적지, attempts 0입니다. 적용 후 collect retry를 실행해 retry.json의 실제 수신·업무 횟수를 비교합니다.
- 같은 도구의 collect timeout을 실행합니다. timeout.json에는 /lost의 클라이언트 504, 서버의 커밋된 응답, 같은 키로 /charge를 호출한 회수 결과가 함께 있어야 합니다. 숫자를 직접 만들어 쓰지 않습니다.
- collect conflict로 conflict.json을 저장합니다. 같은 업무 키에 금액을 100에서 200으로 바꾼 요청이 409를 받고 기존 업무 금액은 100으로 남는지 확인합니다.
- collect durability로 durability.json을 저장합니다. 도구는 이 VM 안의 upstream 파드만 실제 삭제·재생성합니다. client UID는 같고 upstream UID·서버 instance는 달라야 합니다. 같은 업무 키와 응답 ID는 보존돼야 합니다.
- /opt/fixtures/ica-retry/broken.py를 /root/ica-retry/transaction.py로 복사하고 charge의 기본 실행에 있는 분리 커밋 결함을 고칩니다. initialize·charge·Conflict, after-business·after-key·after-commit 강제 종료 지점을 유지합니다. 커밋 전에는 업무·키 모두 0개, 커밋 후에는 둘 다 1개가 남고 재시도 후 업무는 항상 1개여야 합니다.
- transaction_probe.py /root/ica-retry/transaction.py identity로 같은 키의 동시 요청 8개를 확인합니다. 새 처리는 하나여야 하며 같은 키의 고객·금액 변경은 Conflict, JSON 순서 변경은 같은 응답, 다른 키의 같은 내용은 별개 업무여야 합니다. 잘못된 금액과 알 수 없는 필드는 ValueError로 거절합니다.
- /root/ica-retry/incident.json에 추가 시도 2·최대 시도 3·naive 업무 3·중복 방지 업무 1을 기록합니다. timeout_means_rollback과 external_payment_exactly_once는 false입니다. changed_payload_status는 실제 충돌 코드, durable_scope는 same-vm-disk, atomic_scope는 single-sqlite-file로 적습니다. 앞선 실제 관측도 그대로 남겨 최종 채점합니다.
참고
- 명령 예: python3 /opt/fixtures/ica-retry/runtime.py collect timeout. 관측 파일이 있으면 기존 결과를 보존합니다. 새 시험이 필요하면 자기 관측 파일을 다른 이름으로 보관한 뒤 실행하세요.
- 처음 apply한 정책은 Envoy에 전파될 시간이 필요합니다. collect가 라우트 불일치를 말하면 실제 proxy-config routes를 확인하세요.
- broken.py는 분리 커밋 사고를 재현하는 의도적 오답입니다. 채점은 학생 파일을 고치지 않고 임시 DB에서 실행합니다.
- 부하 실험의 성공 비율이나 응답 속도 자체를 정답으로 외우지 마세요. 업무 키별 상태를 봅니다.
- 같은 VM의 디스크 보존만 다룹니다. VM 종료·전원 차단·외부 결제의 exactly-once는 보장하지 않습니다. 개인 자료·실제 결제 정보를 넣지 마세요.
실제 프록시와 파드 신원 기록
inventory 명령으로 두 파드의 UID를 기록합니다. Running 이름만 보지 말고 실제 프록시가 준비됐는지 확인하세요.
세 번 수신과 세 번 업무를 구별하기
routes.yaml를 적용하고 collect retry를 실행하세요. attempts는 추가 시도이며 /naive와 /flaky의 업무 장부를 따로 봅니다.
504 뒤 이미 커밋된 업무 회수
/lost의 500ms 예산과 재시도 없음 조건을 확인하세요. collect timeout은 같은 업무 키로 /charge에 다시 묻습니다.
같은 키의 다른 금액 거절
collect conflict의 두 요청은 업무 키가 같고 금액만 다릅니다. 기존 업무와 응답이 보존됐는지 확인하세요.
파드를 바꿔도 같은 업무 응답
collect durability는 이 VM의 upstream만 교체합니다. 파드 UID와 서버 instance가 바뀌고 업무 ID는 같아야 합니다.
분리 커밋 결함을 코드로 고치기
broken.py를 transaction.py로 복사해 읽으세요. charge의 기본 실행에서 업무 쓰기와 중복 기록 사이에 커밋이 끼어 있는지 찾으세요.
동시 요청과 별개 업무의 경계
같은 키의 동시 요청은 하나로 합치고, 다른 키의 동일 내용은 별개 업무로 남깁니다. 내용 변경 거절과 JSON 순서도 확인하세요.
응답과 업무를 나눈 사고 보고서
최대 시도 수와 실제 업무 효과를 구분하고, 보장 범위를 단일 SQLite 파일·같은 VM 디스크로 한정하세요.