종합 연습 — HTTP 대화를 케이스로 읽어낸다
실무의 장애 조사를 본뜬 8 가지 케이스에 「무엇을 부탁했는가·결과는 어땠는가·조건과 보충」의 3 점 세트 읽기를 적용하여, 전 6 장의 지식을 가로질러 쓴다.
마무리의 8 문제 — 케이스에 3 점 세트를 적용한다
마지막 장은 종합 연습입니다. 실무에서 만나는 장면을 본뜬 8 가지 케이스에, 전 6 장의 지식을 가로질러 답합니다. 망설여지면, 이 강좌의 구호로 돌아와 주세요 — 무엇을 부탁했는가? 결과는 어땠는가? 조건과 보충은 무엇인가?
| 막히면 | 돌아갈 장 |
|---|---|
| 메시지의 뼈대·스테이트리스 | 제 1 장 |
| 메서드의 구분·안전과 멱등·재시도 | 제 2 장 |
| 상태 코드의 분류와 구분 | 제 3 장 |
| Host·Content-Type·Cookie 등의 헤더 | 제 4 장 |
| max-age·ETag·304·no-store | 제 5 장 |
| curl 과 Network 탭의 관찰 절차 | 제 6 장 |
케이스 조사의 틀입니다. 증상에서 출발해, 리퀘스트 행(무엇을 부탁했는가) → 상태 코드(결과는 어땠는가) → 헤더(조건과 보충)의 순으로 읽으면, 원인의 쪽(클라이언트 쪽 / 이동 / 서버 쪽 / 캐시)을 좁혀 갈 수 있습니다.
케이스 7-1 — 리다이렉트와 폼의 트러블
제 2〜3 장과 제 6 장의 범위입니다. 이동의 연쇄와 POST 의 재전송을 읽어냅니다.
Q1. 케이스: https://example.com/mypage 를 열면 브라우저가 「리다이렉트가 반복되었습니다」라는 오류를 표시합니다. curl -v https://example.com/mypage 로 관찰하니, 302 로 Location: /login 으로, /login 도 302 로 Location: /mypage 로 이동시키고 있었습니다. 일어나고 있는 일의 설명으로 올바른 것은 어느 것입니까.
Location 의 행선지를 따라가면 /mypage → /login → /mypage 의 순환이 보입니다. 전형적인 원인은, 로그인 판정의 조건(Cookie 의 유무 등)이 2 개의 페이지에서 어긋나 서로 상대에게 이동시키는 것입니다. 브라우저는 일정 횟수에서 끊고 이 오류를 냅니다. 503 이라면 Status 에 그렇게 나올 것이고, DNS 가 망가져 있으면 애초에 접속할 수 없습니다. curl 은 루프를 한 단계씩 정직하게 보여 준 쪽입니다.
Q2. 케이스: 주문 완료 페이지에서 브라우저를 새로 고침한 이용자로부터 「폼 재전송 확인이 나오고, 진행하니 주문이 이중이 되었다」는 보고가 있었습니다. 서버 쪽의 정석 대책은 어느 것입니까.
POST 에의 200 응답을 그대로 표시하면, 새로 고침 = POST 의 재실행이 됩니다(POST 는 멱등이 아니므로 이중 주문이 될 수 있음 — 제 2 장). POST/Redirect/GET 은 처리 후에 리다이렉트를 돌려주고 완료 페이지를 GET 으로 보여 주는 틀로, 새로 고침되어도 안전한 GET 이 반복될 뿐이 됩니다. no-store 는 재전송 문제를 해결하지 않고, 주문을 GET 으로 하는 것은 「안전한 메서드로 상태를 바꾸는」 반대 방향의 악수입니다.
Q3. 케이스: 이미지 파일의 리스폰스 헤더에 Cache-Control: max-age=604800 이 설정되어 있습니다. 이 캐시가 fresh 로 있을 수 있는 기간은 며칠입니까.
604800 ÷ 86400(하루의 초 수) = 7 일입니다. 제 5 장의 빈출 값 환산 그 자체입니다. 「1 주일 캐시해도 좋다」는 설정은 정적 파일에서 자주 보이므로, 604800 을 본 순간에 7 일이라고 읽을 수 있으면 설정 리뷰가 빨라집니다.
케이스 7-2 — 반영되지 않는다·깨진다·보이지 않는다
제 3〜6 장의 범위입니다. 캐시·권한·문자 인코딩을 구분합니다.
Q4. 케이스: CSS 를 수정해 서버에 반영했는데, 자신의 브라우저에서는 옛 디자인 그대로 표시됩니다. Network 탭을 보니, 그 CSS 행의 Size 열에 (disk cache) 라고 표시되어 있었습니다. 원인과 대처의 조합으로 가장 적절한 것은 어느 것입니까.
(disk cache) 는 「서버에 리퀘스트가 나가지 않았다」의 결정적인 표식입니다(제 5〜6 장). 서버를 아무리 고쳐도, fresh 인 동안 브라우저는 보러 오지 않습니다. 수중의 확인은 Disable cache 로 충분하지만, 이용자 전원의 캐시는 지울 수 없으므로, 영구 대책은 style.v2.css 처럼 URL 자체를 바꿔 「다른 리소스」로 가져오게 하는 설계가 정석입니다. 업로드 실패라면 Size 열에 통상의 전송량이 나와 있을 것입니다.
Q5. 케이스: 회원제 사이트에서, 로그인이 끝난 이용자로부터 「어제까지 볼 수 있던 자료 페이지가 오늘부터 볼 수 없다」는 보고가 있었습니다. Network 탭에서는 그 페이지로의 GET 이 403 을 돌려주고 있습니다. 이 관찰에서 말할 수 있는 것으로 가장 적절한 것은 어느 것입니까.
403 은 「누구인지는 알았지만, 권한이 없다」(제 3 장). 삭제라면 404, 서버 다운이라면 5xx 나 접속 오류가 될 것이고, 403 이 돌아오고 있는 시점에서 서버는 살아 있고 리퀘스트도 도착해 있습니다. 「어제까지 볼 수 있었다」와 합치면, 자료의 공개 범위나 회원 종별·권한 설정이 바뀌었을 가능성이 높다고 조사할 곳이 좁혀집니다. 상태 코드 하나로, 의심할 곳이 이만큼 달라집니다.
Q6. 케이스: 리뉴얼한 https://example.com 의 페이지에서 일본어가 「è±�å�」 같은 기호열로 깨져 있습니다. curl -I 로 확인하니 Content-Type: text/html; charset=ISO-8859-1 이 돌아오고 있었고, HTML 파일 자체는 UTF-8 로 저장되어 있었습니다. 적절한 대처는 어느 것입니까.
실체는 UTF-8, 라벨은 ISO-8859-1 — 제 4 장에서 읽은 「라벨과 내용물의 불일치」 그 자체입니다. 브라우저는 선언을 믿고 잘못된 문자 인코딩으로 바이트열을 해석하기 때문에 깨집니다. 고쳐야 할 것은 서버의 charset 선언이며, 이용자에게 매번 설정 변경을 강요하는 안이나 본문을 영어·이미지로 하는 안은 원인을 방치한 회피책조차 되지 못합니다. 헤더를 고치면 전원의 표시가 한 번에 고쳐집니다.
케이스 7-3 — 장애의 구분과 재시도의 판단
제 2〜3 장의 총마무리입니다. 5xx 의 구분과, 멱등성에 근거한 재시도 판단으로 강좌를 마무리합니다.
Q7. 케이스: 사이트 전체가 갑자기 오류가 되어, 어느 URL 이든 502 Bad Gateway 가 돌아옵니다. 구성은 「리버스 프록시 + 뒤의 애플리케이션 서버」의 2 단입니다. 가장 먼저 조사할 곳으로 가장 적절한 것은 어느 것입니까.
502 는 「중계역은 살아 있지만, 뒤로부터 정상적인 응답을 얻지 못했다」(제 3 장). 502 라는 HTTP 리스폰스가 돌아오고 있다는 것 자체가, 프록시까지는 도달할 수 있다는 증거입니다. 그래서 첫수는 애플리케이션 서버의 사활과 로그. 브라우저 설정이나 DNS 계약이 원인이라면, 애초에 502 라는 형태의 답장은 도착하지 않습니다. 3 자리 숫자가 2 단 구성의 어느 쪽인지까지 가르쳐 주고 있습니다.
Q8. 케이스: 재고 관리 시스템에서 2 개의 리퀘스트가 타임아웃되었습니다. (A) PUT /items/42(상품 42 의 정보를 이 내용으로 치환한다)와 (B) POST /orders(신규 발주를 작성한다)입니다. 기계적으로 곧바로 재전송해도 되는 것은 어느 쪽입니까.
강좌의 마무리는 제 2 장의 실무 감각입니다. 타임아웃은 「처리되었는데 답장만 사라졌을」 가능성을 포함합니다. PUT 은 같은 내용으로의 치환이므로, 설령 2 번 처리되어도 최종 상태는 같음 — 안심하고 재전송할 수 있습니다. POST 는 2 번 처리되면 발주가 2 건. 확인이나 중복 방지의 구조 없는 재전송은 사고입니다. 「갱신의 재시도는 멱등성을 확인하고 나서」— 이 한 문장을 가져가 주세요.
강좌를 마치며 — 왕복 서신 읽는 법을 지니고 다니기
수고하셨습니다. 이 강좌에서 암기한 항목은 사실 극히 적습니다. 대신 가져가 주었으면 하는 것은, 어떤 출력 앞에서도 통용되는 읽는 법의 틀입니다.
- 무엇을 부탁했는가 — 리퀘스트 행의 메서드와 경로. 그 부탁은 안전한가, 멱등한가
- 결과는 어땠는가 — 상태 코드를 백의 자리부터. 누구의 문제인지가 먼저 보인다
- 조건과 보충은 무엇인가 — Content-Type 은 내용물과 일치하는가. Cache-Control 은 무엇을 약속하고 있는가. Cookie 는 곁들여져 있는가
개발자 도구의 Network 탭도, curl -v 의 출력도, 내일부터 만날 어떤 HTTP 로그도, 이 3 가지로 반드시 읽기 시작할 수 있습니다. 압도되지 말고, 언제나의 3 가지부터 읽는다 — 그것이 이 강좌에서 몸에 익힌 힘입니다.