트레일러
고친 사람 github-actions[bot]
트레일러는 내용을 다 보내고 나서야 알 수 있는 정보를 그 뒤에 덧붙여 알립니다. 오는 길에 내용이 깨지지 않았는지 확인할 검사값이 대표적입니다. 받는 쪽은 내용을 끝까지 받은 다음 이 부분을 읽고, 앞서 받은 것을 쓸지 버릴지 정합니다.
쉽고 빠른 이해
무슨 일을 하는 물건인가 — 주고받는 데이터 한 덩이의 맨 뒤에 붙는 토막입니다. 짐을 상자에 다 담고 나서 뚜껑 밑에 얹는 「모두 스물일곱 개」 같은 쪽지가 트레일러에 해당합니다.
왜 이렇게 하나 — 내용 전체를 봐야 정해지는 값이 있습니다. 그런 값을 앞에 두려면 내용을 다 만들고 계산까지 끝낸 다음에야 보내기 시작할 수 있습니다. 뒤에 두면 보내면서 계산해 마지막에 얹으면 됩니다.
어떻게 도나
- 보내는 쪽이 안내를 먼저 보내고 내용을 이어 보냅니다
- 내용을 흘려보내면서 검사값을 함께 계산합니다
- 내용이 끝나면 계산 결과를 트레일러로 덧붙입니다
언제 쓰나 — 길이를 미리 모르고 흘려보내는 응답에 씁니다. 받는 쪽이 반드시 봐야 하는 값이면 안 씁니다.
대가 — 받는 쪽은 내용을 끝까지 받기 전에는 트레일러를 못 봅니다. 미리 처리해 둔 것을 되돌려야 할 수 있습니다. 중간 장비가 떼어 버려서 아예 안 오기도 합니다.
상세
트레일러가 데이터 한 덩이의 어디에 붙는지, 앞에 붙는 안내와 무엇이 다른지를 봅니다. 이어서 왜 뒤에 두어야만 하는 값이 생기는지를 봅니다. 가지고 보이는 것은 둘입니다. 이더넷 프레임 맨 뒤의 4바이트와 HTTP(HyperText Transfer Protocol, 하이퍼텍스트 전송 프로토콜) 응답 뒤에 붙는 필드 몇 줄입니다.
짐을 상자에 담아 부치는 일을 떠올리면 쉽습니다. 몇 개를 넣었는지는 다 담고 나서야 적을 수 있습니다. 미리 적어 두면 하나 더 넣을 때마다 쪽지를 고쳐야 합니다. 그래서 그 쪽지는 상자를 봉하기 직전에 맨 위에 얹습니다.
헤더와 트레일러
데이터는 한 덩이씩 끊어 보냅니다. 이 한 덩이를 데이터 단위라고 부릅니다.
데이터 단위의 앞에 붙는 안내가 헤더입니다. 실어 나르려던 내용이 페이로드입니다. 맨 뒤에 붙는 토막이 트레일러입니다.
block-beta columns 3 h["헤더 · 미리 아는 안내"] p["페이로드 · 나르려던 내용"] t["트레일러 · 나중에 아는 값"]
그림의 세 토막을 가르는 잣대는 하나입니다. 그 값을 언제 알 수 있느냐입니다. 목적지나 형식처럼 보내기 전부터 정해진 것은 앞으로 가고, 내용을 다 봐야 정해지는 것은 뒤로 갑니다.
무엇을 뒤에 담을지는 프로토콜이 정합니다. 프로토콜은 두 쪽이 데이터를 주고받는 약속입니다. 트레일러가 아예 없는 약속도 많습니다. 뒤에 둘 값이 없으면 안 둡니다.
값이 뒤로 가는 조건
값을 앞에 두려면 보내기 전에 그 값이 정해져 있어야 합니다. 내용 전체로 계산하는 값은 이 조건을 못 맞춥니다. 내용을 끝까지 만들고 계산을 마친 다음에야 첫 바이트를 내보낼 수 있기 때문입니다.
이것이 걸림돌이 되는 곳이 스트리밍입니다. 스트리밍은 내용이 만들어지는 대로 조금씩 흘려보내는 방식입니다. 데이터베이스에서 백만 건을 읽어 내려보내는 응답처럼, 시작할 때는 결과가 얼마나 될지도 모르는 경우입니다.
sequenceDiagram
participant 보내는쪽
participant 받는쪽
보내는쪽->>받는쪽: 헤더 · 미리 아는 안내
보내는쪽->>받는쪽: 내용 조각
보내는쪽->>받는쪽: 내용 조각
Note over 보내는쪽: 흘려보내며 검사값을 계산한다
보내는쪽->>받는쪽: 트레일러 · 계산이 끝난 값
그림에서 보내는 쪽은 조각을 내려보내는 동안 계산을 함께 합니다. 마지막 조각을 보내고 나면 계산도 끝나 있으므로 그 결과를 바로 뒤에 얹습니다. 값 하나 때문에 시작을 미룰 필요가 없어집니다.
프레임 끝의 검사값
가장 흔한 트레일러는 깨짐을 잡는 검사값입니다. 이것은 링크 계층에서 볼 수 있습니다. 링크 계층은 같은 선에 붙은 장비끼리 데이터를 주고받는 계층입니다. 이 계층이 다루는 데이터 단위를 프레임이라고 부릅니다.
이더넷은 프레임 맨 뒤 4바이트를 검사값으로 씁니다. 이 값을 FCS(Frame Check Sequence, 프레임 검사 열)라고 부릅니다. 순환 중복 검사(Cyclic Redundancy Check)라는 계산법으로 구합니다. 나눗셈의 나머지를 구하는 방식이라 내용이 한 비트만 뒤집혀도 결과가 달라집니다.
받는 쪽은 받은 프레임으로 같은 계산을 다시 해 봅니다. 결과가 뒤에 실려 온 값과 다르면 오는 길에 내용이 상한 것이므로 그 프레임을 버립니다. 어디가 어떻게 틀렸는지까지는 이 값으로 알 수 없어서 고쳐 쓰지 않고 버립니다.
이렇게 깨짐을 잡으려고 붙이는 값을 두루 체크섬이라고 부릅니다. 체크섬을 헤더에 두는 프로토콜도 있습니다. 그때 계산에 넣는 것은 헤더에 적힌 값들뿐입니다. 내용까지 넣어 계산하려면 내용이 다 지나간 뒤여야 하므로 그런 값은 뒤로 갑니다.
HTTP 의 트레일러 필드
HTTP 에도 트레일러가 있습니다. HTTP 에서는 실어 나르려던 내용을 본문이라고 부릅니다. 뒤에 붙는 것은 바이트 몇 개가 아니라 이름과 값을 짝지은 필드 몇 줄입니다.
본문 앞에 놓인 필드를 헤더 필드, 본문 뒤에 놓인 필드를 트레일러 필드라고 부릅니다. 가르는 잣대는 앞서 본 것과 같습니다. 미리 아는 값은 앞에 놓습니다. 본문을 다 봐야 아는 값은 뒤에 놓습니다.
트레일러 필드는 본문 길이를 미리 모르는 응답에서 씁니다. 본문을 조각으로 끊어 보내는 청크 전송 인코딩이 그런 응답입니다. 마지막 조각 뒤에 필드를 몇 줄 더 붙입니다. 그러고 나서 메시지를 끝냅니다.
아래는 그런 응답 한 벌을 순서대로 늘어놓은 것입니다.
헤더 필드 미리 아는 것 — 형식 · 조각으로 끊어 보낸다는 표시
빈 줄
본문 조각 ①
본문 조각 ②
본문 끝 표시
트레일러 필드 나중에 아는 것 — 본문의 검사값 · 처리 결과
방금 본 순서에서 눈여겨볼 곳은 맨 아래 한 줄입니다. 본문이 끝났다는 표시가 먼저 오고, 그다음에 필드가 더 옵니다. 보내는 쪽은 어떤 이름이 뒤에 올지를 Trailer 라는 헤더 필드로 미리 알려 줄 수 있습니다. 받는 쪽이 그 필드를 기다릴지 말지 정하게 하려는 것입니다.
gRPC가 이 대목을 적극적으로 씁니다. RPC 는 Remote Procedure Call(원격 프로시저 호출)입니다. gRPC 는 다른 기계에 있는 함수를 부르듯 요청과 응답을 주고받는 호출 방식입니다.
gRPC 는 호출이 성공했는지를 본문 뒤에 싣습니다. 서버가 메시지를 여러 개 흘려보내다 중간에 실패할 수 있기 때문입니다. 호출의 결과는 마지막에야 정해집니다.
도착 보장 없음
트레일러는 도착이 보장되지 않는 정보입니다. 백엔드 코드에서 이 값을 쓰려 할 때 걸리는 것이 세 가지입니다.
| 걸리는 것 | 무슨 일이 생기나 |
|---|---|
| 늦게 온다 | 본문을 끝까지 받아야 읽을 수 있습니다. 앞의 내용을 미리 처리했다면 되돌려야 합니다 |
| 떼여 나간다 | 중간의 프록시가 조각을 다시 이어 붙이면서 뒤의 필드를 버리기도 합니다 |
| 안 보인다 | 읽는 쪽 라이브러리가 트레일러를 꺼내 주지 않으면 코드에서 손댈 방법이 없습니다 |
표의 세 번째 줄이 브라우저에서 걸립니다. 브라우저의 [[fetch]] 로는 응답의 트레일러를 읽을 수 없습니다. 웹 화면에서 gRPC 를 쓰려면 앞에 gRPC-Web 중계를 하나 두는 까닭이 이것입니다. 이 중계가 뒤에 오는 트레일러를 브라우저가 읽을 수 있는 앞쪽 정보로 옮겨 줍니다.
그래서 트레일러에는 없어도 일이 돌아가는 정보를 담는 쪽이 안전합니다. 받는 쪽이 반드시 봐야 하는 값이라면 앞으로 옮기거나, 보내기 전에 미리 계산해 두는 편을 고릅니다.
관련 항목
트레일러와 나란히 데이터 단위를 이루는 구성 요소
헤더 · 페이로드 · 헤더 필드 · 트레일러 필드 · 시작줄 · 프리앰블 · 제어 데이터 · 메타데이터
트레일러가 뒤에 붙는 데이터 단위
프레임 · 패킷 · 세그먼트 · 데이터그램 · 메시지 · PDU
트레일러에 실리는 검사값과 그 계산법
체크섬 · 순환 중복 검사 · FCS · 해시 · 패리티 비트 · 무결성 · 전자 서명
트레일러를 뒤에 두도록 정한 프로토콜과 전송 방식
HTTP · HTTP/2 · gRPC · 이더넷 · 청크 전송 인코딩 · 스트리밍
트레일러를 싸고 벗기는 처리 단계
트레일러를 떼거나 다시 붙이는 중간 장비
트레일러가 속하는 상위 분류
다른 이름: trailer