동시 요청 - 멀티 쓰레드

김원종·2023년 11월 23일

웹브라우저든 어떤 클라이언트에서 서버를 요청을 하면 WAS웹 애플리케이션 서브는 응답을 할것이다. 그럼 아래와 같은 그림이 나온다

요청을 하면 TCP,IP 연결이 되고 서블릿이라는것을 호출을 한다!!근데 도대체 저 서블릿객체를 누가 호출을 하는것인가??바로 쓰레드라는것이다.

쓰레드

  • 애플리케이션 코드를 하나하나 순차적으로 실행하는 것은 쓰레드
  • 자바 메인 메서드를 처음 실행하면 main이라는 이름의 쓰레드가 실행
  • 쓰레드가 없다면 자바 애플리케이션 실행이 불가능
  • 쓰레드는 한번에 하나의 코드 라인만 수행
  • 동시 처리가 필요하면 쓰레드를 추가로 생성




쓰레드가 하나만 있다고 가정해보자 ! 요청이 오면 연결 부분에서 쓰레드를 할당을 하고 그 쓰레드를 가지고 서블릿 코드를 실행해주는것이다.그리고 나서 쓰레드를 가지고 응답까지 다 하고 나면 쓰레드는 휴식을 하는것이다. 그렇다면 만약 다중 요청이라면??



만약 1번 요청이 왔는데 처리가 지연이 되는 상황일때 만약 요청2가 들어오면??
2번요청은 대기를 해야하는 상황이 생기는것이다.1번이 쓰레드를 계속 잡고 있으니 2번요청은 아예 수행이 되지 않을것이고 그럼 1번과 2번 모두 오류가 발생할것이다.

그럼 이런식으로 요청이 올때마다 쓰레드를 생성하면 같은 서블릿을 호출하던 아니던 해당하는 서블릿 코드를 실행하고 응답을 줄것이다.이렇게 해도 충분히 잘 동작할것이다 .
하지만 요청마다 쓰레드를 생성하면 무조건 좋은것일까??

요청 마다 쓰레드 생성 장단점

  • 장점
    • 동시 요청을 처리할 수 있다.
    • 리소스(CPU ,메모리 ) 가 허용할 때 까지 처리가능
    • 하나의 쓰레드가 지연 되어도, 나머지 쓰레드는 정상 동작한다.
  • 단점
  • 쓰레드는 생성 비용은 매우 비싸다.
    • 고객의 요청이 올 떄 마다 쓰레드를 생성하면 , 쓰레드 생성 속도가 느린만큼 응답 속도가 늦어진다.
  • 쓰레드는 컨텍스트 스위칭 비용이 발생한다.
    • 컨텍스트 스위칭 - 쓰레드가 하나일때는 상관이 없겠지만 쓰레드는 CPU가 수백개가 있는게 아니기 때문에 코어 수만큼 동시에 돌아갈텐데 만약 코어가 하나고 쓰레드가 두개면 ? 코어하나는 두개의 쓰레드를 동시에 실행할수 없는데 순차적으로 처리하는 속도가 너무 빨라 우리는 동시에 돌아간다고 생각한다.그렇다면 그 두개가 전환이 될때 비용이 발생하는데 그것을 컨텍스트 스위칭이라고 한다.
  • 쓰레드 생성에 제한이 없다.
    • 고객 요청이 너무 많이 오면 , CPU , 메모리 임계점을 넘어서 서버가 죽을 수 있어 서버가 다운 되 버릴수도있다. CPU는 100%치고있고 메모리는 이미 가득차버린 상황에 계속 생성을 하려하면 서버가 죽어버리는것이다.

그럼 위의 문제들을 어떻게 해결을 해야할까??이런걸 해결하기 위해 보통의 WAS는 이런식으로 구성되어있다.

바로 쓰레드 풀 이라는 것을 사용한다.이름 그대로 풀장같은 것이다. 그 안에 쓰레드들이 휴식을 취하다가 요청이 오면 연결부분은 풀안에 있는 쓰레드에게 요청을한다. 풀안에 미리 쓰레드를 만들어 둔 상황이기에 가능하다! 요청이 와서 사용된 쓰레드들은 사라지는게 아니라 다시 풀로 반납이 된다. 빌려쓰고 가져다 놓는 그런 상황인것이다!!

