학습(구)/Java(구)

자바 성능 튜닝 - 웹 개발(JSP/서블릿/스프링)

잉아당 2021. 6. 8. 16:33
728x90

<JPS와 서블릿>

WAS 에서 병목 현상이 발생할 수 있는 부분은 서버쪽의 UI부분과 비즈니스 로직 부분으로 나눌 수 있습니다.

JSP와 서블릿으로 서버단의 UI를 구성합니다.

 

JSP는 가장 처음에 호출되는 경우에만 시간이 소요되고 그 이후에는 컴파일된 서블릿 클래스가 수행됩니다.

 

JSP 라이프 사이클

1. JSP URL 호출

2. 페이지 번역

3. JSP 컴파일

4. 클래스 로드

5. 인스턴스 생성

6. jspInit 메서드 호출

7. _jspService 메서드 호출

8. jspDestory 메서드 호출

=> JSP 페이지가 이미 컴파일 및 클래스 로드가 되어져 있고 JSP 파일이 변경되지 않았다면 2~4 프로세스는 생략됩니다. 

 

Pre- compile : 서버 종류에 따라 서버가 기동될 때 컴파일을 미리 수행하는 옵션으로 최신 버전을 반영한 후 처음 호출 되었을 때 응답시간이 느린 현상을 방지 할 수 있지만 개발 시 옵션을 켜 놓으면 서버 기동 시 매번 컴파일 하기 때문에 개발 생산성이 떨어지게 됩니다.

 

서블릿 라이프 사이클 

- Servlet 객체자 자동으로 생성되고 초기화 

- 사용자가 Servlet을 처음으로 호출 했을 때 생성되고 초기화

=> 사용가능 상태로 대기하다 중간에 예외가 발생하면 사용 불가능으로 변하다가 다시 사용가능으로 변합니다.

=> 해당 서블릿이 필요가 없을 때는 파기가 되고 JVM에서 제거가 됩니다.

서블릿은 JVM에서 여러 객체로 생성되지 않고 사용가능 상태의 서블릿은 JVM에 존재하며 여러 스레드에서 해당 서블릿의 service() 메서드를 호출하여 공유합니다.

공유 되어지기 때문에 변수를 생성 할때 scope 를 잘 생각 해서 작성해야 합니다.

 

JSP include

- inlcude 방식은 정적인 방식과 동적인 방식이 있습니다.

- 정적 방식 : JSP 페이지 번역 및 컴파일 단계에서 필요한 JSP를 읽어 포함시키는 방식

<%@ include file = "url"%>

- 동적 방식 : 페이지 호출 때마다 지정된 페이지를 불러 수행

<jsp:include page="url"/>

 

=> 성능은 정적이 빠르지만 추가되어 동일한 이름의 변수가 있으면 오류가 발생할 수 있으므로 상황에 맞게 사용해야 합니다.

 

Java Beans

- UI에서 서버 측 데이터를 담아서 처리하기 위한 컴포넌트

- 많은 useBean은 성능을 저하 시ㅣ므로 TO(Transfer object) 패턴을 사용하는 것이 좋습니다.

 

태그라이브러리 

- JSP에서 공통적으로 반복되는 코드를 클래스로 만들어 이 클래스를 정의된 태그로 사용할 수 있게 하는 라이브러리 

- XML 기반의 tld파일과 태그 클래스로 구성

- 태그라이브러리를 사용하기 위해서 web.xml에 tld URL 과 파일 위치를 설정해야 사용할 수 있습니다.

- 주로 태그라이브러리 클래스를 잘못 작성하거나 태그 라이브러리 클래스로 전송되는 데이터가 많을 떄 성능에 문제가 생기게 됩니다.

 

<스프링>

- 스프링은 복잡한 어플리케이션도 POJO(Plain Old Java Object)로 개발 할 수 있는 장점을 가지고 있습니다.

- POJO : 특정 프레임워크나 라이브러리에 얽매이지 않는 오브젝트

- 서블릿을 개발할려면 HttpServlet이라는 클래스를 상속해야 하지만 스프링을 사용하면 상속하지 않아도 웹 요청을 처리 할 수 있는 클래스를 생성할 수 있습니다.

- DI : 객체간의 의존을 주입하여 편하게 관계를 관리하는 기술로써 종속성을 줄여줍니다.

- AOP : 중복된 코드를 따로 분리하여 공통된 부분을 여러 객체에 적용시킬 수 있는 기술입니다. 주로 트랜잭션 등에 사용됩니다.

- PSA : 비슷한 기술에 적용할 수 있게 추상화 계층을 제공하여 사용하는 기술이 바뀌더라도 비즈니스 로직의 변화가 없도록 해주는 것입니다.

- 프록시를 사용하는데 있어 성능 저하 현상이 많이 발생합니다.

- 캐시는 스프링에서 자체적으로 제공하고 있으며 문자열을 리턴했을 때 이미 생성되어진 뷰 객체를 찾아 사용하게 됩니다. 하지만 매번 다른 문자열을 리턴하는 등 캐시가 생성될 여지가 없는 상황에서 문자열을 리턴하는 것은 메모리 낭비가 될 수 있으므로 뷰 객체 자체를 반환하는 방법이 도움 될 수 있습니다.