Rust 백엔드를 오래 버티게 만드는 계층 설계와 PostgreSQL 활용법

Rust로 백엔드 서비스를 만들 때 어려운 지점은 언어 문법보다 여러 크레이트와 애플리케이션 코드를 어디서 나눌지 정하는 일이에요. Rust와 PostgreSQL로 중간 규모 서비스를 운영해 온 개발자가 HTTP 스택, 코드 계층, 작업 큐와 Cron을 한 구조 안에서 설명했어요. 1
핵심 요약
| 구분 | 핵심 | 왜 볼 만한가요 |
| HTTP 스택 | Tokio 위에 rustls, hyper, axum을 층별로 올려요 | 각 크레이트의 역할과 교체 범위를 구분할 수 있어요 |
| 코드 구조 | 진입점, 서비스, 저장소의 3개 계층으로 나눠요 | HTTP 프레임워크와 비즈니스 규칙, SQL이 서로 엉키는 일을 줄여요 |
| PostgreSQL 활용 | 작업 큐와 Cron 리더 선출까지 PostgreSQL로 처리해요 | 별도 인프라를 늘리지 않고 중복 실행을 막는 방법을 볼 수 있어요 |
| 운영 | 캐시는 서비스 계층에 두고 tracing으로 로그와 추적을 모아요 | 비즈니스 규칙과 관측 정보를 코드 구조에 맞게 배치할 수 있어요 |
1. Rust 백엔드는 크레이트보다 경계를 먼저 정해요
원문 저자는 Rust가 Go보다 백엔드 개발 속도에서 불리할 수 있다고 봐요. 대신 강한 타입 시스템과 컴파일러 검사가 비즈니스 로직의 실수를 줄여 주고, 추가 런타임 비용을 피하는 추상화가 성능이 필요한 서비스에 잘 맞는다고 설명해요. 이 평가는 모든 프로젝트에 적용되는 벤치마크가 아니라, 코드가 1만 줄을 넘고 엔드포인트가 약 100개인 서비스를 운영한 경험에서 나온 판단이에요. 2
HTTP 서버는 하나의 프레임워크로 끝나지 않아요. Tokio가 비동기 작업과 소켓을 맡고, rustls와 tokio-rustls가 TLS 연결을 처리해요. Hyper는 네트워크 바이트를 요청과 응답 구조로 바꿔요. Axum은 그 위에 라우팅, 미들웨어, 오류 처리와 extractor를 제공해요. 클라이언트 요청에는 reqwest를 쓰고, 공통 서비스 인터페이스에는 tower를 배치해요. 구조화된 로그와 추적은 tracing이 맡아요. 2
애플리케이션 코드는 HTTP·스케줄러·워커 같은 진입점, 서비스, 저장소 순서로 나눠요. 진입점은 입력을 서비스가 이해하는 형태로 바꾸고 결과를 다시 응답으로 변환해요. 서비스 계층에는 인증, 입력 검증, 비즈니스 불변조건과 캐시 정책을 둬요. 저장소는 PostgreSQL 쿼리와 데이터베이스 오류 변환에 집중해요. HTTP 계층이 저장소를 바로 호출하지 못하게 제한하면 프레임워크를 바꿀 때 비즈니스 규칙까지 고칠 가능성이 작아져요.
저장소 계층은 여러 데이터베이스를 자유롭게 바꾸기 위한 추상화로 쓰지 않아요. 같은 테이블을 다루는 쿼리를 한곳에 모아 재사용하고, 컬럼 변경 범위를 좁히는 역할에 가깝게 둬요. SQLx의 Executor를 감싼 공통 trait을 사용하면 같은 저장소 메서드를 연결 풀과 트랜잭션 연결에서 함께 쓸 수 있어요. 고유 제약 조건 위반 같은 데이터베이스 오류를 도메인 오류로 바꾸는 지점도 명확해져요.
PostgreSQL은 데이터 저장 외의 운영 문제에도 쓰여요. 백그라운드 작업 큐를 PostgreSQL로 구성하고, 여러 서버 복제본 가운데 Cron을 실행할 한 대를 advisory lock으로 골라요. 락을 얻은 연결을 유지하는 서버만 스케줄러를 실행하므로 같은 작업이 복제본 수만큼 반복되는 일을 막을 수 있어요. 별도의 메시지 브로커나 리더 선출 시스템이 꼭 필요한 규모인지 판단하기 전까지 운영 요소를 줄이는 선택이에요. 2
캐시는 저장소가 아니라 서비스 계층에 둬요. 어떤 데이터를 얼마나 오래 저장해도 되는지는 비즈니스 규칙에 가깝기 때문이에요. SPA와 정적 파일도 rust-embed로 API 서버에 포함할 수 있어요. 웹과 API를 같은 도메인에서 제공하면 배포 단위가 줄고 CORS 설정도 단순해져요. 다만 정적 자산 트래픽, 캐시 전략, 글로벌 전송 요구가 커지면 CDN을 분리하는 편이 나을 수 있어요.
왜 중요한가요
Rust 백엔드 도입을 검토할 때 언어의 성능만 비교하면 실제 유지보수 비용을 놓치기 쉬워요. 이 사례는 각 라이브러리의 책임, 비즈니스 규칙의 위치, SQL과 캐시의 경계를 먼저 정해요. 팀은 프레임워크 교체나 데이터 모델 변경이 생겼을 때 어느 코드까지 영향을 받는지 예측하기 쉬워져요. 2
PostgreSQL로 큐와 리더 선출까지 처리하는 방식은 모든 서비스의 정답은 아니에요. 작업량과 장애 격리 요구가 커지면 전용 큐나 별도 스케줄러가 필요할 수 있어요. 초기와 중간 규모에서는 이미 운영 중인 데이터베이스를 활용해 구성 요소를 줄일 수 있어요. 먼저 단순한 구조로 시작하고 부하와 장애 요구가 바뀔 때 분리할 기준을 세우는 접근이에요.
참고 자료
- Rust와 PostgreSQL로 확장 가능한 백엔드 서비스 구축하기 — GeekNews
- Building scalable backend services with Rust and PostgreSQL — Sylvain Kerkour
'IT & AI' 카테고리의 다른 글
| Cursor는 왜 채용 공고보다 후보자 50명부터 찾을까 (0) | 2026.08.17 |
|---|---|
| AI가 코딩을 쉽게 해도 프로덕트 매니저가 필요한 이유 (0) | 2026.08.17 |
| AI 코딩 시대, 플랫폼 엔지니어링이 비용을 줄이는 이유 (0) | 2026.08.17 |
| Airbnb는 왜 로그인 방법을 서버가 고르게 했을까요 (0) | 2026.08.17 |
| Git 커밋 기록을 표처럼 고치는 git-knife, 날짜와 작성자도 한 번에 바꿔요 (0) | 2026.08.17 |