"Apache에서 NGINX로 마이그레이션해야 할 것 같아요."
NGINX로 웹서버를 마이그레이션해야 할 것 같다는 얘기가 나와, Apache와 NGINX, 그리고 HTTP 프로토콜에 대해 알아보려 한다.
HTTP 프로토콜 버전
HTTP/1
HTTP/1.0 (1996년, RFC 1945) → 최초의 표준화된 HTTP 버전
HTTP/1.1 (1997년, RFC 2068 → 1999년, RFC 2616 → 2014년, RFC 7230~7235) → 현재도 일부 사용 중
HTTP1/1.0
- 최초로 공식 표준화된 HTTP 프로토콜
- 클라이언트(브라우저)와 서버가 단순한 요청-응답 방식으로 동작
- 비연결성(Connectionless): 요청할 때마다 새로운 TCP 연결을 생성하고, 응답을 받으면 즉시 연결 종료
✅ 장점
- 구조가 단순하여 구현하기 쉬움
- 초기 웹 환경(정적 페이지 위주)에서는 충분히 동작
❌ 단점
- 매 요청마다 TCP 연결을 새로 생성해야 해서 속도가 느림
→ 연결 설정(TCP 3-way handshake) 비용이 커짐
- 다수의 리소스(이미지, CSS, JS 등)를 로딩할 때 매번 연결을 다시 맺어야 함
- 헤더 정보가 반복적으로 전송되며 불필요한 데이터 낭비
HTTP1/1.1
- Persistent Connection (Keep-Alive) 기본 지원 → 한 번 연결을 맺으면 여러 개의 요청을 처리 가능 (연결 재사용)
- 파이프라이닝(Pipelining) 지원 → 요청을 병렬적으로 처리하여 응답 속도 향상 (하지만 브라우저 지원 부족으로 거의 사용되지 않음)
- Chunked Transfer Encoding 지원 → 데이터 크기를 미리 알 수 없어도 전송 가능 (스트리밍에 유용)
- 캐시 제어(Cache-Control) 및 압축 전송(Content-Encoding: gzip) 지원 → 불필요한 요청을 줄이고, 데이터 전송을 최적화
✅ 장점
- 연결 유지(Persistent Connection) 덕분에 속도 개선
- 헤더 압축 및 캐싱 개선으로 불필요한 데이터 전송 감소
- Chunked Transfer 덕분에 대용량 데이터를 효율적으로 전송
❌ 단점
- 여전히 요청 단위로 응답을 받아야 하는 구조라서 병목 현상 발생 가능
(특히 여러 개의 요청이 있을 때, 앞 요청이 완료될 때까지 대기하는 문제)
- 파이프라이닝이 제대로 활용되지 못함 (브라우저에서 기본적으로 비활성화)
HTTP/2
HTTP/2 (2015년, RFC 7540) → 성능 개선
- 이진 프로토콜: HTTP/1.x와 달리 이진 형식으로 데이터를 전송, 파싱 속도 향상 및 오류 처리 유리.
- 헤더 압축: HPACK 기술로 헤더 압축, 중복 데이터 최소화, 네트워크 대역폭 절약.
- 멀티플렉싱: 단일 TCP 연결로 여러 요청과 응답을 동시에 처리, 속도 향상.
- 서버 푸시: 서버가 클라이언트가 요청하지 않은 리소스를 미리 전송, 웹 페이지 로딩 시간 단축.
- 스트림: 요청과 응답을 독립적인 스트림으로 처리, 우선순위 설정으로 효율적인 리소스 관리.
✅ 장점
- 성능 향상: 멀티플렉싱으로 여러 요청을 병렬 처리해 웹 페이지 로딩 시간 단축, 헤더 압축으로 대역폭 소비 줄임.
- 더 빠른 페이지 로딩: 서버 푸시 기능으로 필요한 리소스를 미리 전송, 페이지 로딩 속도 향상.
- 네트워크 효율성 증가: 하나의 TCP 연결로 여러 요청 처리, 연결 수 감소 및 지연 시간 줄어듦.
- 리소스 관리 최적화: 스트림 우선순위 설정으로 서버가 필요한 리소스를 우선 처리.
❌ 단점
- 복잡한 구현: HTTP/2는 이진 프로토콜과 멀티플렉싱을 사용해 구현이 복잡하고, 서버 푸시 기능은 클라이언트와 서버가 이를 지원해야 제대로 활용됨.
- TCP 연결 의존성: TCP 연결에 의존하므로, 패킷 손실이나 연결 끊김으로 인해 성능 저하가 발생할 수 있음.
- 중간 네트워크 장비의 처리 문제: 일부 방화벽이나 프록시가 HTTP/2를 지원하지 않아 성능 향상이 제한될 수 있음.
- 서버 푸시의 남용 문제: 서버 푸시를 잘못 사용하면 불필요한 리소스를 전송하여 대역폭 낭비 및 성능 저하를 초래할 수 있음.
HTTP/3
HTTP/3 (2022년, RFC 9114) → 최신 웹 표준
- QUIC 프로토콜 사용: UDP 기반의 QUIC 프로토콜을 사용, 더 빠르고 안정적인 연결 제공.
- 다중화: HTTP/2처럼 멀티플렉싱을 지원하며, QUIC은 빠른 연결 설정과 빠른 복구 기능 제공.
- 헤더 압축: HTTP/2보다 향상된 HPACK 방식의 헤더 압축으로 성능 최적화.
- 0-RTT 연결 설정: 이전에 연결된 서버와 재연결 시, 연결 지연 시간을 거의 없이 빠르게 데이터 전송.
- 멀티스트림: 여러 스트림을 독립적으로 처리하여 패킷 손실 시 다른 스트림에 영향을 미치지 않음.
- 전송 계층 보안: TLS 1.3을 기본으로 사용하여 보안 강화 및 효율적인 HTTPS 처리.
✅ 장점
- 더 빠른 연결 설정: 0-RTT 연결 설정 덕분에 지연 시간이 짧고 데이터 전송이 빠르며, 모바일 네트워크에서 성능 향상.
- 향상된 성능과 안정성: 멀티스트림으로 여러 요청을 처리하고, 패킷 손실이 다른 스트림에 영향을 미치지 않음.
- 네트워크 지연 감소: 연결 재사용으로 웹 페이지 로딩 속도 향상, 네트워크 지연 최소화.
- 모바일 및 고속 네트워크 환경에 유리: QUIC가 모바일과 고속 네트워크에서 뛰어난 성능 발휘.
- 향상된 보안: TLS 1.3 사용으로 암호화 및 중간자 공격(MITM) 방어, 보안 수준 향상.
❌ 단점
- UDP 사용에 따른 네트워크 장비 지원 문제: UDP를 사용하는 HTTP/3는 일부 네트워크 장비에서 제대로 처리되지 않을 수 있어 도입에 시간이 걸릴 수 있음.
- 서버 및 클라이언트 지원 한계: HTTP/3를 지원하지 않는 서버나 클라이언트에서 정상 동작하지 않으며, 업데이트가 필요.
- 구현 복잡성: QUIC 기반의 HTTP/3는 기존 프로토콜보다 구현이 복잡하고, 서버와 클라이언트가 QUIC을 지원해야 함.
tcp(HTTP/2) vs QUIC(HTTP/3) 무엇이 다른가?
| 특징 | TCP (HTTP/2) | QUIC (HTTP/3) |
|---|
| 전송 프로토콜 | TCP | UDP |
| 연결 설정 시간 | 상대적으로 긴 연결 설정 시간 | 빠른 연결 설정, 0-RTT 지원 |
| 헤드오브라인 블로킹 | 발생 가능 (하나의 패킷 손실이 전체 영향을 미침) | 스트림 단위로 처리되어 헤드오브라인 블로킹 해결 |
| 암호화 | 별도의 TLS 암호화 과정 필요 | QUIC에서 내장된 TLS로 즉시 암호화 |
| 모바일 성능 | 상대적으로 낮음 | 네트워크 변화에 강하고 연결 복원성 뛰어남 |
- 빠른 연결 설정
- 헤드오브라인 블로킹 해결
- 즉시 적용되는 암호화
- 모바일 환경에서 안정성 향상
본론
Apache -> NGINX 마이그레이션이 필요한가?
Apache에서 NGINX로 마이그레이션이 필요하다는 얘기는 들었지만, 그 이유는 듣지 못함. 그래서 프로덕트의 특징을 고려해서 한번 생각해봄.
클라이언트에서 이미지 리소스를 자주 요청함
- 여러 이미지를 동시에 요청할 때 헤드오브라인 블로킹이 해결되어 성능이 향상됨.
- 빠른 연결 설정 덕분에 자주 연결을 재설정하는 경우 성능 향상.
- UDP 기반으로 패킷 손실이나 네트워크 지연에 강해 안정적인 이미지 전송 가능.
- 모바일 환경에서의 성능이 뛰어나, 네트워크 상태가 불안정한 환경에서도 안정적인 이미지 로딩.
이미지 서버와 웹 서버를 분리하거나 NGINX로 마이그레이션하는 두 가지 선택지가 있다. HTTP/2에서 HTTP/3로의 마이그레이션을 고려할 수도 있으며, NGINX는 HTTP/3를 지원하여 빠른 연결 설정과 성능 개선을 제공할 수 있다. 어떤 방향으로 개선할지는 아직 미정이다.
단순히 웹 표준이라는 이유만으로 HTTP/2에서 HTTP/3로 마이그레이션할 이유가 있는가?"
HTTP/2에서 HTTP/3로 마이그레이션은 필수는 아님. HTTP/3는 여러 성능 개선과 안정성 향상을 제공하지만, 모든 상황에서 필요하지 않을 수 있음. 예를 들어, HTTP/3는 빠른 연결 설정, 헤드오브라인 블로킹 문제 해결, 모바일 네트워크에서 더 나은 성능 등을 제공하는데, 이런 장점들이 특정 상황에서만 유효함.
예를 들어, 모바일 사용자 비중이 크고, 네트워크 환경이 불안정하거나 지연이 큰 경우 HTTP/3의 성능 향상이 뚜렷하게 나타날 수 있음. 반면, 일반적인 웹사이트나 낮은 트래픽 환경에서는 HTTP/2로도 충분히 안정적이고 빠른 성능을 제공할 수 있음.
따라서, 서비스의 성격과 트래픽 상황을 고려해 성능 개선이 필요하다고 판단되면 HTTP/3로의 마이그레이션이 유리할 수 있음. 단, 기존 HTTP/2에서 큰 성능 문제나 개선이 필요하지 않다면 굳이 HTTP/3로 전환할 필요는 없음.
QUIC는 UDP 기반인데, 어떻게 TCP처럼 손상된 패킷에 대해 재전송을 지원하는가?
QUIC는 UDP 기반이지만, TCP처럼 패킷 손실에 대해 재전송 지원.
- 패킷 손실 감지: 패킷 순서 추적하고 손실된 패킷 감지.
- 패킷 재전송: 손실된 패킷 지연 없이 재전송.
- 스트림 단위 재전송: 손실된 스트림만 재전송, 다른 스트림은 영향 안 받음.
- 패킷 번호 및 ACK: 각 패킷 고유 번호 부여하고, 손실된 패킷에 대해 ACK로 재전송 요청.
QUIC는 이렇게 UDP의 신뢰성 문제 해결하고, TCP처럼 패킷 재전송 지원.