- 문제 상황 :
- k8s에 의해 N개의 파드, previw 서버, 레플리카, 오토 스케일링 등등의 운영 환경 배포 상황에서 관리자 모듈을 빌드 및 오케스트레이션 하는 과정에서 커넥션이 다수 발생해서 설정된 DB 커넥션의 한계치를 넘어버리는 상황
- 추가 설명 : (멀티 모듈의 상위 모듈은 하위 모듈이 가지고 있는 의존성들의 커넥션의 총 합을 갖게 됨..)
- 어플리케이션의 actuator가 헬스체크도 제대로 못할 뿐더러 rds에서 생성한 db 의 max_connection의 임계치까지 도달해버려 로컬에서 DB 접속이 불가해지고, 물론 파드에 문제가 발생하는 현상 식별
- k8s에 의해 N개의 파드, previw 서버, 레플리카, 오토 스케일링 등등의 운영 환경 배포 상황에서 관리자 모듈을 빌드 및 오케스트레이션 하는 과정에서 커넥션이 다수 발생해서 설정된 DB 커넥션의 한계치를 넘어버리는 상황
- 멀티 모듈 형태의 아키텍처를 가지고 있는 어플리케이션에서 **관리자 모듈(**Admin)을 운영 환경에 배포해야하는 상황에서 발생한 문제
- 고민한 내용 그리고 문제 식별과 해결 포인트 :
- 고민 1)
- pods는 정상으로 떴다는 신호를 받아서 원하는 페이지에는 접근이 가능할 것이라는 생각
- thymeleaf의 LoginPage에 접근하지 못하는 현상 발생
- 이 시점까지 커넥션이 문제가 될 것이라 생각 x
-
- security 설정 점검 및 변경 → 문제 없음
- 마이그레이션 이전 버전의 security 설정파일 재점검 및 오탈자,누락된 부분 있는지 확인 → 없음
- fabicon.ico 이미지 문제일까 추가 후 재시도(경로 및 실제 이미지 문제) → 실패
- **외부 폰트를 가지고 오는 html 의 링크에서 해당 부분에서 접근에 관한 보안 정잭으로 인해 문제가 생긴 것인지 주석 후 시도 (외부에서 접근에 관련내용의 문제)**→ 실패
- k8s 내부의 포트 문제일까 싶어 포트 변경 후 재시도 → 실패
- 기존에 설정해놓은 Mybatis의 설정때문인가 싶어 일부 설정 변경 및 비교 → 문제 없음
- SSL 인증서 점검 → 문제 없음
- openenssl s_client -connect 웹서버 주소:443
- 혹시나 helm chart에 http 관련 설정이 문제가 있는 것일까 싶어 helm-chart에 아래의 설정 추가(쿠버 네티스 자체적인 문제) → 실패
- data: server.insecure: "true"
- 사내 서비스의 관리자도 동일하게 thymeleaf로 되어 있음을 알고 설정 추가(엔진엑스 관련 ingress.yaml 설정 추가) → 실패 (
- security 설정 점검 및 변경 → 문제 없음
-
- 고민 1)
nginx.ingress.kubernetes.io/proxy-body-size: 50m
nginx.ingress.kubernetes.io/proxy-connect-timeout: "300"
nginx.ingress.kubernetes.io/proxy-send-timeout: "300"
nginx.ingress.kubernetes.io/proxy-read-timeout: "300"
nginx.ingress.kubernetes.io/from-to-www-redirect: "true"
- 각 설정 별 부가 설명
- nginx.ingress.kubernetes.io/proxy-body-size
- Client에서 업로드 할 수 있는 최대 요청 본문 크기 제한
- 파일 업로드와 같은 요청에서 큰 데이터 전송 시, 기본 값보다 큰 값으로 조정할 때 사용
- 기본값 1MB → 늘리지 않으면 413 Error 발생
- Client에서 업로드 할 수 있는 최대 요청 본문 크기 제한
- nginx.ingress.kubernetes.io/proxy-connect-timeout
- BE 서버와 연결을 설정하는 데 최대 대기 시간
- 기본값 60s → 타겟 서버가 느리면 사용
- nginx.ingress.kubernetes.io/proxy-send-timeout
- nginx가 BE 서버로 요청 보낼 때의 타임아웃
- nginx.ingress.kubernetes.io/proxy-read-timeout
- nginx가 BE 서버의 응답을 읽을 때 대기 설정
- 대용량 데이터 처리 혹은 수행이 오래 걸리는 작업애 대해 적절한 타임 고려
- nginx.ingress.kubernetes.io/from-to-www-redirect
- www가 없는 도메인을 www가 포함된 도메인으로 자동 리다이렉션
- 고민 2)
- 왜 커넥션이 계속해서 튈까? 혹시나 문제가 되지 않을까?를 고민 타 회사 동료들과 의견을 나누고 문제 포인트를 식별하기 위해 해당 RDS의 정보들을 확인 및 문제 식별
/* 현재 서버에 연결된 커넥션 조회*/ show status like '%used_connection%'; /* 현재 실행중인 mysql 프로세스 조회 */ SHOW PROCESSLIST; /* 현재의 DB에 Max Connection */ show variables like 'max_connections';
- www가 없는 도메인을 www가 포함된 도메인으로 자동 리다이렉션
- nginx.ingress.kubernetes.io/proxy-body-size
- 문제 포인트 :
- 최대치로 설정된 값에 대한 현재 수행중인 커넥션이 이미 넘어버린 상황
- aws rds db.t3.medium + mariaDB 기준 Max connection 152
- 이미 수행중인 프로세스가 152 connection
- 할당중인 버퍼 사이즈 및 데이터 관련 계산 :
- 최대치로 설정된 값에 대한 현재 수행중인 커넥션이 이미 넘어버린 상황
SHOW VARIABLES LIKE 'sort_buffer_size'; # 2097152
SHOW VARIABLES LIKE 'join_buffer_size'; # 262144
SHOW VARIABLES LIKE 'read_buffer_size'; # 262144
SHOW VARIABLES LIKE 'read_rnd_buffer_size'; # 524288
SHOW VARIABLES LIKE 'thread_stack'; #262144
SHOW VARIABLES LIKE 'net_buffer_length'; #16384
sort_buffer_size = 2097152 / 1024 = 2048KB
join_buffer_size = 262144 / 1024 = 256KB
read_buffer_size = 262144 / 1024 = 256KB
read_rnd_buffer_size = 524288 / 1024 = 512KB
thread_stack = 16384 / 1024 = 16KB
2048KB + 256KB + 256KB + 512KB + 16KB = 3088KB (약 3.02MB)
-
- HiKariCP와 같은 커넥션 풀은 미리 일정 수의 커넥션을 생성하고 유지함 (사용하지 않더라도)
- 설정된 최소 커넥션 값이 높으면 사용하지 않는 커넥션도 계속해서 유지
- 해결 포인트 :
- 커넥션을 어떤 방식으로 늘릴 것인가?
- 강제적으로 커넥션 수를 조정하거나..
- (set global max_connection= xxx or 파라미터 그룹 에서 설정)
- 기존에 제로카라는 전체 서비스는 모두 다 한 곳의 RDS를 바라보고 있는 상황인데, 이를 좀 분리하는 방식 (새로운 RDS 생성) → (추후 작업 예정 확정)
- ERP 모듈이 바라보고 있는 RDS 와 서비스 운영을 위한 API 서버들이 바라보고 있는 RDS
- 그러는 과정에서 알게 된 사실
- MariaDB 는 보수적으로 약 24MB의 메모리를 커넥션에 할당하게 된다 → 이걸 통해서 max_connection을 계산할 수 있음 (mysql =24MB)
- ai 답변 (아래)
- MariaDB 는 보수적으로 약 24MB의 메모리를 커넥션에 할당하게 된다 → 이걸 통해서 max_connection을 계산할 수 있음 (mysql =24MB)
- mysql처럼MariaDB도 할당하는 메모리의 사이즈를 줄여 최대 커넥션 개수 증진으로 max_connection 증가로 이전에 발생한 문제인 To many Connection 해결(해결)
- maximun-pool-size 설정 ⇒ 해당 모듈은 커넥션이 많이 필요 없음
- 그러나 근본적으로 관리자 로그인 화면인 타임리프에 접근하지 못하는 이슈는 그대로 존 빌드 시 k8s가 새로운 파드를 띄우면서 커넥션을 잡게 되는데, 여기서 더 넘을 수 없어 빌드 로그에선 Too Many Connection 에러 발생
- 강제적으로 커넥션 수를 조정하거나..
- 커넥션을 어떤 방식으로 늘릴 것인가?
네, MariaDB는 기본 공식이 조금 다릅니다. RDS MariaDB의 경우:`LEAST({DBInstanceClassMemory/25165760},12000)`이 공식을 사용합니다. 여기서 차이점을 보면:MySQL:
- 연결당 약 12MB (12,582,880 바이트) 계산
- 상한값 제한 없음
MariaDB:
- 연결당 약 24MB (25,165,760 바이트) 계산
- 최대 12,000개로 상한값 제한
이런 차이가 있는 이유는:
1. MariaDB가 연결당 더 보수적으로 메모리를 할당 (약 24MB)
2. 과도한 연결로 인한 서버 부하를 방지하기 위해 절대적인 상한선(12000) 설정
따라서 같은 인스턴스 타입이라도 MariaDB는 MySQL보다 기본적으로 더 적은 최대 연결 수를 허용하게 됩니다.