J2EE 애플리케이션이 느리게 실행되고 있습니까? 증가하는 트래픽을 견딜 수 있습니까? 이 기사에서는 고성능, 고탄력성 JSP 페이지 및 서블릿 개발을 위한 성능 최적화 기술에 대해 설명합니다. 아이디어는 가능한 한 빨리 구축하고 점점 늘어나는 사용자와 요청에 적응하는 것입니다. 이 기사에서는 서블릿과 JSP 페이지의 성능을 크게 향상시켜 J2EE의 성능을 향상시킬 수 있는 실용적이고 입증된 성능 조정 기술을 배우도록 안내하겠습니다. 이러한 기술 중 일부는 설계 및 코딩 단계와 같은 개발 단계에서 사용됩니다. 기술의 또 다른 부분은 구성과 관련되어 있습니다.
기술 1: HttpServletinit() 메소드에서 데이터 캐싱
서버는 서블릿 인스턴스를 생성한 후 서블릿이 요청을 처리하기 전에 서블릿의 init() 메소드를 호출합니다. 이 메소드는 서블릿의 라이프사이클에서 한 번만 호출됩니다. 성능을 향상시키려면 init()에 정적 데이터를 캐시하거나 초기화 중에 수행해야 하는 비용이 많이 드는 작업을 수행하십시오. 예를 들어, 한 가지 모범 사례는 javax.sql.DataSource 인터페이스를 구현하는 JDBC 연결 풀을 사용하는 것입니다.
DataSource는 JNDI 트리에서 가져옵니다. SQL이 호출될 때마다 JNDI를 사용하여 DataSource를 찾는 것은 매우 비용이 많이 들고 애플리케이션 성능에 심각한 영향을 미칩니다. Servlet의 init() 메소드를 사용하여 DataSource를 얻고 나중에 재사용하기 위해 캐시할 수 있습니다.
publicclassControllerServletextendsHttpServlet
{
privatejavax.sql.DataSourcetestDS=null;
publicvoidinit(ServletConfigconfig)throwsServletException
{
super.init(config);
Contextctx=널;
노력하다
{
ctx=newInitialContext();
testDS=(javax.sql.DataSource)ctx.lookup("jdbc/testDS");
}
catch(NamingException)
{
ne.printStackTrace();
}
잡기(예외)
{
e.printStackTrace();
}
}
publicjavax.sql.DataSourcegetTestDS()
{
returntestDS;
}
...
...
}
기술 2: 서블릿 및 JSP의 자동 로딩 기능을 비활성화합니다
. 서블릿/JSP를 수정할 때마다 서버를 다시 시작해야 합니다. 자동 로딩 기능은 개발 시간을 줄여주기 때문에 개발 단계에서 매우 유용한 기능으로 간주됩니다. 그러나 런타임 단계에서는 매우 비용이 많이 듭니다. 서블릿/JSP는 불필요한 로딩으로 인해 성능이 저하되고 클래스 로더에 대한 부담이 증가합니다. 다시 말하지만, 특정 클래스 로더에 의해 로드된 클래스가 현재 클래스 로더에 의해 로드된 클래스와 협력할 수 없기 때문에 이로 인해 애플리케이션에 이상한 충돌이 발생할 수 있습니다. 따라서 실행 환경에서 더 나은 성능을 얻기 위해서는 서블릿/JSP의 자동 로딩 기능을 꺼야 합니다.
기술 3: HttpSession 제어
많은 애플리케이션에는 서로 관련될 수 있도록 일련의 클라이언트 요청이 필요합니다. HTTP 프로토콜은 상태 비저장이므로 웹 기반 애플리케이션은 세션이라는 상태를 유지 관리해야 합니다. 상태를 유지해야 하는 애플리케이션을 지원하기 위해 Javaservlet 기술은 세션을 관리하고 세션을 구현하기 위한 여러 메커니즘을 허용하는 API를 제공합니다. HttpSession 개체는 세션 역할을 하지만 사용에는 비용이 듭니다. HttpSession이 사용되고 재정의될 때마다 서블릿이 이를 읽습니다. 다음 기술을 사용하여 성능을 향상시킬 수 있습니다.
lJSP 페이지에서 기본 HttpSession을 생성하지 않음: 기본적으로 JSP 페이지는 HttpSession을 생성합니다. JSP 페이지에서 HttpSession을 사용하지 않는 경우 성능 오버헤드를 절약하려면 다음 페이지 지침을 사용하여 HttpSession 객체가 자동으로 생성되지 않도록 하세요.
< %@pagesession="false"% >
1) HttpSession에 대형 객체 그래프를 저장하지 마세요: HttpSession에 데이터를 대형 객체 그래프로 저장하면 애플리케이션 서버는 매번 전체 HttpSession 객체를 처리해야 합니다. 이로 인해 Java 직렬화가 강제되고 계산 오버헤드가 증가합니다. 직렬화 오버헤드로 인해 HttpSession 개체에 저장된 데이터 개체가 증가하면 시스템 처리량이 감소합니다.
2) 사용 후 HttpSession 해제: HttpSession을 더 이상 사용하지 않는 경우 HttpSession.invalidate() 메서드를 사용하여 세션을 무효화합니다.
3) 시간 초과 값 설정: 서블릿 엔진에는 기본 시간 초과 값이 있습니다. 세션을 삭제하지 않거나 시간이 초과될 때까지 세션을 계속 사용하면 서블릿 엔진이 메모리에서 세션을 삭제합니다. 메모리 및 가비지 수집의 오버헤드로 인해 세션 시간 초과 값이 클수록 시스템 복원력과 성능에 미치는 영향이 커집니다. 세션 시간 초과 값을 가능한 한 낮게 설정하십시오.
기술 4: gzip 압축 사용
압축은 중복된 정보를 제거하고 가능한 한 작은 공간에 정보를 설명하는 방법입니다. gzip(GNUzip)을 사용하여 문서를 압축하면 HTML 파일 다운로드 시간을 효과적으로 줄일 수 있습니다. 메시지가 작을수록 더 빨리 전송됩니다. 따라서 웹 애플리케이션에서 생성된 콘텐츠를 압축하면 사용자에게 더 빨리 도달하고 사용자 화면에 표시됩니다. 모든 브라우저가 gzip 압축을 지원하는 것은 아니지만, 브라우저가 이를 지원하는지 확인하고 gzip 압축 콘텐츠를 브라우저로 보내는 것은 쉽습니다. 아래 코드 조각은 압축된 콘텐츠를 보내는 방법을 보여줍니다.
publicvoiddoGet(HttpServletRequestrequest,HttpServletResponse응답)
throwsIOException,ServletException
{
OutputStreamout=null
//HTTP 요청에서 Accepting-Encoding 헤더를 확인합니다.
//헤더에 gzip이 포함된 경우 GZIP을 선택합니다.
//헤더에 압축이 포함된 경우 ZIP을 선택합니다.
//그렇지 않으면 압축을 선택하세요.
Stringencoding=request.getHeader("Accept-Encoding")
if(encoding!=null&&encoding.indexOf("gzip")!=-1)
{
response.setHeader("콘텐츠 인코딩","gzip");
out=newGZIPOutputStream(response.getOutputStream());
}
elseif(encoding!=null&&encoding.indexOf("압축")!=-1)
{
response.setHeader("콘텐츠 인코딩","압축");
out=newZIPOutputStream(response.getOutputStream());
}
또 다른
{
아웃=응답.getOutputStream()
}
...
...
}
기술 5: SingleThreadModel을 사용하지 마세요
SingleThreadModel은 서블릿이 한 번에 하나의 요청만 처리하도록 보장합니다. 서블릿이 이 인터페이스를 구현하면 서블릿 엔진은 새로운 요청마다 별도의 서블릿 인스턴스를 생성하므로 시스템 오버헤드가 많이 발생합니다. 스레드 안전 문제를 해결해야 하는 경우 이 인터페이스 대신 다른 방법을 사용하십시오. SingleThreadModel의 사용은 더 이상 Servlet2.4에서 권장되지 않습니다.
기술 6: 스레드 풀
서블릿 엔진을 사용하여 각 요청에 대해 별도의 스레드를 생성하고 해당 스레드를 service() 메서드에 할당한 다음 service() 메서드가 실행된 후 스레드를 삭제합니다. 기본적으로 서블릿 엔진은 각 요청에 대해 새 스레드를 생성할 수 있습니다. 스레드를 생성하고 삭제하는 데 비용이 많이 들기 때문에 이 기본 동작은 시스템 성능을 저하시킵니다. 스레드 풀을 사용하여 성능을 향상시킬 수 있습니다. 예상되는 동시 사용자 수에 따라 스레드 풀을 구성하고 스레드 풀의 최소 및 최대 스레드 수와 최소 및 최대 증가 값을 설정합니다. 처음에 서블릿 엔진은 구성의 최소 스레드 수와 동일한 수의 스레드로 스레드 풀을 생성합니다. 그런 다음 서블릿 엔진은 작업을 완료할 때마다 새 스레드를 생성하는 대신 풀에서 요청에 스레드를 할당합니다. 스레드 풀을 사용하면 성능이 크게 향상될 수 있습니다. 필요한 경우 최대 스레드 수와 증가 수에 따라 더 많은 스레드를 생성할 수 있습니다.
기술 7: 올바른 포함 메커니즘 선택
JSP 페이지에는 파일을 포함하는 두 가지 방법이 있습니다. 즉, 포함 지침(< %@includefile="test.jsp"% >)과 포함 작업(<jsp:includepage="test.jsp ")입니다. 플러시="true"/>). include 지시문은 페이지가 서블릿으로 컴파일될 때와 같이 컴파일 단계 중에 지정된 파일의 내용을 포함합니다. 포함 작업에는 요청 단계(예: 사용자가 페이지를 요청할 때) 동안 파일 콘텐츠를 포함하는 작업이 포함됩니다. 지침을 포함하는 것이 작업을 포함하는 것보다 빠릅니다. 따라서 포함된 파일이 자주 변경되지 않는 한 include 지시문을 사용하면 더 나은 성능을 얻을 수 있습니다.
기술 8: useBean 작업에서 적절한 범위 사용
JSP 페이지를 사용하는 가장 강력한 방법 중 하나는 JavaBean 구성 요소로 작업하는 것입니다. JavaBeans는 <jsp:useBean> 태그를 사용하여 JSP 페이지에 포함될 수 있습니다. 구문은 다음과 같습니다:
<jsp:useBanid="name"scope="page|request|session|application"class=
"package.className"type="typeName">
</jsp:useBean>
범위 속성은 Bean의 가시 범위를 설명합니다. 범위 속성의 기본값은 페이지입니다. 애플리케이션의 요구 사항에 따라 올바른 범위를 선택해야 합니다. 그렇지 않으면 애플리케이션 성능에 영향을 미치게 됩니다.
예를 들어 일부 요청과 관련된 개체가 필요하지만 범위를 세션으로 설정한 경우 해당 개체는 요청이 끝난 후에도 메모리에 남아 있습니다. 메모리에서 명시적으로 삭제하거나 세션을 무효화하거나 세션 시간이 초과되지 않는 한 메모리에 남아 있습니다. 올바른 범위 속성을 선택하지 않으면 메모리 및 가비지 수집 오버헤드로 인해 성능이 영향을 받습니다. 따라서 개체에 적합한 범위를 설정하고 작업이 끝나면 즉시 삭제하십시오.
기타 기술
1) 문자열 연결 방지: String 객체는 불변 객체이므로 "+" 연산자를 사용하면 많은 수의 제로타임 객체가 생성됩니다. "+"를 더 많이 사용할수록 더 많은 제로타임 개체가 생성되어 성능에 영향을 미칩니다. 문자열을 연결해야 하는 경우 "+" 작업 대신 StringBuffer를 사용하세요.
2) System.out.println 사용 방지: System.out.println은 디스크 입력/출력을 동기식으로 처리하므로 시스템 처리량이 크게 줄어듭니다. 가능하면 System.out.println을 사용하지 마세요. 사용할 수 있는 성숙한 디버깅 도구가 많이 있지만 때로는 System.out.println이 추적이나 디버깅 목적으로 여전히 유용할 때도 있습니다. 오류 및 디버깅 단계에서만 열리도록 System.out.println을 구성해야 합니다. finalBoolean 변수를 사용하여 false로 구성하면 컴파일 단계에서 최적화 확인 및 실행 추적 출력이 완료됩니다.
3) ServletOutputStream과 PrintWriter의 비교: 문자 출력 스트림과 데이터를 바이트로 인코딩하기 때문에 PrintWriter를 사용하면 약간의 성능 오버헤드가 발생합니다. 따라서 PrintWriter는 모든 문자 집합 변환이 올바르게 완료된 후에 사용해야 합니다. 반면에 서블릿이 바이너리 데이터만 반환한다는 것을 알고 있는 경우 서블릿 컨테이너가 바이너리 데이터를 인코딩하지 않으므로 ServletOutputStream을 사용하면 문자 집합 변환 오버헤드가 제거됩니다.
요약
이 기사의 목적은 J2EE 애플리케이션의 전반적인 성능을 향상시킬 서블릿 및 JSP 성능을 향상시키기 위한 실용적이고 입증된 성능 최적화 기술을 보여주는 것입니다. 다음 단계는 EJB, JMS, JDBC 등 기타 관련 기술의 성능 튜닝을 관찰하는 것입니다.