욱'S 노트

Tomcat - 시작 속도 빠르게 하기 본문

Programming/Tomcat

Tomcat - 시작 속도 빠르게 하기

devsun 2015. 8. 6. 11:34

이번 섹션은 웹어플리케이션 및 아파치 톰캣의 구동 속도를 빠르게 하기 위한 몇가지 추천사항을 제공한다.


General


팁과 트릭을 진행하기 전에 하나 하고 싶은 조언은 만약 톰캣이 행이나 응답이 없다면 먼저 진단을 수행해보야 한다. 스레드 덤프를 획득한다면 톰캣이 실제 무엇을 하고 있는지를 알 수 있다. 트러블슈팅과 진단 페이지를 자세히 살펴보아라.


JAR scanning


서블릿 3.0 스펙에서는 몇가지 plugablility features에 대한 지원을 소개하고 있다. 이것은 웹어플리케이션 구조를 단순하게 하고 추가적인 프레임워크 플러깅을 단순하게 하는 것이다. 불행하게도 이 기능은 JAR와 클래스 파일의 스캐닝을 요구한다. 이 경우 꽤 많은 시간을 소요하게 된다. 스펙에서는 기본적으로 스캐닝을 수행할 것을 요구한다. 하지만 몇몇의 방법으로 스캐닝을 피하도록 웹어플리케이션을 구성할 수 있다. 


Introduced by Servlet 3.0:


  • SCI (javax.servlet.ServletContainerInitializer)
  • Web fragments (META-INF/web-fragment.xml)
  • jar 파일내에 웹 어플리케이션 번들 리소스 (META-INF/resources/*)
  • 웹어플리케이션의 정의 컴포넌트 어노테이션(@WebServlet etc.)
  • SCI에 의해 초기화되는 3-rd 파티 라이브러리 어노테이션 (arbitrary annotations that are defined in @HandlesTypes annotation on a SCI class)

이번 명세에 소개된 기능은 다음과 같다.


  • TLD scanning, (Discovery of tag libraries. Scans for Tag Library Descriptor files, META-INF/**/*.tld).


어노케이션 스캐닝이 느린 이유는 각 클래스 파일을 읽고 그 안에 있는 어노테이션을 찾아서 파싱해야 하기 때문이다. 


컨테이너에 제공된 SCI는 어노테이션 스캐닝을 트리거한다. 이것은 Tomcat 8 이나 Tomcat 7d의 모든 버젼에 배포되어 있는 WebSocket API 구현체를 찾기 위한 것이다. 정의된 SCI 클래스는 WebSocket 엔드포인트 스캐닝을 트리거 한다.(@ServerEndpoint 또는 ServerApplicationConfig 인터페이스의 구현체) 만약 WebSocket을 지원할 필요가 없다면 톰캣의 WebSocket API와 WebSocket 구현체를 지우면 된다. (websocket-api.jar and tomcat7-websocket.ja ror tomcat-websocket.jar).


TLD 스캐닝의 경우에는 톰캣7이나 이전 버젼에서는 TLD 스캐닝이 두번 발생했다.

첫번째 시작시 tld 파일에 정의된 리스너를 발견하기 위해서 (TldConfig 클래스에 의해 수행) 

두번째는 JSP 엔진에 의해 JSP 페이지를 위한 자바 코드를 생성할 때 발생한다.(TldLocationsCache에 의해 수행)

두번째 스캐닝은 더욱 느린데 TLD를 포함하지 않는 스캔된 JAR에 관한 진단 메시지를 출력하기 때문이다.

톰캣 8에서는 TLD 스캐닝이 시작시 한번만 발생한다.(JapserIntializer)


Configure your web application


톰캣 7 마이그레이션 챕터를 살펴보아라.

WEB-INF/web.xml을 정의하는데에는 두가지 옵션이 있다.

web-app 엘리먼트에 metadata-complete="true"라고 어트리뷰트를 세팅하자.

<absolute-ordering /> 엘리먼트를 추가하자.


metadata-complete="true"를 세팅하는 것은 웹어플리케이션 및 웹어플리케이션에서 정의할때 어노테이션(Servlets 등)을 사용한 클래스 스캐닝을 비활성화한다. metadata-complete 옵션만으로 모든 어노테이션 스캐닝을 비활성화하는 것은 충분하지 않다. 만약 @HandlesTypes 어노테이션과 함께 SCI가 존재한다면 톰캣은 해당 어노테이션을 사용한 클래스나 인터페이스를 스캔해야 한다.


<absolute-ordering> 엘리먼트는 web fragment JAR들을( WEB-INF/web-fragement.xml에 있는 이름을 따른다.)들 명시하는 것은  SCI를 위한 fragment 및 어노테이션을 위한 스캔을 수행하기 위함이다. 빈 <absolute-ordering/> 엘리먼트는 스캔대상을 지정하지 않겠다는 의미이다.


