개 요

프로젝트 테스트를 진행도중 요청 시 간헐적으로 무한대기 상태에 빠지는 현상이 발생하게 되었다.

간혈적으로 발생하는 현상이다보니 정확한 원인확인이 어려웠고, 원인 확인을 위해 이전 로그까지 모두 확인해보게되었다.

로그를 확인해보니 요청이 없는 시간대에서 connection validate check 에러가 발생하고 있었고

요청이 없는상태에서 다시 요청을 했을때 무한대기 상태에 빠지게 되고있었다.

(connection validate check는 DBCP 설정에서 10분 주기로 5개씩 확인하도록 설정 되어있다.)

그런데, 무한대기상태에 빠져있다가 일정시간이 지나서 요청을하면 정상요청이 되었다.

 

원인을 유추해보자

위 현상으로 보았을 때 원인을 아래와 같이 유추할 수 있었다.

  1. 일정시간 이상 요청이 없는 경우 커넥션 연결을 끊는다.
  2. 연결이 끊긴상태에서 validate check를 해서 에러가 발생한다.
  3. 연결 유지하는시간이 validate check 주기보다 짧기 때문에 에러가 발생한다.
  4. 연결이 끊긴상태에서 다시요청을 하게되면 커넥션연결로 인해 요청이 대기상태에 빠진다.
  5. 일정시간이 지나고 커넥션이 연결되고 요청을 했기때문에 정상호출이 되었다.
  6. 무한대기상태에 빠진것은 timeout설정을 안했기 때문이다.
  7. 연결을 끊는것은 application단에서 인지, 서버단인지, 네트워크단인지 확인이 필요하다.

 

OS keepalive 설정 확인

OS(windows,linux) 기본 설정으로 keepalive가 2시간으로 설정되어있는것을 확인하였다.

연결소켓(tcp)을 2시간동안 유지하다 초과되면 연결이 끊긴다.

OS에 이런설정이 있다는 것은 처음 알게된 사실이다. 2시간을 기준으로 validate 주기와 개수를 결정한다.

명령어

# sysctl -a | grep keepalive

 

validate 주기와 개수 결정

 이제 연결유지되는 시간을 알게되었으니 validate 주기와 개수를 결정해보자.

('IDC 정책에서 허용하는 최대 유휴 커넥션 유지 시간' / timeBetweenEvictionRunsMillis 속성값) * numTestsPerEvictionRun 속성값) > 전체 커넥션 개수

위 공식을 현재 설정에 적용해보면 아래와 같다

(120분/10분) * 5개 > 100개

결과는, 60 > 100로 40개를 체크하지 못하는 결과가나온다.

체크하지 못한 40개의 커넥션은 끊기게 될것이고 재연결 시 위와 같이 대기상태에 빠지는 것이다.

IDC 정책 변경은 어려우니,

timeBetweenEvictionRunsMillis의 주기를 낮추거나, numTestsPerEvictionRun의 개수를 늘려야한다.

case1) timeBetweenEvictionRunsMillis = 6분 / numTestsPerEvictionRun =5개

case2) timeBetweenEvictionRunsMillis = 10분 / numTestsPerEvictionRun = 9개

위 두케이스 테스트를 통해 최적화를 해보자.

 

참고자료

https://d2.naver.com/helloworld/5102792

https://mikelim.mintocean.com/entry/tomcat-%EC%BB%A8%EB%84%A5%EC%85%98%ED%92%80-%EC%82%AC%EC%9A%A9%EC%8B%9C-%EC%97%B0%EA%B2%B0%EB%81%8A%EA%B9%80%EC%9D%84-%EB%B0%A9%EC%A7%80-%ED%95%98%EA%B8%B0-%EC%9C%84%ED%95%9C-%EC%84%A4%EC%A0%95

https://blog.naver.com/tyboss/70176230775

+ Recent posts