사용자가 웹 애플리케이션에 요청을 날리면, WAS는 아래 그림처럼 서블릿을 호출해 JSON이나 HTML페이지를 만들고 사용자에게 응답을 날립니다.
그럼 서블릿 객체는 누가 호출 할까?
쓰레드는 개발자가 코딩한 내용을 읽고 실제로 일을 수행하는 일꾼에 비유할 수 있습니다.
따라서 쓰레드가 없다면 자바 애플리케이션의 실행은 불가능합니다.
자바 메인 메서드를 처음 실행하면 main이라는 이름의 쓰레드가 순차적으로 일을 수행합니다. 말그대로 순차적으로 일을 수행하기 때문에 여러가지 일을 동시처리하고 싶다면, 쓰레드를 추가로 생성해 주어야 합니다.
웹 애플리케이션에서도 결국 서블릿을 호출해 일을 하는 녀석은 쓰레드 입니다.
사용자의 요청을 받게되면 쓰레드가 할당되고..
이 쓰레드가 서블릿을 호출해 로직을 실행합니다...
웹 애플리케이션에서는 수많은 사용자들이 동시에 요청하는 경우가 많습니다. 이를 동시에 쳐내기 위해 거의 모든 웹 애플리케이션은 프로그램의 일꾼, 쓰레드를 여러개 돌리는 환경 즉 멀티 쓰레드 환경을 취하고있습니다.
만약 쓰레드가 하나만 있다면, 한 사용자가 요청한 작업을 모두 끝내기 전까지는 다른 사용자의 요청을 처리할 수 없어 느리고 답답한 서비스가 될 뿐만 아니라, 쓰레드 하나에 장애가 발생하면 서버 전체가 멈춘다는 약점이있습니다.
한 사용자의 요청을 처리하는 도중 처리 지연이 발생합니다.
(사용자의 입력을 기다린다거나, 오류가 발생해 처리가 멈춘경우 등등)
그러면 다른 사용자의 요청 처리를 시작할 수 없어 서버전체가 다운됩니다.
위 문제를 해결하기 위해 매번 요청이 올 때마다 새로운 쓰레드를 생성하면 어떨까요?
쓰레드1이 처리 지연으로 멈춘 상황에서 또다른 요청이 오더라도 새로운 쓰레드2를 만들어 요청을 처리할 수 있습니다.
이는 동시 요청을 처리할 수 있고, 리소스(CPU, 메모리)가 감당 할 수 있는 수준에서는 무한한 요청을 모두 처리할 수 있습니다.
그러나 쓰레드를 생성하는 비용은 매우 비싸기 때문에 고객이 요청할 때마다 쓰레드를 만들게 되면 응답 속도가 늦어질 수 밖에 없습니다.
또한 쓰레드는 컨텍스트 스위칭 비용이 발생합니다. 따라서 쓰레드가 너무 많아지면 성능 저하 문제가 있습니다.
컨텍스트 스위칭
여러개 쓰레드가 동시에 일을 처리한다고는 하지만, 결국 CPU를 할당받아야 일을 수행할 수 있습니다.
만약 CPU가 한 개 고 쓰레드가 2개일 경우 CPU는 한 쓰레드에 먼저 할당되어 잠시 일을 처리하고 다음 쓰레드로 넘어가 또 잠시 일을 처리하게됩니다.
번갈아가며 조금씩 일을 하는 것 이지요.
이 속도가 너무 빠르기 때문에 우리 눈에는 두 쓰레드가 동시에 일을 하는 것처럼 보이는 것 입니다.
이 CPU 할당을 바꾸는 것을 컨텍스트 스위칭이라고 합니다.
마지막으로 고객 요청이 너무 많아지면 서버 리소스 임계점을 넘어 서버가 죽을 수 있습니다.
위 문제를 해결하기위해, WAS는 쓰레드 풀을 사용합니다.
WAS는 서버가 실행될 때 적정 갯수의 쓰레드를 만들어 쓰레드 풀에 저장하고 관리합니다.
요청이 들어오면 이미 생성되어있는 쓰레드를 쓰레드풀에서 꺼내 사용하고, 종료 하면 다시 반납합니다.
쓰레드가 미리 생성되어 있기 때문에, 쓰레드를 생성하고 삭제하는 비용이 절약되어 응답시간이 빠르다는 장점이있습니다. 또한 생성가능한 쓰레드의 최대치(톰캣은 최대 200개)를 설정할 수 있기 때문에 너무 많은 요청이 들어와도 기존 요청 만큼은 안전하게 처리할 수 있습니다.
개발자는 이 쓰레드 풀의 사이즈를 적절히 설정하는 것이 중요합니다. 이 값이 너무 낮으면 동시 요청이 많을 경우 응답 지연이 발생하고, 너무 높게 설정하면 리소스 임계점 초과로 서버가 다운될 위험이있습니다. 이는 환경마다 모두 다르므로 성능 테스트를 통해 적절한 수를 찾는 것이 중요합니다.