http://javaboutique.internet.com/tutorials/tuning/

J2EE 어플리케이션 성능 향상을 위한 6가지 이슈 : JSP와 Servlets 의 성능 향상을 위한 튜닝 #

번역 : Judd (horanghi@naver.com)

이슈 1 : 올바른 Include 매카니즘 적용하기 #

다이나믹 페이지(JSP) 에서 include 부분을 어떻게 쓰는냐에 따라 많은 성능적인 효과를 다르게 느낄 수 있다. JSP 페이지에서 외부 JSP 를 include 하는 방법은 아래와 같이 두가지가 있다. Include directive 방식 (<%@ include file="test.jsp" %>): JSP 컴파일 시점에서 파일의 내용이 include 되게 된다. (JSP => Servlet 으로 변경시) Include action 방식 (<jsp:include page="test.jsp" flush="true" />): 런타임시 파일의 내용이 include 되게 된다. (유저의 요청으로 페이지가 실행되는 시점) Include directive 는 include action 보다 성능적으로 좋으며 빠르다. 페이지는 런타임시에 컴파일 되지 않으며 그러므로 인해 서버사이드 측에서는 어떠한 액션도 하지 않는다. 단지 클라이언트에게 페이지를 보내는 것을 제외하곤 . include 되는 페이지가 자주 바뀌지 않거나 페이지가 다이나믹페이지가 아닌 경우는 include directive 형태로 써야 성능을 향상 시킬 수 있다.

이슈 2 : useBean 액션의 정확한 Scope 을 정하여 사용하라. #

JSP 페이지는 JavaBeans의 형태로 코드상에 재사용을 할 수 있다. 이것은 <jsp:useBean> 이란 액션태그를 사용함으로써 JSP 페이지내에 활용이 가능하다. 문법은 아래와 같다.

<jsp:useBean id="name" scope="request|page|session|application"  
class="package.className" type="typeName">  
</jsp:useBean>   

scope 의 값은 attribute 값중 하나이다. 이값은 Bean이 사용되어질 범위를 정한다. scope 이 정해지지 않는 경우 디폴트 값은 page 로 된다. 성능적인 측면에서 scope을 정확하게 정하는 것이 중요하다. 예를 들어 특정한 요청에 대해서만 bean을 사용하는데 scope이 session 으로 세팅되었다면 해당 object는 요청이 끝나도 계속적으로 메모리에 남게될 것이다. 이 object는 session 이 유효하지 않을 때까지 메모리에 남게 되어 낭비를 발생 시킨다.

이슈 3: 데이타 캐싱을 위해 HttpServlet의 init() 메소드를 활용하라. #

servlet 의 init() 메소드는 servlet 인스턴스가 생성된 후 클라이언트의 요청을 처리 전에 오직 한번 호출된다. 로드가 걸리는 작업이나 초기화 작업은 init 메소드 안에 넣으므로써 좀더 좋은 성능을 낼 수 있다. Connection 풀링은 init() 메소드에 구현할 수 있는 좋은 예중 하나이다. 계속적으로 재활용이 이후에도 가능하며 또한 재활용된다. 예를 아래에 보여주고 있다.

public class TaskServlet extends HttpServlet{  
  
   private javax.sql.DataSource dataSource = null;   
  
