실전 프로젝트 2주차. 오늘은 일주일간 막혀있던 문제를 해결했다. TIL에 바로 정리해보려 한다.
문제 : jmeter 부하 테스트를 할 때 마다 10000명이든 15000명이든 20000명이든 오류율을 배제하고 나면 티켓 예매가 정상적으로 진행 된 갯수는 8000명대로 일정했다.
시도 :
처음엔 EC2 사양 문제라고 생각했다. 하지만 EC2 CPU 부하율이 생각보다 낮았고, 인스턴스 성능을 바꿔봐도 개선점이 없어서 배제했다.
쓰레드풀 변경. 생성 쓰레드가 적거나, 갑작스런 쓰레드 생성시 부하가 걸린건가 하고 생각이 들어 max 쓰레드풀을 100부터 1000까지 올려가며 테스트 해봤으나 속도에는 차이가 있었지만 오류율은 그대로 였다.
DB 커넥션 풀 변경. 쓰레드 풀이 커도 DB 커넥션 풀이 받쳐주지 못하면 JDBC 예외가 터지면서 서버에서 DB로 가는 경로에 병목현상이 생겼다. 그래서 DB 커넥션풀도 조정해 봤지만 오류율과는 크게 상관이 없었다.
해결 :
쓰레드풀을 계속 바꾸는 과정에서 Spring의 내장 웹서버인 Tomcat 설정을 바꿨는데 그곳에서
server.tomcat.max-connections : 서버가 유지할 수 있는 최대 Connection의 수 (Default : 8192)
를 보게 되었고, 디폴트 숫자가 부하 테스트시 봤던 숫자가 비슷해 이걸 조정해봐야 겠다는 생각이 들었다. max 커넥션 수를 15000 으로 설정하고 테스트 해보니
위와 같이 오류율이 급감했다. 물론 평균 응답속도는 증가했지만 오류율은 잡을 수 있게 되었다.
알게된 점 : tomcat의 max-connection을 조정해 동시에 받을 수 있는 커넥션 수를 조절할 수 있다.
server.tomcat.threads.max : 최대 실행가능 쓰레드 수. Default=200
server.tomcat.threads.min-spare : 항상 대기중인 쓰레드의 최소 수 default=10
server.tomcat.max-connections : 서버가 유지할 수 있는 최대 Connection 수. default=8192
server.tomcat.accept-count : 모든 쓰레드가 사용 중일때 들어온 요청이 대기하는 큐의 최대 길이. default=100. 일반적인 상황에서는 모든 쓰레드가 가득차면 장애일 가능성이 높아 큐의 길이가 너무 길면 응답시간만 늦어지고 장애 상황 인지가 늦어질 수 있다.
server.tomcat.connection-timeout : 최초 연결이 허용되고 요청 URI를 제출할 때 까지 커넥터가 기다리는 시간.
server.tomcat.max-http-form-post-size : post 요청 최대 form 컨텐츠 용량. default=2mb
server.tomcat.max-swallow-size : request body 최대 용량. default=2mb
server.tomcat.processor-cache : 캐시로 재사용 될 최대 유휴 프로세서 수. default=200. -1은 무제한으로 최대연결수와 동일
server.tomcat.uri-encoding : URI 디코딩에 사용할 문자 인코딩 설정. default=UTF-8