[Go To Learn 2기 1주차] 애플리케이션의 개발 과정에서 stateless, stateful 이해하기

Juppi·2025년 3월 19일
0

해당 글은 K-DEVCON에서 진행하는 고투런 2기 멘토링 세션에서 학습 내용을 바탕으로 정리한 글입니다.

State 이해하기

애플리케이션에서 ‘상태(State)’란 특정 시점에서 시스템이나 애플리케이션이 가지고 있는 조건, 데이터 또는 특성을 의미한다. 간단히 말하면, 클라이언트와 서버가 서로 소통하면서 유지하고 공유하는 정보를 나타낸다고 볼 수 있다. 보통 시스템이 stateful인지 stateless인지는 클라이언트와 서버 간 상호작용을 얼마나 오래 유지하고, 이를 어떻게 관리하고 저장하는지에 따라 구분된다.

Stateful 애플리케이션은 사용자 또는 시스템과의 상호작용에 대한 ‘맥락(Context)’을 유지한다. 이 상태 정보는 메모리나 데이터베이스(DB)와 같은 다양한 저장소에 저장되기 때문에, 애플리케이션이 재시작되거나 장애가 발생한 후에도 상태를 유지하고 복구할 수 있는 장점이 있다.

이와 반대로, Stateless 애플리케이션은 상태 정보를 서버에 저장하지 않는다. 각 요청은 독립적으로 처리되며 이전 요청과는 아무런 연관성이 없다. 따라서 서버가 재시작되더라도 별도의 복구 과정 없이 즉시 서비스를 제공할 수 있다.

결과적으로, stateful과 stateless의 차이는 상태 정보를 얼마나 유지하고 관리하는지에 따라 결정되며, 각 방식은 상황에 따라 서로 다른 장점과 한계를 가진다.

Stateful Application 이해하기

우리가 흔히 말하는 'stateful(상태 저장)'이란 개념은 클라이언트와 서버 간에 주고받는 정보를 기억하고 유지한다는 뜻이다. 즉, 한 번의 요청과 응답이 끝나고 나서도, 이전에 클라이언트와 나눈 대화의 맥락을 서버가 기억하고 있다는 의미다.

예를 들어, 온라인 쇼핑몰에서 장바구니에 상품을 담았다고 생각해보자. 이때 쇼핑몰 서버는 우리가 장바구니에 어떤 상품을 담았는지 상태를 저장해두고, 다음 요청(예를 들어 결제 단계로 넘어가는 요청)을 받을 때 이 정보를 활용한다. 이렇게 서버는 각각의 클라이언트와 나눈 세션(session)을 추적하며, 이전의 행동이나 요청을 바탕으로 알맞은 응답을 제공할 수 있다.

stateful한 서버는 이전 요청의 맥락에 따라 현재 요청의 응답이 달라질 수 있다는 특징이 있다. 같은 요청이라도 사용자가 과거에 어떤 행동을 했느냐에 따라 완전히 다른 결과를 얻을 수도 있는 것이다. 장바구니의 예시로 돌아가면, 같은 '결제 요청'이라도 담아둔 상품이 다르면 서로 다른 결과(다른 결제 금액이나 상품 정보)를 서버가 반환하게 된다.

또한, 상태 저장 트랜잭션의 큰 장점 중 하나는 트랜잭션이 중단되어도 과거의 컨텍스트와 기록이 저장되어 있기 때문에, 다시 연결하거나 작업을 재개할 때 중단된 지점에서부터 자연스럽게 다시 시작할 수 있다는 점이다.

이러한 개념은 꼭 클라이언트-서버 구조에만 국한되지 않는다. 시스템이 일련의 과정을 기억하고, 이전의 작업 내용을 바탕으로 다음 작업을 수행하거나 결과를 도출할 수 있다면 그것도 stateful하다고 할 수 있다. 결국 stateful하다는 것은 시스템이 '기억력'을 가지고 있다는 것과 같다.

이전 상태(일련의 대화, 상호작용 내용)를 기억하고 있기 때문에, 트랜잭션 처리가 빨라서 사용자에게 빠른 응답을 제공할 수 있지만, 시스템이 복잡해질 수 있다는 단점을 가지고 있다. 하지만 그럼에도 불구하고, 여전히 게임 업계 등에서는 높은 응답성을 위해 stateful 구조를 많이 채택하고 있다.

Stateful 애플리케이션에서 상태를 저장하는 다양한 방법 🛠️

  • 세션(Session): 서버 메모리나 데이터베이스에 세션 데이터를 저장하여 사용자의 상태를 추적하는 방법
  • 쿠키(Cookie): 클라이언트 측에 작은 데이터를 저장하고 서버가 이를 읽어 상태를 유지하는 방법
  • 데이터베이스(Database): 사용자 정보를 데이터베이스에 저장하고 필요할 때마다 조회하는 방식
  • 캐싱(Caching): 자주 사용하는 데이터를 캐시에 저장하여 빠르게 접근할 수 있도록 하는 방식

Stateless Application 이해하기

반대로 stateless 애플리케이션은 클라이언트와의 이전 상호작용을 기억하거나 유지하지 않는다. 즉, 모든 요청은 독립적이고, 이전의 요청과 상관없이 처리된다. 클라이언트가 보내는 모든 요청에 필요한 정보가 전부 포함되어 있어야 하며, 서버는 이 정보만으로 응답을 생성한다.

