Tomcat은 자바 기반의 인기 있는 서블릿 컨테이너로, 웹 애플리케이션을 서빙하는 데 자주 사용됩니다. 하지만 많은 사용자가 접속하는 대형 서비스에서는 기본 설정으로는 성능이 한계에 부딪힐 수 있습니다. 이때 중요한 것이 Tomcat 최적화입니다.

본 포스트에서는 Tomcat의 성능을 최적화하는 다양한 방법 중에서 쓰레드 풀(Thread Pool)NIO(Non-blocking I/O) 를 활용하는 방법에 대해 다뤄보겠습니다.


1. NIO와 Thread Pool 구조 이해하기

Tomcat은 기본적으로 Blocking I/O를 사용하여 각 클라이언트 요청마다 하나의 쓰레드를 할당합니다. 이는 요청 처리 중 IO 작업이 진행될 때 해당 쓰레드를 블록시키기 때문에 성능에 한계가 있을 수 있습니다. 많은 요청이 동시에 들어오면 서버가 과부하 상태에 빠질 수 있습니다.

이를 해결하기 위한 방법이 NIO입니다. Non-blocking I/O(NIO)는 요청 처리 중 IO 작업을 비동기적으로 처리하여 쓰레드를 블록하지 않습니다. 이 덕분에 적은 수의 쓰레드로도 많은 요청을 처리할 수 있습니다.

NIO쓰레드 풀은 서로 보완적인 관계입니다. NIO가 비동기적으로 요청을 처리하는 동안, 쓰레드 풀(Thread Pool) 은 처리 가능한 쓰레드 수를 조절하여 리소스를 효율적으로 관리합니다.


2. Tomcat에서 NIO 사용하기

Tomcat에서 NIO를 사용하려면 Connector 설정을 변경해야 합니다. server.xml 파일에서 기본 프로토콜을 HTTP11NioProtocol로 설정하면 NIO 방식으로 동작합니다.

NIO 설정 예시

<Connector port="8080" 
           protocol="org.apache.coyote.http11.Http11NioProtocol" 
           connectionTimeout="20000" 
           redirectPort="8443" />
  • protocol="org.apache.coyote.http11.Http11NioProtocol": Tomcat이 NIO 방식으로 HTTP 요청을 처리하도록 지정합니다.

3. 쓰레드 풀(Thread Pool) 최적화

Tomcat의 쓰레드 풀 설정을 통해 동시 처리 가능한 요청 수를 조정할 수 있습니다. 적절한 쓰레드 수를 설정하지 않으면, 과도한 쓰레드 생성으로 인해 서버 자원이 낭비될 수 있으며, 너무 적은 쓰레드는 대기 시간을 증가시킬 수 있습니다.

Tomcat 쓰레드 풀 설정 예시

Tomcat의 server.xml 파일에서 maxThreads, minSpareThreads, maxConnections 등의 설정을 통해 쓰레드 풀을 최적화할 수 있습니다.

<Connector port="8080" 
           protocol="org.apache.coyote.http11.Http11NioProtocol"
           connectionTimeout="20000"
           redirectPort="8443"
           maxThreads="200" 
           minSpareThreads="25" 
           maxConnections="10000"
           acceptCount="100"
           enableLookups="false" />
  • maxThreads: Tomcat이 동시에 처리할 수 있는 최대 쓰레드 수를 설정합니다. 이를 적절히 설정해야 서버가 과부하되지 않습니다.
  • minSpareThreads: 최소 여유 쓰레드 수입니다. 이 값을 적절히 설정하면 새로운 요청에 빠르게 대응할 수 있습니다.
  • maxConnections: Tomcat이 동시에 처리할 수 있는 최대 연결 수입니다. 이 값이 너무 낮으면 연결 대기 시간이 길어지고, 너무 높으면 리소스 소모가 많아질 수 있습니다.
  • acceptCount: 요청 대기 큐의 최대 크기를 설정합니다. 이 값은 maxConnections를 초과하는 연결이 대기할 수 있는 최대 수입니다.

4. JVM 메모리 설정 최적화

Tomcat의 성능을 높이기 위해서는 JVM 메모리 설정도 매우 중요합니다. 적절한 Garbage Collection(GC) 설정을 통해 시스템 자원을 효율적으로 관리하고, 불필요한 메모리 정리로 인한 성능 저하를 막을 수 있습니다.

JVM 메모리 설정 예시

export CATALINA_OPTS="-Xms1024m -Xmx2048m -XX:+UseG1GC -XX:MaxGCPauseMillis=200"
  • -Xms와 -Xmx: 초기 힙 메모리 크기와 최대 힙 메모리 크기를 설정합니다.
  • -XX:+UseG1GC: G1 가비지 컬렉터를 사용하도록 설정합니다.
  • -XX:MaxGCPauseMillis: 가비지 컬렉션의 최대 대기 시간을 설정하여, 너무 긴 GC 대기 시간을 방지할 수 있습니다.

5. 기타 최적화 팁

  • 압축(Compression) 활성화: HTTP 응답을 GZIP으로 압축하면 네트워크 대역폭을 절약하고, 사용자에게 더 빠른 응답을 제공할 수 있습니다.
    <Connector port="8080" 
               protocol="org.apache.coyote.http11.Http11NioProtocol" 
               compression="on" 
               compressableMimeType="text/html,text/xml,text/plain" />
    
  • 예시:
  • 캐싱(Caching): 자주 요청되는 리소스에 대해 캐싱을 활성화하여 성능을 향상시킬 수 있습니다. HTTP 캐싱 헤더를 적절히 설정하면 서버의 부담을 줄일 수 있습니다.
  • 데이터베이스 연결 풀(Connection Pooling): Tomcat은 기본적으로 DBCP(Database Connection Pooling)를 지원합니다. DB 연결을 효율적으로 관리하면 데이터베이스 요청의 성능을 최적화할 수 있습니다.
    <Resource name="jdbc/MyDB" 
              auth="Container" 
              type="javax.sql.DataSource" 
              maxTotal="100" 
              maxIdle="20" 
              maxWaitMillis="10000"
              username="dbuser" 
              password="dbpassword" 
              driverClassName="com.mysql.cj.jdbc.Driver" 
              url="jdbc:mysql://localhost:3306/mydb"/>
    
  • 예시:

결론

Tomcat 성능 최적화는 NIO와 쓰레드 풀(Thread Pool)을 적절히 활용하여 웹 애플리케이션의 처리 성능을 향상시키는 중요한 작업입니다. 이러한 최적화 작업을 통해 웹 서버의 응답 시간을 단축시키고, 더 많은 동시 요청을 효율적으로 처리할 수 있습니다.

Tomcat의 성능을 극대화하려면 지속적인 모니터링과 튜닝이 필요합니다. 트래픽 패턴에 맞춰 설정을 조정하고, 필요한 경우 시스템 성능을 측정하여 더 나은 결과를 얻을 수 있습니다.

 

 

반응형
블로그 이미지

visualp

c#, java

,