톰캣7에서 absolute-ordering 옵션은 웹어플리케이션에서 제공된 SCI 및 컨테이너에서 제공된 SCI 모두에 영향을 끼친다. 톰캣8에서는 웹어플리케이션의 SCI에만 영향을 주는 반면 컨테이너에서 제공된 SCI는 항상 발견된다. 이러한 경우 absolute-ordering 옵션이 어노테이션 스캐닝을 방지하지 못하지만 스캔된 JAR 리스트는 빈값이 될 것이다. 그러나 스캐닝은 빠르게 완료될 것이다. WEB-INF/classes 하위이 클래스들은 absolute-ordering 옵션에 상관없이 항상 스캔이 된다. 웹어플리케이션의 리소스 및 TLD 스캐닝은 이러한 옵션에 영향을 받지 않는다.


Remove unnecessary JARs


필요하지 않는 JAR 파일은 지워라. 필요한 클래스를 찾기 위해 모든 JAR파일을 검사할 필요가 있다. 만약 jar 파일이 없다면 검사할 대상도 없다는 것이다.

웹어플리케이션은 Servlet API나 Tomcat 클래스의 복제본을 절대 가지지 말아야 한다. 그러한 클래스들은 컨테이너(톰캣)에 의해 제공되어야 하며 웹 어플리케이션에서는 절대 존재하지 말아야 한다. 만약 메이븐을 사용한다면 이러한 디펜던시는 반드시 provided 스코프로 설정하여야 한다.


Exclude JARs from scanning


톰캣 7에서는 시스템 프로퍼티에 이름이나 패턴을 리스팅하여 스캐닝에서 제외할 수 있다. 일반적으로 conf/catalina.properties 파일에 정의한다.


톰캣 8에서는  몇가지 옵션이 존재하는데 시스템 프로퍼티나 웹어플리케이션의 context 파일에 <JarScanFilter> 엘리먼트를 설정함으로서 스캐닝에서 제외시킬수 있다.


Disable WebSocket support


context 엘리먼트에 contanerSciFilter라는 어트리뷰트가 있다. 이것은 톰캣 SCI API를 위해 주입된 컨테이너에서 제공된 기능을 비활성화시키기 위해 사용된다. - 웹소켓 지원(Tomcat 7 이후), JSP 지원 (Tomcat 8이후)


필터를 위한 클래스 명은 톰캣 JAR파일내의 META-INF/services/javax.servlet.ServletContainerInitializer 파일에서 찾을 수 있다. 웹소켓을 지원하기 위한 클래스명은 org.apache.tomcat.websocket.server.WsSci 이며  JSP 지원하기 위한 클래스명은 org.apache.jasper.servlet.JasperInitializer이다.


Entropy Source


Tomcat 7 이상의 버젼에서는 세션 아이디를 위한 랜덤 값을 제공하기 위한 SecureRandom 클래스에 많이 의존한다. JRE에 따라 시작시 많은 딜레이를 유발하기도 한다. 이러한 경고는 log를 통해 나타난다.



<DATE> org.apache.catalina.util.SessionIdGenerator createSecureRandom

INFO: Creation of SecureRandom instance for session ID generation using [SHA1PRNG] took [5172] milliseconds.


JRE가 non-bloking 엔트로피 소스를 사용할 수 있도록 시스템 프로퍼티를 설정하는 것이 하나의 방법이다.(-Djava.security.egd=file:/dev/./urandom)


 "/./" 문자가 값임을 명심하라. Java 8에서는 향상된 SecureRandom 구현이 존재한다. 


블록킹 엔트로피 소스(/dev/random)을 non-blocking 엔트로피 소스로 대체하면 더 작은수의 랜덤 데이터를 가지고 오기문에 실제 보안성이 감소된다는 점을 주의하자.


만약 서버의 엔트로피를 생성하는데 문제가 발생한다면 EntropyKey와 같은 하드웨어 제품을 고려하라.


Starting several web applications in parallel


Tomcat 7.0.23+ 이상에서는  웹어플리케이션을 병렬로 시작하도록 설정할 수 있다. 기본으로는 비활성화되어 있다. Host의 startStopThreads 어트리뷰트를 1보다 큰 값으로 세팅함으로써 활성화 시킬 수 있다.


Memory


메모리 파라미터를 조정하라. - 구글은 당신의 친구다.


Config


설정 파일을 가능하면 trim해라. XML 파싱은 간단하지 않다. 파싱할 대상이 감소하면 빨리 파싱을 수행할 수 있다,


Web application


필요하지 않은 웹어플리케이션은 제거해라. 톰캣과 함께 제공된 웹어플리케이션을 모두 제거해라.


코드가 느린일을 수행하지 말도록 해라. 프로파일러를 사용하라.


출처 : http://wiki.apache.org/tomcat/HowTo/FasterStartUp



Comments