ultra_dev
개발 서버 DB Connection Pool 장애 대응기 본문
최근 로컬 개발 환경에서 PostgreSQL을 Docker로 띄우고 프로젝트를 개발하던 중, 뜻밖의 장애를 마주했다. 테스트 서비스 일부에서 갑자기 500 Internal Server Error를 뱉기 시작한 것이다.
🧪 증상
에러 로그를 확인해보니 다음과 같은 메시지가 있었다
FATAL: sorry, too many clients already
🔍 원인 분석
PostgreSQL의 기본 설정은 다음과 같았고
- max_connections = 100
이 프로젝트 환경에서는 아래와 같은 조건이 겹쳤다:
- PostgreSQL 컨테이너 1개에 여러 명의 개발자가 로컬에서 동시에 접속
- 각 WAS에서 커넥션 풀 기본값인 10개 커넥션을 선점
- 결과적으로 DB 커넥션이 100개를 초과 → DB 접근 불가 → 500 에러 발생
🔧 1차 해결 방법: max_connections 수정
우선 해당 리눅스 서버에 들어가서 Docker로 띄운 PostgreSQL의 설정을 수정했다(임시 방편으로 max_connections 증가)
sudo docker exec -it 도커컨테이너id vi /var/lib/postgresql/data/postgresql.conf
⚠️ 하지만 무작정 max_connection만 증가시키는 게 "진짜 해결책"일까?
PostgreSQL 커넥션은 메모리를 잡아먹는다
PostgreSQL은 각 커넥션마다 별도의 OS 프로세스를 fork하는 구조이다.
- 커넥션 1개당 수 MB ~ 수십 MB의 메모리 사용
- 커넥션 200개 → 최소 수백 MB ~ 기가바이트 단위 메모리 사용
- 이게 Docker 컨테이너 안에서 발생하면?
⇒ 컨테이너 메모리 폭증
⇒ 개발 서버 전체에 OOM 발생 가능
실제로 어떤 식으로 터질 수 있나?
- 개발 서버 메모리가 가득 차면 운영체제가 가장 메모리를 많이 쓰는 PostgreSQL 프로세스를 강제 종료(OOM Kill)하게 됨
- => 이 순간 DB 전체가 다운되면서 다른 개발자나 테스트 서비스도 연결 불가 상태로 전이됨
✅ 추가 해결책
1. WAS 커넥션 풀 설정 조정
- 각자 기본 설정으로 10~20개로 잡혀있는 커넥션 수를 줄였다.
- 로컬 개발 환경이기 때문에 3개면 충분할 것이라고 판단했다.
예시 (Spring Boot + HikariCP):
spring.datasource.hikari.maximum-pool-size=3
2. DB 인스턴스 분리 or 개발 환경 분산
- 모든 개발자가 하나의 DB 인스턴스를 공유하는 구조는 위험하고 테스트 간섭 등의 문제가 발생하기 쉽다.
- 따라서 로컬 Docker 환경으로 따로 분리 가능한 경우 분리해서 개발하기로 결정 했다.
🧠 배운 점
- PostgreSQL은 커넥션당 별도 프로세스를 fork하기 때문에 max_connections은 곧 메모리 사용량이다.
- pg_stat_activity를 통해 현재 커넥션 상태를 확인하는 법을 알게 됐다.
- 이 경험을 통해 커넥션 풀과 DB 인프라에 대한 이해를 높이는 좋은 계기가 되었다..!
'DB' 카테고리의 다른 글
DB 이것 저것 정리! (feat.SQL 실행순서..) (0) | 2024.01.19 |
---|---|
Docker 내부 PostgresSQL Dump (0) | 2023.12.08 |
SQL -3 (0) | 2023.01.13 |
SQL -2 (0) | 2023.01.13 |
SQL -1 (0) | 2023.01.13 |
Comments