서블릿은 요청당 스레드: 멀티스레딩과 웹 애플리케이션

허진혁·2023년 8월 15일
2

🤔 글을 작성한 이유

웹 애플리케이션을 개발하면서 서버 측에서 동시에 여러 요청을 처리해야 하는 상황을 자주 마주하게 돼요. 이런 상황에서 서블릿의 멀티스레딩 관련 특성이 중요한 역할을 하게 되는데 자주 접했던 문구인 "서블릿은 요청당 스레드"라는 개념을 통해 서블릿과 멀티스레딩이 어떻게 웹 애플리케이션 개발에 영향을 미치는지 살피려고 해요.

🧐 서블릿과 멀티스레딩의 관계 이해하기

웹 애플리케이션을 개발하다보면 여러 사용자의 요청을 동시에 처리해야 하는 상황을 고려해야 해요. 이때 서블릿과 멀티스레딩이 어떤 관계를 가지며 어떻게 함께 작용하는지 알아보려 해요.

서블릿 역할과 웹 애플리케이션의 작동 방식

서블릿은 Java 기반의 웹 프로그래밍에서 사용되는 중요한 개념이에요.

저는 서블릿을 웹과 요청, 응답을 할 때 동적 처리가 가능한 자바 프로그램 으로 이해하면 편한 것 같아요.

서블릿은 웹 애플리케이션 서버 상에서 실행되며, 클라이언트(일반적으로 웹 브라우저)의 요청에 응답하는 역할을 해요. 사용자가 웹 브라우저를 통해 특정 URL에 접근하면, 서블릿 컨테이너가 해당 URL과 연결된 서블릿을 실행하여 요청을 처리하고 그에 따른 응답을 생성해요.

멀티스레딩의 개념과 여러 스레드가 동시에 실행되는 방식

멀티스레딩은 하나의 프로그램 내에서 여러 개의 스레드가 동시에 실행되는 개념을 의미해요. 여기서 스레드는 실행의 기본 단위로, 각각 독립적으로 실행되는 경량 프로세스라고 간략히 정의할게요. 멀티스레딩을 사용하면 여러 작업을 병렬적으로 처리할 수 있어 시스템의 성능을 향상시킬 수 있어요.

[토비의 스프링 부트 이해와 원리]

웹 애플리케이션에서 서블릿이 멀티스레딩과 연관되는 이유는 웹 서버가 동시에 여러 클라이언트 요청을 처리해야 하기 때문이에요. 많은 사용자가 동시에 웹 페이지를 요청하면 서버는 이를 병렬적으로 처리하기 위해 각각의 요청마다 새로운 스레드를 생성해요. 이렇게 생성된 스레드는 각각의 클라이언트 요청을 독립적으로 처리하며, 서블릿의 로직을 실행하는 구조에요.

서블릿이 요청당 스레드인 이유

서블릿은 요청당 스레드” 란 간단히 말하면, 각각의 클라이언트 요청이 들어올 때마다 서블릿 컨테이너가 새로운 스레드를 생성하여 해당 요청을 처리하는 방식이에요.

서블릿 컨테이너의 스레드 풀을 통한 요청 처리 방식

서블릿 컨테이너는 일종의 웹 서버의 역할을 수행하며, 클라이언트의 요청을 받아 해당 요청을 처리하는 서블릿을 실행해요. 이때 서블릿 컨테이너는 미리 스레드 풀을 준비해두고, 클라이언트 요청이 들어오면 해당 스레드 풀에서 빈 스레드를 가져와 해당 요청을 처리해요. 이 스레드 풀을 통해 스레드 생성 및 소멸의 오버헤드를 줄일 수 있어 성능과 자원 관리가 개선되지요.

서블릿 인스턴스의 상태 공유 문제와 동시성 관리 어려움

"요청당 스레드” 모델은 각 요청마다 별도의 스레드를 사용하므로, 서블릿 인스턴스는 여러 스레드에서 동시에 접근할 수 있어요. 그래서 상태 공유와 관련된 문제를 고려해야 해요.
서블릿 인스턴스 내부의 상태를 동시에 변경하려면 동기화나 thread-safe한 자료구조를 활용하는 방법이 있어요.
또한, 여러 스레드가 동시에 실행되기 때문에 동시성 관리도 무시할 수 없어요. 잘못된 동시성 처리는 예기치 않은 버그나 문제를 야기하게 되기 때문이죠.

⛄︎ 서블릿 스레딩 모델의 장단점

