멀티스레드 환경에서 Servlet 사용

2026. 2. 6. 13:12·Backend/Servlet

 

Tomcat은 멀티스레드 서버다

Tomcat은 멀티스레드 기반 서버다.
즉, 여러 사용자가 동시에 요청을 보내면 Tomcat은 다음과 같이 동작한다.

  • 요청 하나당 스레드 하나를 할당한다
  • 여러 스레드가 동시에 실행된다
  • 같은 Servlet 인스턴스를 공유한다

이 구조를 정확히 이해하지 못하면
Servlet에서 의도하지 않은 버그가 발생한다.

 

 

Servlet 인스턴스는 몇 개가 생성되는가

Servlet은 요청마다 새로 생성되지 않는다.

  • Tomcat이 시작될 때
  • Servlet 클래스당 인스턴스 1개를 생성한다
  • 이후 모든 요청은 이 인스턴스를 재사용한다

즉 구조는 다음과 같다.

  • Servlet 인스턴스: 1개
  • 요청 처리 스레드: 여러 개
  • 여러 스레드가 같은 객체를 동시에 사용한다

이 점이 멀티스레드 문제의 출발점이다.

 

 

요청이 들어왔을 때 내부 동작 흐름

클라이언트가 요청을 보내면 Tomcat 내부에서는 다음 순서가 실행된다.

  1. 클라이언트가 HTTP 요청을 보낸다
  2. Tomcat이 요청을 수신한다
  3. 요청 하나당 스레드를 하나 생성한다
  4. request 객체와 response 객체를 생성한다
  5. 같은 Servlet 인스턴스의 service() 메서드를 호출한다
  6. HTTP 메서드에 따라 doGet() 또는 doPost()가 실행된다

여기서 핵심은 다음이다.

여러 스레드가 동시에 하나의 Servlet 객체에 진입한다

 

 

 

Servlet 필드에 상태 값을 저장하면 왜 문제가 되는가

Servlet 클래스에 다음과 같은 필드가 있다고 가정한다.

public class UserServlet extends HttpServlet {
    private String userId;
}

이 필드는 Servlet 인스턴스의 상태다.
즉, 모든 요청이 이 변수를 공유한다.

실제로 발생하는 문제

  • 사용자 A 요청 → userId = "A"
  • 거의 동시에 사용자 B 요청 → userId = "B"
  • 사용자 A의 응답을 만드는 도중 값이 바뀐다
  • 사용자 A가 B의 정보로 처리되는 상황이 발생한다

이 문제는 다음 조건이 동시에 만족될 때 발생한다.

  • Servlet 인스턴스가 하나다
  • 멀티스레드 환경이다
  • 인스턴스 필드에 요청별 상태를 저장했다

그래서 Servlet 필드에 상태를 저장하면 안 된다.

 

 

지역 변수는 왜 안전한가

반면 다음과 같은 코드는 안전하다.

protected void doGet(HttpServletRequest request, HttpServletResponse response) {
    String userId = request.getParameter("userId");
}

이유는 명확하다.

  • 지역 변수는 스택 영역에 생성된다
  • 스레드마다 스택이 분리된다
  • 다른 스레드가 접근할 수 없다

즉,

  • 인스턴스 변수 → 공유됨 → 위험
  • 지역 변수 → 요청 단위 → 안전

이다.

 

 

static 변수는 더 위험하다

static 변수는 Servlet 인스턴스보다도 더 넓은 범위에서 공유된다.

  • 클래스 로딩 시 한 번 생성된다
  • JVM 전체에서 하나만 존재한다
  • 모든 Servlet 인스턴스, 모든 스레드가 공유한다

즉 static에 요청 상태를 저장하면 다음과 같은 문제가 발생한다.

  • 모든 사용자 정보가 섞인다
  • 테스트 환경에서는 잘 되는 것처럼 보인다
  • 실제 트래픽이 늘면 즉시 사고가 난다

그래서 Servlet에서는 다음 원칙이 있다.

static 필드에는 절대 요청 상태를 저장하지 않는다

 

 

 

디버깅이 어려운 이유

이 문제의 가장 큰 특징은 다음과 같다.

  • 항상 발생하지 않는다
  • 트래픽이 적을 때는 안 터진다
  • 동시에 요청이 들어올 때만 발생한다
  • 재현이 매우 어렵다

그래서 이런 버그는 흔히 다음과 같이 오해된다.

  • “가끔 이상하다”
  • “환경 문제 같다”
  • “서버가 불안정한 것 같다”

하지만 실제 원인은 멀티스레드 + 공유 상태다.

 

 

Servlet에서 반드시 지켜야 할 원칙

멀티스레드 환경에서 Servlet을 안전하게 사용하려면 다음 원칙을 지켜야 한다.

  • 요청 데이터는 지역 변수로만 처리한다
  • Servlet 인스턴스 필드에 상태를 두지 않는다
  • static 필드에 요청 데이터를 저장하지 않는다
  • 공유 자원이 필요하다면 동기화 전략을 명확히 한다

 

'Backend > Servlet' 카테고리의 다른 글

서블릿이 생성되고 요청이 처리되는 전체 흐름  (0) 2026.02.08
forward와 JSP 실행 흐름  (0) 2026.02.06
Servlet Container와 Servlet의 관계  (0) 2026.02.05
RequestMapping static Map은 괜찮은 이유  (0) 2026.02.05
서블릿에서의 static  (0) 2026.02.05
'Backend/Servlet' 카테고리의 다른 글
  • 서블릿이 생성되고 요청이 처리되는 전체 흐름
  • forward와 JSP 실행 흐름
  • Servlet Container와 Servlet의 관계
  • RequestMapping static Map은 괜찮은 이유
sqaxe1
sqaxe1
woojoo-devlog 님의 블로그 입니다.
  • sqaxe1
    Woojoo's Devlog
    sqaxe1
  • 전체
    오늘
    어제
    • 분류 전체보기 (148)
      • Backend (9)
        • Servlet (7)
        • Spring (2)
      • Frontend (1)
      • CS (0)
      • Book (33)
        • 자바 웹 프로그래밍 Next Step (30)
        • 테스트 주도 개발: 고품질 쾌속개발을 위한 TDD.. (1)
        • 성공과 실패를 결정하는 1%의 네트워크 원리 (2)
      • Engineering (0)
        • Testing (0)
      • Infra (6)
        • AWS (6)
      • Java (4)
      • Network (1)
      • 김영한 (28)
        • 자바 입문 (8)
        • 실전 자바 - 기본편 (6)
        • 실전 자바 - 중급편 (10)
        • 실전 자바 - 고급편 (4)
      • Web (39)
        • Web Basics (39)
      • Project (24)
        • NeoSquare (0)
        • Memo Evolution (24)
      • 정보처리기사 (0)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    java
    개발서적
    aws
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.6
sqaxe1
멀티스레드 환경에서 Servlet 사용
상단으로

티스토리툴바