예를 들어, 웹사이트에서 특정 페이지를 조회할 때, 서버는 이전 요청의 내용을 기억하지 않고, 매번 페이지 요청 시 동일한 결과를 제공한다. 이로 인해 서버가 간단해지고, 확장성이 뛰어나 여러 서버로 분산 처리할 때 유리하다.

Stateless 애플리케이션은 서버가 클라이언트와의 이전 상호작용이나 상태를 저장하지 않는다는 특징을 가진다. 즉, 서버는 각 요청을 독립적인 작업으로 간주하며, 이전 요청의 맥락이나 데이터를 유지하지 않고 매번 새롭게 처리한다.

대표적인 예로는 RESTful API가 있다. RESTful API에서는 클라이언트가 요청할 때 필요한 모든 정보를 함께 전달해야 하며, 서버는 이를 기반으로 매번 독립적인 응답을 생성한다. 이렇게 되면 서버의 부담이 줄어들고, 확장성과 병렬성이 좋아진다. 클라이언트 요청을 처리할 때 다른 서버가 요청을 받아도 동일한 결과를 반환할 수 있게 되어, 여러 서버 간 로드 밸런싱(부하 분산)이 용이하다.

또한, Stateless 애플리케이션은 장애 복구에 매우 강력한 장점이 있다. 서버가 아무런 상태도 저장하지 않으므로, 서버가 갑자기 장애를 일으켜도 다른 서버에서 즉시 처리를 이어갈 수 있다. 이는 서비스의 가용성을 높이는 데 큰 역할을 하며, 대규모 서비스에서 특히 중요하다.

하지만 Stateless 방식에도 단점이 존재한다. 서버가 상태를 기억하지 않기 때문에 매 요청마다 클라이언트가 상태 정보를 모두 전달해야 하며, 네트워크 대역폭이나 요청 크기가 커질 수 있다는 문제가 있다. 이를 보완하기 위해 보통 토큰 기반의 인증(JWT 등)이나 클라이언트 측의 상태 관리(쿠키, 로컬스토리지 등)를 함께 활용하게 된다 🚀

네트워크 프로토콜 관점에서 Stateful과 Stateless 이해하기

일반적으로 네트워크 프로토콜 관점에서 HTTP는 'stateless(상태 비저장)'로, TCP/IP는 'stateful(상태 저장)'로 표현한다. 그 이유는 다음과 같다.

  • HTTP는 각 요청이 독립적으로 처리되어, 이전 요청과의 연관성이나 상태를 기억하지 않는다. 즉, 클라이언트가 매번 요청할 때마다 필요한 모든 정보를 포함해야 하므로 stateless라고 표현된다.
  • 반면에 TCP/IP는 연결 지향(connection-oriented) 프로토콜로, 클라이언트와 서버 간 연결 상태를 유지하기 위해 3-way handshake와 같은 절차를 통해 연결 상태 정보를 유지한다. 이러한 연결 상태를 추적하고 유지하기 때문에 stateful이라고 표현하는 것이다.

각 개별 패킷이나 세션 자체가 이전 상태 정보를 반드시 가지고 있지는 않으며, 상태 정보는 연결을 관리하는 프로토콜 차원에서만 유지된다. 즉, 개별 데이터 패킷은 독립적이기 때문에 stateless이지만, TCP/IP 프로토콜이 전체적인 연결 상태를 관리하고 있으므로 프로토콜 전체 관점에서는 stateful하다고 보는 것이 적절하다.

UDP는 연결을 설정하거나 기다리지 않고, 단순히 패킷을 보내고 이를 잊어버리기 때문에 stateless한 프로토콜이며, 왕복 통신을 유지하고 전송상태를 추적해야하는 FTP, SMTP 등은 stateful 프로토콜이다.

계층(Layer)에 따른 Stateful/Stateless의 차이 이해하기

Stateful과 Stateless는 어떤 계층에서 바라보느냐에 따라 그 의미가 달라질 수 있다. 예를 들어, 어플리케이션 수준에서 보면 HTTP 프로토콜은 명백히 stateless이다. 즉, 각 HTTP 요청은 이전 요청의 상태나 결과에 영향을 받지 않으며 독립적으로 처리된다.

하지만 네트워크 레이어로 내려가서 보면 이야기가 달라질 수 있다. HTTP의 버전이나 Keep-Alive(지속 연결)의 사용 여부에 따라 상태 정보를 어느 정도 유지할 수도 있다. 예를 들어, HTTP/1.1에서의 Keep-Alive는 연결을 종료하지 않고 유지함으로써 같은 TCP 연결 위에서 여러 요청을 처리할 수 있게 한다. 이러한 지속적인 연결 관리의 관점에서는 HTTP 역시 버전 및 keep-Alive 사용 여부에 따라부분적으로 stateful하게 볼 수도 있다.

실제 사례를 통해 이벤트 소싱 패턴 뜯어보기 !

작성예정….

reference

https://medium.com/@sdjblogger/the-concept-of-state-in-protocols-stateful-vs-stateless-cead0423d4ee

https://www.redhat.com/en/topics/cloud-native-apps/stateful-vs-stateless

0개의 댓글