   public void init(ServletConfig configthrows ServletException{  
   super.init(config)
   Context context  = null;  
   try  
   
   context = new InitialContext()
   dataSource = (javax.sql.DataSource)context.lookup ("jdbc/dataSource")
     }  
   catch(NamingException namingException)   
   
   namingException.printStackTrace()
 }   
 catch(Exception exception)  
 {   
 exception.printStackTrace();   
 }   
   
  
   public java.sql.Connection getConnection(){ 
   //return connection from dataSource   
   
  
  //Other methods will go here  

이슈 4 : Servlet과 JSPs 의 auto-reloading을 하지 않도록 세팅하라. #

JSP/Servlets 의 Auto-reloading은 servlet 이나 JSP 코드가 바뀌는 경우 서버를 리스타트 할 필요성을 제거해준다. 그러나 어플리케이션이 디플로이될 때 auto-reloading은 상당한 값어치를 치른다. auto-reloading은 성능에 막대한 영향을 준다. 이건 추가적으로 불필요한 로드를 주는 작업(ClassLoader)이 포함되어 있기 때문이다. 또한 클래스를 재로드할 때 이전 클래스로드에 의해 로딩되어있는 클래스와의 예측 불가능한 문제를 낼 확률이 크기때문에 상당한 위험 부담이 있다. 가장 좋은 선택은 auto-reloading 옵션을 끄는 것이 가장 좋다.

이슈 5: 세션 관리 #

대부분의 어플리케이션은 같은 클라언트에게 연속적인 서비스를 하기위해 세션이 필요하다. Java servlet 기술(API)에서도 이 기능은 세션관리를 위해 지원하고 있다. 개발자들은 세션을 유지하기위해서는 httpSession 을 이용한다. 그에 따른 비용도 발생한다. 디폴트 상태에서는 모든 JSP는 HttpSession의 인스턴스를 생성한다. 이렇게 함으로 호출해서 사용할 수 있다. 그러나, 사용하지 않는다면 굳이 생성할 필요성이 없다. 따라서 해당 Session의 생성을 하지 않도록 아래와 같은 코드세그먼트를 넣어줄 필요가 있다.

<%page session="false"%>   
또 다른 이유는 요청이 매번 있을 때마다 HttpSession 을 이용을 피하기 위함도 있다. HttpSession 을 이용할 경우 꽤 큰 내용의 오프젝트를 세션에 저장되어 하는 경향이 있다. 이것은 성능적인 문제가 될 소지가 크다. 따라서 되도록이면 HttpSession을 이용하는 경우에는 적어도 큰 오프젝트를 저장하는 것은 피해야 한다. 사실 오랜 동안의 session의 유지는 좋은 방법이 아니다. 짧은 세션의 유지를 통해 어플리케이션의 성능을 향상 시켜준다. 언제나 불필요한 세션을 닫아 없애는 것이 좋다는 것을 기억하라. 메모리상의 session 을 close/release 하기 위해서 invalidate() 메소드 를 이용할 수 있음을 기억하라.

이슈 6: gzip 압축을 이용하라. #

일반적으로 압축은 데이타의 사이즈를 줄여주는 역할을 한다. 압축방법은 많이 존재하지만 여기서는 gzip에 초점을 맞추겠다. 대게의 브라우져들은 gzip을 지원한다. 기본적으로 gzip 압축 포맷을 이용하여 데이타를 보내면 클라이언트에게 좀더 빠르게 데이타를 보낼 수 있다. 코드 상의 예를 아래에서 보여주고 있다.

public void doGet(HttpServletRequest httpServletRequest, HttpServletResponse 
httpServletResponse)   
 throws IOException, ServletException{   
  
   OutputStream out = null   
  
   // Perform the check to see if the requesting client can support the format. 
   // We can check the from the Accepting-Encoding header of the HTTP request.  
   // If the header includes gzip, choose GZIP, else dont compress  
  
   String encoding = httpServletRequest.getHeader("Accept-Encoding");  
  
   if (encoding != null && encoding.indexOf("gzip"!= -1){   
 httpServletResponse.setHeader("Content-Encoding" "gzip");  
 out = new GZIPOutputStream(httpServletResponse.getOutputStream())
   
   else if (encoding != null && encoding.indexOf("compress"!= -1){   
 httpServletResponse.setHeader("Content-Encoding" "compress")
 out = new ZIPOutputStream(httpServletResponse.getOutputStream());  
   
   else{   
 out = httpServletResponse.getOutputStream();  
  
   
   //Other methods will go here 

Add new attachment

Only authorized users are allowed to upload new attachments.
« This page (revision-5) was last changed on 07-Apr-2008 11:46 by DongGukLee