HTTP 파이프라이닝

섬네일|right|300px|비파이프라인 연결과 파이프라인 연결의 시간 다이어그램

**HTTP 파이프라이닝**(HTTP pipelining)은 **HTTP/1.1**의 기능으로, 여러 HTTP 요청을 해당 응답을 기다리지 않고 단일 TCP 연결을 통해 전송할 수 있도록 한다. HTTP/1.1은 서버가 HTTP 파이프라이닝을 지원하지 않더라도 파이프라인 처리되지 않았지만 유효한 응답으로 파이프라인 처리된 요청에 올바르게 응답하도록 요구한다. 이러한 요구사항에도 불구하고, 많은 레거시 HTTP/1.1 서버는 파이프라이닝을 올바르게 지원하지 않아 대부분의 HTTP 클라이언트가 HTTP 파이프라이닝을 사용하지 못하게 한다.

이 기술은 대부분의 최신 웹 브라우저에서 지원되는 HTTP/2를 통한 **[[다중화 (통신)|다중화]]**로 대체되었다.

HTTP/3에서는 TCP를 대체하는 QUIC을 통해 다중화가 이루어진다. 이는 일부 패킷이 손실되더라도 선두 차단이 없기 때문에 로딩 시간을 더욱 단축시킨다.

## 동기 및 한계
요청의 파이프라이닝은 HTML 페이지 로딩 시간을 극적으로 개선하며, 특히 위성 인터넷 연결과 같이 높은 레이턴시 연결에서 더욱 그렇다. HTTP 1.1의 한계는 여전히 적용되기 때문에 광대역 연결에서는 속도 향상이 덜 분명하다. 즉, 서버는 요청이 수신된 것과 동일한 순서로 응답을 보내야 하므로 전체 연결은 선입 선출 상태를 유지하며 HOL 차단이 발생할 수 있다.

HTTP/2와 SPDY의 비동기 작업은 이에 대한 해결책이다. 2017년까지 대부분의 브라우저는 다중화를 사용하는 HTTP/2를 기본적으로 지원했다.

멱등성이 없는 <code>POST</code>와 같은 요청은 파이프라인 처리되어서는 안 된다. `GET` 및 `HEAD`와 같은 읽기 요청은 항상 파이프라인 처리할 수 있다. `PUT` 및 `DELETE`와 같은 다른 멱등성 요청의 시퀀스는 시퀀스의 요청이 다른 요청의 효과에 의존하는지 여부에 따라 파이프라인 처리되거나 그렇지 않을 수 있다.

HTTP 파이프라이닝은 클라이언트와 서버 모두가 이를 지원해야 한다. HTTP/1.1을 준수하는 서버는 파이프라인 처리된 요청에 대해 유효한 응답을 생성해야 하지만, 실제로 요청을 동시에 처리하지는 않을 수 있다.

대부분의 파이프라이닝 문제는 HTTP 중간 노드(홉-바이-홉), 즉 프록시 서버에서 발생하며, 특히 투명 프록시 서버에서 발생한다(HTTP 체인의 중간 노드 중 하나라도 파이프라인 처리된 요청을 제대로 처리하지 못하면 모든 것이 제대로 작동하지 않는다).

HTTP 프록시 서버와 함께 파이프라이닝을 사용하는 것은 일반적으로 권장되지 않는다. HOL 차단 문제가 프록시 서버 응답 속도를 정말 느리게 할 수 있기 때문이다(서버 응답은 수신된 요청과 동일한 순서로 이루어져야 하므로).

**예시**: 클라이언트가 단일 연결을 통해 프록시에 4개의 파이프라인 처리된 GET 요청을 보내고 첫 번째 요청이 캐시에 없으면 프록시는 해당 요청을 대상 웹 서버로 전달해야 한다. 다음 세 요청이 캐시에 있다면 프록시는 웹 서버 응답을 기다렸다가 클라이언트에 보내고 나서야 세 개의 캐시된 응답도 보낼 수 있다.

클라이언트가 프록시에 4개의 연결을 열고 연결당 1개의 GET 요청을 보낸다면(파이프라이닝을 사용하지 않고) 프록시는 서버로부터 응답을 받기 전에 세 개의 캐시된 응답을 클라이언트에 병렬로 보낼 수 있어 전체 완료 시간을 줄일 수 있다(요청이 선두 차단 문제 없이 병렬로 처리되기 때문에). 동일한 이점은 HTTP/2 다중화 스트림에서도 존재한다.

## 구현 현황
파이프라이닝은 HTTP/1.1에 도입되었으며 HTTP/1.0에는 없었다.

브라우저, 프록시 서버 등에서 파이프라인 처리된 요청/응답을 사용할 때 제대로 작동하지 않는다는 불만이 항상 있었으며, 오랫동안(적어도 2011년까지) 소프트웨어 개발자, 엔지니어, 웹 전문가 등이 그들이 발견한 다양한 종류의 문제를 요약하고, 문제를 해결하고, 오픈 웹에서 파이프라이닝을 다루는 방법에 대한 조언을 제공하기 위해 노력했다.

