• 적정 스레드 개수 = cpu 수 * (1+ 대기, 유휴 시간/서비스 시간)
    • cpu 대기시간이 서비스 시간보다 짧다면 cpu 개수보다 스레드가 적어야 성능이 좋다.
      이유는 대기가 짧기에 (콘텍스트 스위칭 비용이 적기에) 스레드 개수 적어도 상관없다.

    • 반대로 대기시간이 서비스 처리 시간보다 많다면 스레드 수는 cpu개수보다 많아야 성능이 좋다.
      이유는 대기가 길기에 (콘텍스트 스위칭 비용이 많기에) 스레드 개수를 늘려 대기를 줄여야 한다.

cpu가 I/O를 처리함에따라 대기시간(Idle time)이 발생하는 예시

 

  • 스레드를 많이 띄어야 하는 상황
    • 대기 시간 즉 cpu가 i/o처리 시 block 걸리는 시간이 길 때 (ex, 대용량 파일 I/O 발생, 긴 네트워크 지연 발생)
      에는 스레드 개수를 늘려서 대기시간(block io 시간)을 줄여야 한다.

    • *block io에 대해 궁금하시면 제 블로글 참조 부탁드립니다.
      블로킹/논블로킹, 동기/비동기 I/O 란?

  • 적정 스레드 풀 개수 = CPU 수 * (CPU 목표 사용량) * (1+대기 시간/서비스 시간)
    • ex) Worker 스레드는 요청에 대한 응답을 JSON으로 변환하고 몇 가지 규칙을 실행하는 microservice를 호출한다 가정. 응답 시간은 50ms, 서비스 시간은 5ms이며 worker 스레드를 실행시키는 프로그램은 듀얼코어 cpu라 가정한다면 적절 스레드 풀 사이즈는 2*(1+50/5)=22 가된다.

    • 하지만 HTTP 응답 시에는 JMS(자바 메시지 서비스) 로부터의 요청, JDBC Connection Pool과 같은 애플리케이션의 영역을 고려하자면, CPU 사용량을 추가하면 된다. 이때 CPU 목표 사용량은 0~1 사이다.

    • 톰캣의 경우 maxThreads로 요청시 처리 스레드의 최대 수 설정 가능하고 maxConnections 수에 도달하면  aceeptCount 설정에 따라 추가 연결은 허용하지만 요청을 처리하지는 않는다.

      (가능한 모든 요청 처리 스레드가 사용 중일 때 수신 연결 요청에 대한 최대 대기열 길이. 대기열이 가득 찼을 때 수신 된 모든 요청은 거부됩니다. 기본값은 100이다.)

      NIO 및 NIO2는 대기열 기본값이 10000 이고, APR/native는 8192 이다.

  java.sql.Connection DBCP 커넥션 풀 설정 예시

 

+ Recent posts