다음과 같은 장점이 있어요.

  1. 개발에만 집중

서블릿은 개발자가 웹 애플리케이션의 핵심 비즈니스 로직에 집중할 수 있는 환경을 만들어줘요. 멀티스레딩은 서블릿 컨테이너에서 자동으로 관리되며, 특수한 상황이 아니라면 개발자가 별도로 스레드 관리에 신경 쓸 필요가 없어요.

  1. 상태 관리 용이성

각각의 스레드는 독립적으로 실행되므로 각 요청마다 서로 다른 상태를 유지해요. 이는 사용자 간의 분리된 세션 관리와 같은 상태 관리를 용이하게 만들어요.

개발자는 서블릿을 직접 관리하지 않아도 되고, 개발에만 집중할 수 있는 환경에서 일을 하기에 개발 효율성이 높아져요.

하지만 다음과 같은 단점도 있어요.

  1. 공유 자원 관리 어려움

여러 스레드가 동시에 실행되는 환경에서 공유 자원(예: 변수, 객체 등)에 접근할 때 동기화 문제가 발생할 수 있어요. 적절한 동기화 없이 공유 자원을 수정하면 예측할 수 없는 끔찍한 결과가 발생할 수 있어요.

  1. 블로킹 및 성능 문제

하나의 스레드가 블로킹되거나 시간이 오래 걸리는 작업을 수행하는 경우, 이로 인해 해당 스레드가 다른 요청을 처리하는데 시간이 많이 소요될 수 있어요. 이는 전체 웹 애플리케이션의 응답성과 성능을 저하시키는 요인이니 주의해야 해요.

멀티스레딩에서의 주의사항과 해결책

멀티스레딩 환경에서 작업을 효율적으로 처리하기 위해서는 스레드 안전성 및 블로킹 문제와 같은 동시성 관련 주의사항을 어떻게 해결할 수 있는지 알아보아요.

❗️ 주의사항: 스레드 안전성 및 블로킹 문제

  1. 경쟁 조건 (Race Condition): 여러 스레드가 동시에 공유 자원에 접근하여 수정하는 경우 데이터 일관성 문제가 발생해요.
  2. 데드락 (Deadlock): 두 개 이상의 스레드가 서로의 작업이 완료될 때까지 대기하며 무한정 블로킹되는 상황이 발생할 수 있어요.

☀︎ 해결책: 동기화, 비동기 처리, 스레드 풀 관리

  1. 비동기 처리 (Asynchronous Processing): 블로킹 작업을 비동기적으로 처리하여 스레드가 대기하지 않도록 하는 방식이에요. 콜백 함수나 이벤트 기반의 처리 방식을 활용하여 효율적으로 작업을 처리하는 거에요.
  2. 스레드 풀 관리: 각 요청마다 스레드를 생성하고 소멸하는 과정은 오버헤드를 발생시키며, 큰 규모의 웹 애플리케이션에서는 스레드 생성 비용이 증가하여 성능 저하를 야기할 수 있어요. 그래서 스레드 풀을 사용하여 스레드 생성 및 관리를 효율적으로 수행해야 해요. 스레드 풀 크기를 적절히 설정하고, 작업을 병렬적으로 처리하여 블로킹 문제를 최소화하는 방식을 고려해야 해요.
  3. 락 (Lock) 사용 최소화: 락은 동기화 문제를 해결하는 데 사용되지만, 과도한 락 사용은 성능 저하를 야기해요. 따라서 락 사용을 최소화하고 락의 범위를 최소한으로 좁히는 것이 중요해요.
  4. 데드락 회피: 데드락을 회피하기 위해 교착 상태가 발생하지 않도록 스레드들의 작업 순서나 우선순위를 조절하는 방안이에요.
  5. 스레드 안전한 자료구조 사용: thread-safe한 컬렉션을 사용하여 데이터 일관성 문제를 방지할 수 있어요.
  6. 모니터링 및 성능 최적화: 스레드 풀의 동작 상태를 모니터링하고 성능을 최적화하기 위해 필요한 조치를 취해요.

참고자료

ServletContainer와 SpringContainer는 무엇이 다른가?
타미의 Servlet vs Spring
코기의 Servlet vs Spring
스프링 입문을 위한 자바 객체지향의 원리와 이해
최범균의 JSP 2.3 웹 프로그래밍: 기초부터 중급까지

profile
Don't ever say it's over if I'm breathing

1개의 댓글

comment-user-thumbnail
2023년 8월 20일

너무 좋은 글이네요!

답글 달기