### 웹 브라우저에서의 구현
모든 주요 브라우저 중 오페라만이 기본적으로 활성화된 완전히 작동하는 구현을 가지고 있었다. 다른 브라우저에서는 HTTP 파이프라이닝이 비활성화되거나 구현되지 않았다.
* 인터넷 익스플로러 8은 버그가 있는 프록시와 선두 차단에 대한 우려 때문에 파이프라인 요청을 지원하지 않는다.
* 인터넷 익스플로러 11은 파이프라이닝을 지원하지 않는다.
* 모질라 파이어폭스, 시몽키, 카미노와 같은 모질라 브라우저는 파이프라이닝을 지원했지만, 파이어폭스 54에서 제거되었다. 지원되었을 때는 오작동하는 서버와의 문제를 피하기 위해 파이프라이닝이 기본적으로 비활성화되어 있었다. 사용자가 파이프라이닝을 활성화한 경우, 모질라 브라우저는 주로 구형 마이크로소프트 IIS 서버에 대해 파이프라이닝을 끄는 휴리스틱을 사용했다. 제거는 결국 시몽키로 백포트되었다.
* Konqueror 2.0은 파이프라이닝을 지원하지만 기본적으로 비활성화되어 있다.
* 구글 크롬은 이전에 파이프라이닝을 지원했지만, 버그와 제대로 작동하지 않는 서버 문제로 인해 비활성화되었다.
* 페일 문은 파이프라이닝을 지원하며 기본적으로 활성화되어 있다.

### 웹 프록시 서버에서의 구현
대부분의 HTTP 프록시는 나가는 요청을 파이프라인 처리하지 않는다.

투명 HTTP 프록시를 포함한 일부 HTTP 프록시는 파이프라인 처리된 요청을 매우 잘못 관리할 수 있다(예: 파이프라인 처리된 응답의 순서를 뒤섞는 경우).

스퀴드 웹 프록시의 일부 버전은 최대 두 개의 나가는 요청을 파이프라인 처리한다. 이 기능은 기본적으로 비활성화되어 있으며 "대역폭 관리 및 접근 로깅 이유"로 인해 수동으로 활성화해야 한다. 스퀴드는 클라이언트의 여러 요청을 지원한다.

폴리포 프록시는 나가는 요청을 파이프라인 처리한다.

오픈 소스 애플리케이션 딜리버리 컨트롤러인 Tempesta FW도 백엔드 서버로 요청을 파이프라인 처리한다.

### 기타 구현
월드 와이드 웹 컨소시엄 (W3C)에서 만든 Libwww 라이브러리는 1997년 2월 18일 출시된 버전 5.1부터 파이프라이닝을 지원한다.

HTTP 파이프라이닝을 지원하는 다른 애플리케이션 개발 라이브러리는 다음과 같다.

*HTTP 파이프라이닝을 위한 클라이언트 지원을 제공하는 펄 모듈은 HTTP::Async와 LWPng (libwww-perl New Generation) 라이브러리이다.
* 닷넷 프레임워크.NET Framework 3.5는 `System.Net.HttpWebRequest` 모듈에서 HTTP 파이프라이닝을 지원한다.
* Qt 클래스 `QNetworkRequest`는 4.4에서 도입되었다.

현재 파이프라이닝을 활용하는 다른 애플리케이션은 다음과 같다.

*BUILD389 이후의 IceBreak 애플리케이션 서버
* FreeBSD의 phttpget (최소한의 파이프라인 HTTP 클라이언트)
* libcurl은 이전에 CURLMOPT_PIPELINING 옵션을 사용하여 파이프라이닝을 제한적으로 지원했지만, 이 지원은 버전 7.65.0에서 제거되었다.
* portsnap (FreeBSD ports tree 배포 시스템)
* APT는 파이프라이닝을 지원한다.
* 서브버전 (SVN)은 serf WebDAV 접근 모듈을 사용하여 HTTP 파이프라이닝을 선택적으로 지원한다 (기본 모듈인 neon은 파이프라이닝을 지원하지 않는다).
* 윈도우 서버 2003의 마이크로소프트 메시지 큐잉은 기본적으로 HTTP에서 파이프라이닝을 활용하며, HTTPS에서도 사용하도록 구성할 수 있다.
*IBM CICS 3.1은 클라이언트 내에서 HTTP 파이프라이닝을 지원한다.

HTTP 파이프라이닝을 지원하는 테스트 도구는 다음과 같다.

* httperf
* Nmap은 Nmap 스크립팅 엔진(NSE)으로 파이프라인 요청을 지원한다.

## 같이 보기
* HTTP 지속적 연결 상태
* 웹소켓
* SPDY

## 각주

## 외부 링크
*RFC 7230 
* mozilla.org의 HTTP/1.1 파이프라이닝 FAQ
* w3.org의 "HTTP/1.1, CSS1, 및 PNG의 네트워크 성능 효과"
* "페이지 로드 시간 최적화" 기사
* phttpget
* serf C 라이브러리

분류:HTTP