Rust와 PostgreSQL로 확장 가능한 백엔드 서비스 구축하기

2 hours ago 1

Rust는 Go보다 백엔드 개발 생산성이 낮을 수 있지만, 강한 타입 시스템/컴파일러가 보장하는 정확성과 zero-cost abstraction 덕분에 10K+ LOC/약 100개 엔드포인트 규모에서 비즈니스 로직 버그를 줄이거나 높은 성능이 필요한 서비스에 적합함 HTTP 스택은 tokio → TLS(rustls/tokio-rustls) → hyper → axum으로 층을 나누고, 클라이언트는 reqwest, 공통 미들웨어 추상화는 tower, 관측성은 tracing을 사용하는 구성을 권장함 애플리케이션 코드는 HTTP/스케줄러/워커 → 서비스 → 저장소(repository) 의 3개 계층으로 분리하고, 각 계층은 바로 위/아래 계층하고만 통신하도록 제한해 프레임워크나 의존성 변경의 영향을 국소화함 모든 비즈니스 규칙과 캐시는 서비스 계층에 두고, 저장소는 PostgreSQL 쿼리만 담당하게 해 DB 접근과 비즈니스 로직을 분리함. 백그라운드 작업 큐와 Cron 작업도 PostgreSQL을 이용해 구현함 여러 복제본에서 Cron이 중복 실행되는 문제는 PostgreSQL advisory lock을 이용한 리더 선출로 해결하고, SPA/정적 파일까지 API 서버에서 함께 제공해 배포 구조와 CORS 처리를 단순화하는 등 전체적으로 복잡한 인프라보다 단순한 구조를 선호함 Rust HTTP 스택 가장 아래에는 비동기 런타임 tokio가 있으며 작업 스케줄링, 비동기 소켓 API, TCP 연결의 listen/accept를 담당함 TLS 계층은 두 부분으로 구성됨 rustls, boring, openssl 등이 TLS 프로토콜을 구현함 tokio-rustls, tokio-boring 같은 어댑터가 이를 tokio의 비동기 I/O와 연결함 TLS 구현은 rustls를 권장함 Rust 네이티브 라이브러리이며 실행 파일에 정적 링크 가능함 서버나 Docker 이미지의 OpenSSL 버전을 맞추는 배포 문제를 줄일 수 있음 크로스 컴파일도 상대적으로 단순해짐 tokio-rustls는 tokio::TcpStream을 암복호화를 처리하는 TlsStream으로 감싸며, 이렇게 만들어진 스트림을 hyper에 전달함 hyper, axum, tower hyper는 네트워크의 바이트 스트림을 Request와 Response 구조체로 변환하는 HTTP 스택의 핵심임 전송 방식과 분리되어 있으며 HTTP/1.x, HTTP/2.x 등에 맞는 ...

Read Entire Article