티스토리 뷰

Tomcat

Tomcat CurrentThreadBusy 란?

소농배 2019. 5. 29. 17:51

tomcat metric

 

스크린샷처럼 메트릭에 잡히는 Current Thread Busy 가 의미하는 것이 무엇인지 궁금했다. 

 

https://stackoverflow.com/questions/7790303/tomcat-thread-monitoring-mbeans-description

 

Tomcat Thread Monitoring Mbeans Description

In thread related Mbeans of Tomcat I see under Catalina.ThreadPool. there are different attributes viz. maxThreads, currentThreadCount, currentThreadsBusy etc. So, where can I get the description...

stackoverflow.com

 

maxThreads, currentThreadCount, currentThreadsBusy JMX properties relate to a thread pool the Tomcat Connector uses to handle incoming requests. You can see the threads usually named http-nio-[port-number]-exec-[sequence-number] in your application thread list. When a request arrives to the Connector, the latter assigns, by the means of a thread pool, a certain thread to it, this thread will by "busy" until the request is handled. So, currentThreadsBusy reflects the number of the requests that are being currently handled.

 

If it uses java.util.concurrent.ThreadPoolExecutor as a thread pool (default choice), maxThreads maps to the ThreadPoolExecutor's maximumPoolSize, currentThreadsBusy - to activeCount, and currentThreadCount - to poolSize.

 

 

Tomcat 의 currentThreadBusy 는 Http Thread pool 의 ThreadPoolExecutor.getActiveCount()  의 리턴 값이다.

Tomcat thread pool 을 디폴트 설정인  java.util.concurrent.ThreadPoolExecutor 를 사용한다면!

 

ThreadPoolExecutor.getActiveCount() 는 thread pool 에서 Task 를 할당받은 쓰레드의 카운트이다.

시니어분께서는 active group 의 count 라는 커맨트를 주셨다. 

 

 

ThreadPoolExecutor.getActiveCount() 를 코드로 확인해보자.

 

 

 

ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newFixedThreadPool(10);
 
       executor.execute(() -> {
           try {
               TimeUnit.SECONDS.sleep(1000000);
           } catch (Exception e) {
 
           }
       });
 
       executor.execute(() -> {
           try {
               TimeUnit.SECONDS.sleep(1000000);
           } catch (Exception e) {
 
           }
       });
 
 
    	executor.execute(() -> {
           int i = 1;
           while(true) {
               i++;
           }
       });
 
       executor.execute(() -> {
           int i = 1;
           i++;
       });
 
 
       executor.execute(() -> {
           int i = 1;
           i++;
       });
 
       System.out.println(executor.getActiveCount());

 

2개의 쓰레드는 sleep 으로 잠드는 Task 실행

2개의 쓰레드는 빠르게 끝나는 연산 수행 후에 pool 로 돌아가도록 실행

1개의 쓰레드는 무한루프

 

실행 결과 : executor.getActiveCount() => 3

 

 

Thread dump

"pool-1-thread-5" #15 prio=5 os_prio=31 tid=0x00007f9bf6856800 nid=0xa403 waiting on condition [0x00007000079e3000]
   java.lang.Thread.State: WAITING (parking)
        at sun.misc.Unsafe.park(Native Method)
        - parking to wait for  <0x000000076ac3c7a0> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
        at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
        at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
        at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at java.lang.Thread.run(Thread.java:748)
 
"pool-1-thread-4" #14 prio=5 os_prio=31 tid=0x00007f9bf6855000 nid=0x5803 waiting on condition [0x00007000078e0000]
   java.lang.Thread.State: WAITING (parking)
        at sun.misc.Unsafe.park(Native Method)
        - parking to wait for  <0x000000076ac3c7a0> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
        at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
        at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
        at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at java.lang.Thread.run(Thread.java:748)
 
"pool-1-thread-3" #13 prio=5 os_prio=31 tid=0x00007f9bf783e000 nid=0xa603 runnable [0x00007000077dd000]
   java.lang.Thread.State: RUNNABLE
        at Main.lambda$main$2(Main.java:31)
        at Main$$Lambda$3/1791741888.run(Unknown Source)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at java.lang.Thread.run(Thread.java:748)
 
"pool-1-thread-2" #12 prio=5 os_prio=31 tid=0x00007f9bf783d000 nid=0x5603 waiting on condition [0x00007000076da000]
   java.lang.Thread.State: TIMED_WAITING (sleeping)
        at java.lang.Thread.sleep(Native Method)
        at java.lang.Thread.sleep(Thread.java:340)
        at java.util.concurrent.TimeUnit.sleep(TimeUnit.java:386)
        at Main.lambda$main$1(Main.java:21)
        at Main$$Lambda$2/363771819.run(Unknown Source)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at java.lang.Thread.run(Thread.java:748)
 
"pool-1-thread-1" #11 prio=5 os_prio=31 tid=0x00007f9bf783c800 nid=0xa803 waiting on condition [0x00007000075d7000]
   java.lang.Thread.State: TIMED_WAITING (sleeping)
        at java.lang.Thread.sleep(Native Method)
        at java.lang.Thread.sleep(Thread.java:340)
        at java.util.concurrent.TimeUnit.sleep(TimeUnit.java:386)
        at Main.lambda$main$0(Main.java:13)
        at Main$$Lambda$1/381259350.run(Unknown Source)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at java.lang.Thread.run(Thread.java:748)

 

 

즉, 일을 할당 받았지만 sleep 으로 인해 TIMED_WAITING 상태의 쓰레드 2개 + 무한루프 RUNNABLE 상태의 쓰레드 1개 = 3

 

 

위 내용들로 알수 있는 tomcat 의 currentThreadBusy 카운트는 Request 를 받아서 Thread pool 에서 Request 를 할당받은 쓰레드의 갯수이다.

중요한건 Thread Status 와 관련이 없다는 것이다!

WAITING , TIMED_WAITING, RUNNABLE 이든지 간에 Request 만 할당 받았다면 getActiveCount 에 잡힌다.

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/03   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31
글 보관함