백엔드와 DB 통신 : TCP로 통신
--> 매번 커넥션을 열고 닫는 시간적 비용 발생
--> 서비스 성능에 좋지 않다.
--> DBCP 등장
API 요청 들어오기 전 미리 DB connection들을 만들어둠(connection pool)
--> DBCP : DataBase Connection Pool
connection 재사용 -> 열고 닫는 시간 절약
DBCP 설정 방법
--> DB connection은 백엔드서버와 DB사이의 연결을 의미하기에 백엔드서버와 DB 서버 각각에서의 설정 방법을 잘 알고 있어야 한다.
DB 서버 설정
--> max_connections : client와 맺을 수 있는 최대 connection 수
--> wait_timeout : connection이 inactive할 때 다시 요청이 오기 까지 얼마의 시간을 기다린 뒤에 close할 것인지 결정 (비정상적 connection 종료, 다쓰고 반환이 안됨, 네트워크 단절 등 비정상적 상태일때 적절한 시점에서 해결 필요)
---> ex) 시간 내 도착하면 초기화 함 : 60초 설정 -> 58초에 도착 -> 0으로 초기화
DBCP 설정
--> minimumIdle : pool에서 유지하는 최소한의 idle connection 수
--> maximumPoolSize : pool이 가질 수 있는 최대 connection 수(idle + active 커넥션)
--> 만약 idle connection 수가 minimumIdle보다 작고, 전체 connection 수도 maximumPoolSize보다 작다면 신속하게 추가로 connection을 만든다.
--> HikariCP 에선 minumumPoolSize와 maximumPoolSize와 동일(권장, 기본값 설정)
----> pool size 고정
-->maxLifetime : pool에서 connection의 최대 수명
--> maxLifetime을 넘기면 idle일 경우 pool에서 바로 제거, active인 경우 pool로 반환된 후 제거(pool로 반환이 안되면 maxLifetime 동작 안함 -> 다쓴 connection은 pool로 반환 잘 해줘야 함)
--> DBCP 사이즈를 고정했다면, 제거하고 다시 생성
--> DB connection time limit(DB-wait time) 보다 몇 초 짧게 설정해야 함
--> connectionTimeout : pool에서 connection을 받기 위한 대기 시간(요청이 많을 때 계속 connection을 기다리지 않고 끊어줌)
적절한 connection 수를 찾기 위한 과정
(1) 모니터링 환경 구축(서버 리소스, 서버 스레드 수, DBCP 등)
(2) 백엔드 시스템 부하 테스트(nGrinder 등 툴 이용) -> 요청을 점차 늘려가며 테스트
(3) request per second : 단위 초당 처리량 / avg response time : 평균적 응답 시간 확인
(4) 백엔드 서버 DB 서버의 CPU, MEM 등 리소스 사용률 확인 -> 높을 경우 2대의 서버로는 버티지 못하다 판단하고 서버 추가 => DB 서버의 리소스 사용률이 높을 경우 secondary, 캐시, 샤딩 등 활용
(5) thread per request 모델(요청마다 쓰레드) 이라면 active thread 수 확인(널널하다면 다른 이유를 생각할 필요가 있음)
(5-1) DBCP의 active connection 수 확인 -> 다 사용중이라면 사이즈 증가
--> 사용할 백엔드 서버 수를 고려하여 DBCP의 max pool size 결정(예비 서버 고려 등)
실제 서버에서 테스트를 하면 잘못하다가는 실제 사용자에게도 영향 -> 트래픽이 최대한 적은 시간에 테스트 하는것이 좋을듯