🧩 BE

DB 및 서버 가용성 최적화

Assigned To
Date
2026/02/06
Status
Done
Type
Backlog
Server
Table of contents

DB 최적화

기존 로그 파악
ubuntu@ip-172-31-0-26:~$ wc -l ~/backend/logs/backend.log.jsonl 2730 /home/ubuntu/backend/logs/backend.log.jsonl
Shell
복사
hey로 동시에 10명이 접속, 총 100번의 요청을 보내서 부하 Test
hey -n 100 -c 10 "https://api.reportkit-donga.com/api/v2/articles/report?start_date=2026-02-02&end_date=2026-02-02&platform=naver"
Python
복사
Summary: Total: 1.9994 secs Slowest: 0.5198 secs Fastest: 0.0538 secs Average: 0.1865 secs Requests/sec: 50.0162 Total data: 145300 bytes Size/request: 1453 bytes Response time histogram: 0.054 [1 |0.100 [8] |■■■■■■■■■■■ 0.147 [21] |■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ 0.194 [29] |■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ 0.240 [25] |■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ 0.287 [6] |■■■■■■■■ 0.333 [5] |■■■■■■■ 0.380 [4] |■■■■■■ 0.427 [0] | 0.473 [0] | 0.520 [1] |■ Latency distribution: 10%% in 0.1006 secs 25%% in 0.1418 secs 50%% in 0.1781 secs 75%% in 0.2240 secs 90%% in 0.2881 secs 95%% in 0.3383 secs 99%% in 0.5198 secs Details (average, fastest, slowest): DNS+dialup: 0.0068 secs, 0.0000 secs, 0.0735 secs DNS-lookup: 0.0047 secs, 0.0000 secs, 0.0469 secs req write: 0.0000 secs, 0.0000 secs, 0.0003 secs resp wait: 0.1790 secs, 0.0536 secs, 0.4445 secs resp read: 0.0005 secs, 0.0000 secs, 0.0053 secs Status code distribution: [200] 100 responses
Shell
복사
ubuntu@ip-172-31-0-26:~$ wc -l ~/backend/logs/backend.log.jsonl 2780 /home/ubuntu/backend/logs/backend.log.jsonl
Shell
복사
전체 로그 50줄 씩 증가
→ 로그 라인 개수 50% 감소

Lifespan 이벤트 추가

FastAPI에서 lifespan을 활용하면, 시작과 종료 로직을 정의하는 것이 가능.
backend/app/main.py
contextlib.asynccontextmanager로 lifespan 함수 생성
shutdown 시 close_db() 호출 (session.py에 이미 존재하지만 미사용)
app = FastAPI(..., lifespan=lifespan)
→ 서버 오류 시 DB connection 호출 비용 절감

Connection Pool 타임아웃 설정 추가

backend/app/core/config.py
DATABASE_POOL_TIMEOUT: int = Field(default=30) 추가
DATABASE_POOL_RECYCLE: int = Field(default=1800) 추가
backend/app/db/session.py
create_async_engine에 pool_timeout, pool_recyle 파라미터 추가
→ DB 연결 끊기는 문제 해결

내부 코드 개선

에러 핸들링 개선

CustomException 클래스 추가
GlobalExceptionHandler 추가
라우터 별 Exception 처리 로직 추가
retry 데코레이터 추가해서 시스템 안정성 확보
→ Exception 관련 공통로직 개선으로 LoC 약 130줄 개선, 예외처리 중앙화로 유지보수성 up

파일 import 구조 갈아엎기

common.common.~~` 되어야하는데,
죄다 common.~~ 뭐 이렇게 되어있어서 import가 전혀 되지 않고 있음. 해당 부분 github 디렉토리에서 살펴보고 개선하기
pyproject.toml 파일을 보면, 다음과 같이 명시되어 있음.
[tool.setuptools.packages.find] where = ["."] include = ["common", "common*"]
TOML
복사
commoncommon* (common 하위 폴더)를 모두 하나의 패키지로 인식해서 common/common/ 이더라도 런타임 환경에서는 문제없이 실행시킴. but, IDE에서는 루트폴더 기준으로 인식 하기 때문에, source directory가 아니면 인식 못하는 오류 발생.
common, analytics, persistence, external을 source root로 수정해주면 해결.
중복 디렉토리가 싫다면 굳이 갈아엎어도 되고, 어차피 로컬에서 돌릴때 인식 못하는 문제라, 괜히 docker 경로까지 건드리기 귀찮음.. 냅두자

빌드 속도 최적화

현재 빌드 속도 대략 2분 안팎
python 빌드 방식 → python은 컴파일 안하는데 빌드 왜함? → pyproject.toml 활용하여 내부 환경설정파일을 통해 uv sync 이런걸로 배포환경과 동일하게 맞춰서 코드 실행
빌드 프로세스 정리
1.
checkout code
2.
AWS credentials (OICD 인증)
3.
ECR 로그인
4.
docker build → image화
5.
ecr에 image push
6.
lambda update
7.
무중단 배포를 위한 lambda complete wait
8.
deploy summary 작성, 알림
setuptools.build_metahatching으로 배포 방식 변경

Why?

No build dependencies
Optimized by default
Simplicity
Cross-platform (다양한 확장성 제공)

개선 프로세스

1.
각 sub-package의 pyproject.toml 수정
2.
root pyproject.toml 수정
3.
setup.py 파일 4개 삭제
4.
uv sync 실행
5.
패키지 인식 검증

결과

빌드 속도 비교 (common 패키지 1개 기준)
빌드 시간
setuptools: 1.098s
hatchling: 0.630s
빌드 프로세스
setuptools: egg_info → sdist → build_py → install_lib → wheel (5단계)
hatchling: sdist → wheel (2단계)
→ 4개 패키지의 빌드 속도 약 40% 개선
→ 기존에 100% 2분 이상으로 나오던 배포 속도 1분대로 감소