본문 바로가기

연재작/DevOps

Producer - Consumer 패턴

프로그래밍을 공부하다 보면 Producer와 Consumer라는 단어가 참 많이 보인다.

그렇다면 Producer와 Consumer가 무엇이길래 이렇게 많이 등장하는 것일까?

Producer - Consumer 패턴에 대해 알아보자.

 

1. Producer and Consumer Problem

"The producer and consumer problem is one of the small collection of standard, well-known problems in concurrent programming. A finite-size buffer and two classes of threads, producers and consumers, put items into the buffer (producers) and take items out of the buffer (consumers)."

 

생산자 소비자 문제는 기본적으로 동시성 문제를 해결하기 위한 문제의 유형이다.
하지만 이를 해결하기 위한 디자인 패턴으로 불리기도 하다.

유한 사이즈의 buffer를 설정하고, 요청을 해결하기 위한 스레드를 다루는 두 개의 클래스를 생산자와 소비자로 정의한다.

생산자는 buffer에 item들을 올려놓고, 소비자가 buffer에 올려져있는 내용들을 순서대로 처리한다.

 

 

1.5 Event Queue 패턴

생산자 - 소비자 문제를 해결하는 문제 중 위의 buffer의 사용이 바로 Event Queue 패턴을 사용하는 것이다.

Queue는 선입 선출 방식의 자료구조로,

이를 사용해서 동시적으로 발생한 문제들을 이 Event Queue에 집어넣는 방식으로 프로그래밍의 동시성 문제를 해결한다.

 

 

2. Producer - Consumer 패턴의 예시

  • Event Loop : Web Browser나 Node.js의 웹 서버에서 비동기 처리를 위해서 사용하는 이벤트 루프가 생산자 - 소비자 패턴의 대표적인 예시이다.
    • 웹 브라우저와 Node.js는 비동기 작업을 처리할 때 싱글 스레드인 Event Loop를 Consumer로 사용한다.
    • Producer는 Task Queue(Node.js의 경우 event queue)에 이벤트와 작업을 적재한다.
    • Event Loop가 큐에서 이벤트를 하나씩 꺼내 Web Worker(웹 브라우저) 또는 LIBUV(Node.js)에서 해당 작업을 비동기적으로 처리하도록 하는 Consumer가 된다.
      (다시 말해, Event Loop 자체는 싱글 스레드로 사용되지만, Web Worker와 LIBUV를 통해서 멀티스레드를 통한 비동기 작업을 진행하는 것이다.)
  • 메시지 큐 시스템
    • RabbitMQ, Kafka와 같은 메시지 큐 시스템이 생산자 소비자 패턴이다.
      • 생산자는 작업을 메시지 큐에 넣고, 소비자가 큐에서 작업을 꺼내 비동기로 처리한다.
      • 주문 생성 작업을 큐에 넣어서 생산하고, 워커들이 이를 처리하여 결제, 배송처리를 진행한다.

Kafka의 아키텍쳐. 생산자 - 소비자 패턴을 사용한다.

 

2.5 API GW는 Producer Consumer 패턴을 사용하는 것은 아니다.

 

API GW와 같은 경우, 설명하는 부분중에 가끔 Producer, Consumer의 개념으로 접근하는게 있지만

해당하는 역할이 그런 것일 뿐이지 실제로 생산자 - 소비자 패턴을 사용하지는 않는다.

 

생산자 - 소비자 패턴과의 다른 점은

생산자 - 소비자 패턴은 간접적으로 생산자가 소비자를 지정하지만,

API GW는 생산자인 API GW가 직접적으로 소비자(서비스, 혹은 클러스터)를 지정한다.

 

또한, 생산자 - 소비자 패턴은 큐에 담는 과정을 가지게 되어 동시성 문제를 해결할 수 있지만,

API GW는 직접 처리 모델이기 때문에 동시성 문제에 대한 해결책을 가지지는 못한다.

 

 

 

3. Publisher - Subscriber 패턴?

비슷하게 생산 - 소비를 지정하는 이름을 가진 형태의 패턴으로는 pub-sub 패턴이 있다.

이벤트 시스템에서 사용하는 패턴으로, 발행자가 이벤트를 발행하고,

이를 구독한 모든 구독자에게 전달하는 구조를 갖는다.

생산자 - 소비자 문제와는 다르게 발행자와 구독자가 직접적으로 연결되지 않는다.

 

pub - sub 패턴의 경우, 대표적인 예시로는 위에서 잠깐 언급한 Web worker 가 있다.

Web worker에서 postMessage와 onMessage를 사용하는 방식이 Pub/Sub 패턴과 유사하다.

메인 스레드와 웹 워커가 서로 메시지를 발행하고 구독하여 데이터를 주고 받기 때문이다.

 

웹 소켓 기반의 알림 시스템 또한 이와 같은 패턴을 사용해 실시간으로 데이터를 전달할 수 있어

사용자 경험을 향상시킨다. (채팅 어플리케이션, 주식 거래 어플리케이션, 스포츠 경기 실시간 스코어 전송 등)