콘텐츠로 이동

아키텍처

Pingclair는 Cargo workspace입니다. 실제로 동작하는 서버는 pingclair 바이너리이며 다음 crate를 링크합니다.

Crate 역할
pingclair 명령줄 진입점. 인수 파싱, 로깅, 기동, 서비스 래퍼.
pingclair-config 설정 컴파일러. Pingclairfile을 어휘 분석하고 파싱하며 의미를 검사합니다.
pingclair-proxy Pingora 기반 HTTP/1.1·HTTP/2 프록시, quiche 기반 HTTP/3 리스너, 부하 분산, 공용 요청 정책 계층.
pingclair-static 정적 파일 제공. 파일 읽기, MIME 타입, 범위 요청, 스트리밍.
pingclair-tls 인증서 관리. 수동 인증서, 상주하는 내부 인증 기관, ACME 자동 발급.
pingclair-api 상태 확인과 설정 다시 로드를 위한 Admin API.
pingclair-core 위 crate들이 공유하는 데이터 구조와 서버 수명 주기.
client
|
| TLS with ALPN, or QUIC
v
listener HTTP/1.1 and HTTP/2 on TCP, HTTP/3 on UDP
|
v
transport adapter Pingora ProxyHttp for TCP, tokio-quiche for QUIC
|
v
policy layer routing, matchers, headers, rate limits, access log
|
v
handler file server | reverse proxy | FastCGI | static response
|
v
upstream or disk

두 전송 방식은 결국 같은 정책 계층으로 합류합니다. 그래서 라우팅, 헤더 처리, 속도 제한, 접근 로그의 동작이 HTTP/1.1, HTTP/2, HTTP/3에서 같습니다. 차이는 프로토콜상 꼭 필요한 지점에서만 납니다.

  • 본문은 스트리밍됩니다. 요청과 응답 본문은 상한이 있는 청크로 프록시를 지납니다. 압축, 미들웨어, 프록시는 본문 전체를 버퍼링하지 않으므로 큰 업로드나 느린 수신자가 본문 크기에 비례하는 메모리를 쓰지 않습니다.
  • 업스트림 연결은 재사용됩니다. 백엔드와의 keepalive 연결을 재사용합니다. 호스트 이름 업스트림은 dns_refresh로 설정한 간격마다 다시 해석되므로, 새 주소로 재시작한 컨테이너에도 사람이 개입하지 않고 따라갑니다.
  • 런타임 상태는 요청 중에 불변입니다. 요청은 공개된 스냅샷을 읽습니다. 다시 로드는 사용 중인 것을 수정하는 대신 새 스냅샷을 공개합니다.

일부 동작은 프로토콜에 따라 의도적으로 다릅니다. 나중에 발견하는 대신 여기에 적어 둡니다.

영역 동작
Trailers 요청에서 선언한 trailer는 전달되지 않습니다. 응답 확정 전에는 501을 반환하고, 확정된 HTTP/3 스트림은 reset하며, 업스트림이 응답 trailer를 알리면 502를 반환합니다.
CONNECT HTTP/3에서 터널 지원이 구현될 때까지 CONNECT와 extended CONNECT501을 반환합니다.
FastCGI php_fastcgi는 HTTP/1.1과 HTTP/2에서 동작합니다. FastCGI가 필요한 라우트는 그 경로가 자체 FastCGI 클라이언트를 가질 때까지 HTTP/3에서 501을 반환합니다.

WebSocket 업그레이드는 부하가 걸리면 간헐적으로 실패합니다. 바쁜 머신에서 약 10-15%가 실패합니다. 원인은 Pingclair 자체의 업그레이드 처리 가 아니라 업스트림 pingora-proxy crate의 경쟁 상태입니다. 유휴 상태의 개발 머신에서는 재현되지 않으므로 여기에 적어 둡니다. 업스트림 이슈: cloudflare/pingora#946.