실무 때 고민할 만한 부분
1. Servlet 초기화 시간 : 요청 시 초기화 vs 서버 기동시 초기화
요청 시 초기화(Lazy Initialization) - 기본 동작
서블릿 컨테이너는 처음으로 해당 서블릿에 대한 요청이 들어왔을 때 서블릿 객체를 생성하고
init()
메서드를 호출한다.즉, 초기화는 요청이 오기 전까지 지연(Lazy) 된다.
이 동작은 기본적으로 모든 서블릿에 적용된다.
장점
서버 시작 시간 단축
서버 시작 시 서블릿 객체를 초기화하지 않으므로, 서버 부팅 속도가 빠르다.
초기화가 필요한 서블릿이 많거나 무거운 작업을 포함할 때 효과적
불필요한 초기화 방지
요청이 없는 서블릿은 초기화되지 않으므로, 메모리와 CPU 자원을 절약할 수 있다.
테스트 단계에서 사용되지 않는 서블릿이 초기화되는 일을 방지
단점
첫 요청의 지연
첫 요청 시 서블릿 객체 생성 및 초기화가 동시에 이루어지므로 응답 시간이 길어질 수 있다.
초기화 작업이 오래 걸릴 경우 사용자 경험이 저하된다.
초기화 실패의 위험
첫 요청 시 초기화에 실패하면 해당 요청에 대한 처리가 실패로 끝날 수 있다.
이는 요청이 많이 몰리는 시점에서 장애를 유발할 가능성을 증진시킨다.
적합한 상황
서버 부팅 시간이 중요한 환경. (Auto Scaling)
서블릿이 드물게 사용되거나, 특정 요청에서만 호출되는 경우
서버 시작 시 초기화(Eager Initialization)
특정 서블릿을 서버 시작 시 미리 초기화하도록 설정할 수 있다.
이를 위해서
@webservlet
어노테이션이나web.xml
파일에서load-on-startup
설정을 사용한다.load-on-startup
이 양의 정수 값이면, 서블릿 컨테이너가 서버를 시작할 때 해당 서블릿을 미리 초기화하려 한다.숫자가 클수록 초기화 우선순위가 낮아진다.
장점
첫 요청 응답 시간 단축
서버가 시작될 때 서블릿이 미리 초기화되므로, 첫 요청 시 지연이 없다.
초기화 작업이 복잡하거나 오래 걸리는 경우 사용자 경험 개선
안정성 증가
서버 시작 시 초기화 오류를 확인하고 조치 가능
초기화 실패 시 서버 시작 단계에서 로그 확인 및 수정 가능
예상 가능한 성능
초기화 작업이 서버 시작 단계에서 완료되므로, 요청 처리 중 예상 못한 작업 지연을 방지
단점
서버 시작 시간 증가
모든 서블릿을 미리 초기화하므로, 초기화 작업이 많거나 무거운 경우, 서버 시작 속도가 느려질 수 있다.
리소스 낭비 가능성
요청이 오지 않는 서블릿도 초기화되므로, 불필요하게 메모리와 CPU 를 사용할 수 있다.
특히 많은 서블릿이 배포되어 있지만, 일부만 사용된다면 비효율적
자주 사용되지 않는 서블릿은
load-on-startup
을 꺼두는 것이 맞다.
적합한 상황
자주 호출되거나 중요도가 높은 서블릿.
초기화 작업이 길고, 첫 요청 지연이 사용자 경험에 큰 영향을 주는 경우.
2. 갑자기 트래픽이 피크를 칠 때 서버 로딩타임이 길다면? (Eager Initialization)
서버 상황
현재 갑자기 트래픽이 피크를 쳐서 서버 증설이 이루어지는 상황이다.
문제 상황
서버 증설 및 Auto Scaling 이 느려지는 환경
서버 부팅 시 Eager Initialization 으로 모든 서블릿 및 관련 리소스를 초기화하면, 새로운 서버가 준비되는데 시간이 오래 걸린다. 이로 인해 트래픽 증가에 대한 Auto Sacling 반응이 느려질 수 있다.
초기 요청 지연
서버 부팅 시간이 길어진다는 이유는 초기 요청을 받기까지 시간이 오래 걸린다는 것을 의미한다.
로드 밸런서의 부하 증가
초기화가 완료되지 않은 서버가 트래픽을 처리할 준비가 되지 않으면, 로드 밸런서는 기존 서버에 과도한 트래픽을 전달하게 된다. 이로 인해 기존 서버의 부하가 증가하고 성능이 저하될 수 있다.
생각해 볼 부분
위와 같이 고가용성을 요구하는 환경에서는 "서버가 요청을 받을 수 있는 상태로 빠르게 전환되는 것" 이 중요한 요구사항이다.
때문에, 첫 요청 시 초기화 비용을 감수하고서라도 빠르게 서버가 요청 받을 수 있는 상태로 바뀌는 것이 더 중요할 수 있다.
3. 서버 로딩 타임을 줄일 수 있는 방법은?
해결방안
Eager Initailization -> Lazy Initialization 변경
Lazy Initailization 이점
빠른 가용성 확보
서버가 초기화 작업 없이 즉시 요청을 받을 수 있기 때문에, 서버 추가 과정에서의 지연 시간이 줄어든다.
예를 들어, Auto Scailiing 으로 새 인스턴스를 추가할 때 서버가 전체 리소스를 미리 초기화하지 않고 요청을 받을 준비가 된 상태로 부팅할 수 있다.
리소스 효율성
사용되지 않는 리소스를 초기화하지 않으므로 불필요한 리소스 소비를 줄이고, 서비스 부팅 시간을 단축할 수 있다.
초기화 작업이 트래픽 패턴에 따라 분산되므로 CPU, 메모리 등의 리소스 사용이 급격히 치솟는 현상을 완화한다.
확장성과 가용성 강화
Lazy Initailization 을 통해서 일부 요청의 응답이 늦어질 수는 있지만, 동시에 요청을 처리할 수 있는 서버의 수가 늘어나므로 전반적인 서비스 안정성이 강화된다.
첫 요청에서 초기화가 끝난 뒤부터는 해당 서버가 빠르게 트래픽을 처리할 수 있다.
Lazy Initialization 과 고가용성의 트레이드오프
Lazy Initialization은 가용성을 우선시하며, 초기화 시간으로 인해 발생할 수 있는 첫 요청의 느린 응답을 일부 요청의 희생으로 감수하는 접근 방식이다.
만약 첫 요청의 응답 시간이 중요한 환경이라면 Lazy Initialization 이 적합하지 않을 수 있다.
4. 서블릿 초기화 설정 가이드
일반적인 상황
일반적인 운영 반영의 상황에서 반영하는 서버를 내리더라도 운영중인 서버에 부하가 많지 않다는 것을 가정!
사용자 경험 측면에서, 초기화를 통해 응답이 늦어진다는 것이 긍정적인 경험이 아닐 것으로 보여지기 때문에, 초기화 비용이 많이 드는 서블릿에 대해서는 Eager Initialization 을 사용
스케일 업 상황
스케일 업 상황에서는 올라가는 서버가 요청을 받을 수 있는 상태로 변하는 것이 가장 중요하다.
때문에, 초기화 비용을 감수하더라도 Lazy Initialization 을 통해서 빠르게 서버가 올라가는 것이 좋다.
5. 서블릿이 차지하는 메모리 비용을 예측할 수 있을까?
서블릿들이 차지하는 메모리 비용은 서블릿 자체의 객체 크기뿐 아니라 서블릿 초기화 시 생성하는 리소스들(예 : DB 연결, 캐시, 객체 풀 등) 의 메모리 사용량에 따라 달라진다.
따라서 정확한 비용을 예측하려면 여러 요소를 고려해야 한다..
6. 서비스를 좀 더 내 마음대로 모니터링 할 수 있게 하려면?
ServletContextListener
를 사용해보자.Spring Interceptor 와 비슷한 기능을 수행한다.
6-1. ServletContextListener
ServletContextListener 란?
웹 컨테이너는 웹 어플리케이션이 시작, 종료 되는 시점에 특정 클래스의 메서드를 실행할 수 있는 기능을 제공한다.
이 기능을 통해 웹 어플리케이션 시 필요한 초기화 작업 또는 종료된 후 사용된 자원을 반환하는 작업 등을 수행
7. URL 매핑에 들어가는 비용은?
정확하게 찾기가 어렵다 ..
Last updated