어떤 장점이 있냐!! 만약 우리의 서버가 200개가 한계라고 설정해두었는데 200개보다 더 많은 요청이 오면 쓰레드 풀에 쓰레드가 없는 상황일것이다 . 그럼 쓰레드 풀에서는 대기하거나 또는 거절을 할 수 있다.거절을 하면 설정값이 다 찼다고 거부하고 요청을 다시 뱉어버리고 대기는 마치 맛집에 대기열처럼 순번을 정하고 정해진 수까지는 대기 시킬수있고 대기는 쓰레드가 돌아오면 대기열에 쓰레드를 사용하게한다.

쓰레드풀 요청 마다 쓰레드 생성으 단점 보안

  • 특징
    • 필요한 쓰레드를 쓰레드 풀에 보관하고 관리한다.
    • 쓰레드 풀에 생성 가능한 쓰레드의 최대치를 관리한다. 톰캣은 최대 200개 기본 설정 (변경 가능0)
  • 사용
    • 쓰레드가 필요하면 , 이미 생성되어 있는 쓰레드를 쓰레드 풀에서 꺼내서 사용한다.
    • 사용을 종료하면 쓰레드 풀에 해당 쓰레드를 반납한다.
    • 최대 쓰레드가 모두 사용중이어서 쓰레드 풀에 쓰레드가 없으면?
      • 기다리는 요청은 거절하거나 특정 숫자만큼만 대기하도록 설정할 수 있다.
  • 장점
    • 쓰레드가 미리 생성되어 있으므로, 쓰레드를 생성하고 종료하는 비용(CPU)이 절약되고 , 응답 시간이 빠르다.
    • 생성 가능한 쓰레드의 최대치가 있으므로 너무 많은 요청이 들어와도 기존 요청은 안전하게 처리할 수 있다.

쓰레드 풀 실무팁

  • WAS의 주요 튜닝 포인트는 최대 쓰레드 (max thread)수이다.
  • 이 값을 너무 낮게 설정하면?
    • 동시 요청이 많으면 , 서버 리소스는 여유롭지만,클라이언트는 금방 응답 지연
  • 이 값을 너무 높게 설정하면?
    • 동시 요청이 많으면, CPU,메모리 리소스 임계점 초과로 서버 다운
  • 장애 발생시?
    • 클라우드면 일단 서버부터 늘리고 , 이후에 튜닝
    • 클라우드가 아니면 열심히 튜닝

10개를 설정했는데 만약 100개의 요청이 오면..?10개는 실행되고 90개는 대기하거나 거절하는것이다.그 상황에서 CPU 사용률을 보앗는데 5%만 사용하는것이다. 물론 극단적인 상황이다 . 요청은 계속 쌓이고 그럼 계속 밀리면서 장애가 발생한다.
개발자입장에는 매우 치욕적이다 CPU를 5% 10%만 쓰는것..!! 개발자가 셋팅을 잘못한것이다.
이런경우에 못해도 CPU사용율을 50%는 사용해야한다.그럼 못해도 원래 처리값에 10배는 처리할수있는것이다. 그걸 몰라서 aws인스턴스를 10배로 늘려서 쓰면 돈만 10배로 나가는것이다.

만약 너무 높게잡으면?
동시 요청이 너무 많을때 CPU메모리 리소스가 인계점 초과로 서버가 바로 다운이 되어버린다.
예를 들어 1만개로 하면 만개의 요청을 다받는거고 그럼 서버가 바로 죽는것이다. 죽으면 복구또한 쉽지가않다.

중요한건 적정값을 찾아서 설정해야한다.

쓰레드 풀 쓰레드 풀의 적정 숫자

  • 적정 숫자는 어떻게 찾나요?
  • 애플리케이션 로직의 복잡도, CPU, 메모리 ,IO 리소스 상황에 따라 모두 다름
  • 성능 테스트
    • 최대한 실제 서비스와 유사하게 성능 테스트 시도
    • 툴 : 아파치 ab ,제이미터, nGrinder

WAS의 멀티 쓰레드 지원 핵심

  • 멀티 쓰레드에 대한 부분은 WAS가 처리
  • 개발자가 멀티 쓰레드 관련 코드를 신경쓰지 않아도 됨
  • 개발자는 마치 싱글 쓰레드 프로그래밍을 하듯이 편리하게 소스 코드를 개발
  • 멀티 쓰레드 환경이므로 싱글톤 객체(서블릿,스프링 빈)는 주의해서 사용
profile
개린이

0개의 댓글