발행-구독 패턴은 비동기 메시징 패러다임이다. 

발행자와 구독자가 있고 그 사이에 브로커(이벤트버스)가 존재한다. 

 

브로커(이벤트버스)는 발행자와 구독자 사이에 위치하며 주로 메시지큐가 브로커의 역할을 수행한다.

모든 들어오는 메시지를 필터링하고 다시 메시지들을 구독자에게 배포한다. 

 

발신자의 메시지는 특별한 수신자가 정해져 있지 않다. 대신 발행된 메시지는 정해진 범주에 따라, 각 범주에 대한 구독을 신청한 수신자에게 전달 된다. 수신자는 발행자에 대한 지식이 없어도 원하는 메시지만을 수신할 수 있다. 

 

옵저버 패턴과의 차이점

발행-구독 패턴의 Publisher(발행자)-Subscriber(구독자)의 관계는 옵저버 패턴의 Subject(주제)와 Observer(관찰자)를 떠오르게 한다. 확실히 옵저버 패턴과 상당히 유사하지만, 똑같지는 않다.

 

1. Publisher와 Subscriber 는 서로 몰라도 상관 없다.

옵저버 패턴은 구독을 하고 notify 하는 과정에서 Subject와 Observer의 직접적인 소통이 이루어진다. Subject에서 Observer들의 콜렉션을 돌면서 직접 notify 메소드를 호출하던 것을 떠올리면 된다. 

 

반면 발행-구독 패턴은 발행 객체와 구독 객체 사이에 직접적인 소통을 하지 않아도 된다. 

발행 객체와 구독 객체 사이에 브로커라고 하는 제 3의 구성요소가 소통의 역할을 하기 때문이다. 

 

브로커가 발행 객체와 구독 객체 사이에서 메시지를 필터링 하여 다시 배포하므로, 발행자와 구독자는 서로 알지 못해도 브로커에 의해 소통이 가능하다.

 

2. 발행-구독 패턴이 옵저버 패턴보다 더 낮은 결합도를 가진다. 

발행구독 패턴의 Publisher와 Subscriber는 서로를 몰라도 되고, 옵저버 패턴의 Subject와 Observer는 서로를 알고 있다고 했다. 그러므로 당연히 발행-구독 패턴이 옵저버 패턴보다 더 낮은 결합도를 갖게 되는 것이다.

 

Publisher와 Subscriber가 서로의 존재를 모르니 서로 의존할 일이 전혀 없기 때문이다.

 

3. 옵저버 패턴은 주로 동기적으로 동작하며, 발행-구독 패턴은 비동기적으로 동작하게 된다. 

옵저버 패턴은 주로 동기적으로 구현하고, 발행 구독 패턴은 주로 비동기적으로 구현한다. 

 

4. 옵저버 패턴은 주로 단일 도메인(하나의 애플리케이션)에서 동작하며, 발행-구독 패턴은 크로스 도메인(서로 다른 애플리케이션)에서도 동작이 가능하여 분산 구조에서 주로 사용한다.
옵저버 패턴은 데이터 제공자(Subject)가 Observer를 알고 있어야한다. 그러나 발행-구독 패턴에서 Publisher와 Subscriber가 서로 몰라도 된다. 이러한 차이점 덕분에 Publisher와 Subscriber는 중간의 브로커와 소통할 수 있다면 앱의 도메인이 다르더라도 처리가 가능하다.


Message Que

메시지 큐란?

MOM을 구현한 시스템.

메시지 지향 미들웨어(MOM)은 비동기 메시지를 사용하는 다른 응용 프로그램의 데이터 송수신을 말한다. 

메시지 큐는 프로그래밍에서 프로세스 또는 프로그램 인스턴스가 서로 데이터를 교환할 때 사용하는 방법이다. 

 

MOM은 메시지큐를 포괄하고 있고 메시지큐에는 Kafka, RabbitMQ, ActiveMQ 등이 있다.

 

메시지 큐를 왜 사용하는가?

Message Queueing은 대용량 데이터를 처리하기 위한 배치 작업이나, 채팅 서비스, 비동기 데이터를 처리할 때 사용한다. 프로세스 단위로 처리하는 웹 요청이나 일반적인 프로그램을 만들어서 사용하는데 사용자가 많아지거나 데이터가 많아지면 요청에 대한 응답을 기다리는 수가 증가하다가 나중에는 대기 시간이 지연되어서 서비스가 정상적으로 되지 못하는 상황이 오기 때문에 기존에 분산되어 있던 데이터 처리를 한 곳에 집중하면서 메세지 브로커를 두어서 필요한 프로그램에 작업을 분산시키는 방법을 하는 것이 그 목적이다.

 

- 메시지 큐는 IPC(Inter-Process Communication) 도구 중 하나로, 시스템 프로그래밍에서 사용된다. 

프로세스들 간에 데이터 송수신을 위해 사용하는데, 각 데이터를 메시지 형태로 생성, 전달하고 수신이 가능하게끔 Queue 데이터 구조를 이용한다.

 

- 분산 메시징 시스템에 활용된다.

모니터링, 로그, 이벤트 메시지 등 아주 거대한 양의 데이터를 다룰 일이 생김에 따라 필요하게 된다.

Queue는 여러 컴포넌트들이 데이터를 생성하고 또 저장하고 사용하는 과정에서 일종의 버퍼 역할을 수행한다.

 

이로 인해 Producer와 Consumer간의 속도가 다를 때, 둘 중 어느 한 컴포넌트가 장애가 발생했을 때 상황 등에 대응이 가능하여 장애 전파를 막을 수 있다. 

 

기본적으로 분산 메시징 시스템은 어떤 특정 메시지가 최소한 한 번은 전달될 수 있도록 보장하며 다수의 reader와 writer를 하나의 큐를 통해서 공유하고 상호작용할 수 있게끔 만든다. 

 

장점

- 비동기 : Queue에 넣어두기 때문에 나중에 처리할 수 있다.

- 분리 또는 비동조(Decoupling) : 애플리케이션과 분리할 수 있다.

- 탄력성(Resilience) : 일부가 실패 시 전체에 영향을 받지 않는다.

- 과잉(Redundancy) : 실패할 경우 재실행이 가능하다.

- 보증(Guarantees) : 작업이 처리된 걸 확인할 수 있다.

- 확장성(Scalable) : 다수의 프로세스들이 큐에 메시지를 보낼 수 있다.

 

사용처

 - 다른 곳의 API로 부터 데이터 송수신이 가능하다.
 - 다양한 애플리케이션에서 비동기 통신을 할 수 있다.
 - 이메일 발송 및 문서 업로드가 가능하다.
 - 많은 양의 프로세스들을 처리할 수 있다.

 

 

Reference

https://gobae.tistory.com/122

 

발행-구독 패턴(Publisher-Subscriber Pattern)이란?

이전 글 옵저버 패턴(Observer Pattern)이란? 옵저버 패턴 옵저버 패턴은, 옵저버들의 목록을 객체(관찰하려는 대상)에 등록하여 객체가 상태 변화가 있을 때 마다 메서드 등을 통해 객체가 직접 목록

gobae.tistory.com

https://err0rcode7.github.io/backend/2021/06/19/%EB%A9%94%EC%8B%9C%EC%A7%80-%ED%81%90%EC%99%80-%EC%A2%85%EB%A5%98-%EA%B7%B8%EB%A6%AC%EA%B3%A0-%EB%B9%84%EA%B5%90.html

 

메시지 큐와 종류 그리고 비교

메시지 큐와 종류 그리고 비교

err0rcode7.github.io

https://sugerent.tistory.com/644

 

메시지큐(Message Queue) 알아보기

Ref. https://12bme.tistory.com/176 메시지 큐 개념을 다시 잡아보고자 학습용도로 작성한 포스팅입니다. 출처는 http://zzong.net/post/3 입니다. 메시지 지향 미들웨어(Meesage Oriented Middleware: MOM)은..

sugerent.tistory.com

 

'디자인패턴' 카테고리의 다른 글

옵저버 패턴 (Observer Pattern)  (1) 2022.06.14

옵저버(관찰자) 패턴 정의

옵저버 패턴은 어떠한 주제가 있고, 해당 주제를 관찰하는 관찰자들로 이루어져 있다. 주제의 상태가 바뀌면 관찰자들에게 연락을 하게 되는 일대다(one-to-many, 1:N) 의존성의 디자인 패턴이다.  

ex) 유튜버와 구독자들의 관계.

유튜버가 영상을 등록하면, 구독자들은 알림을 받는다.

 

옵저버 패턴의 구현

하나의 주제(Subject)를 하나의 객체로 표현하고, 관찰자(Observer) 또한 객체로 구현한다. 따라서 Subject 객체의 상태가 변경되면 해당 Subject에 의존하는 모든 Observer 객체들에게 상태가 변경되었음을 알린다. 

 

출처 : https://ko.wikipedia.org/wiki/옵서버_패턴

Subject : 관찰 대상인 '주제' 객체로, 자신을 관찰하는 observer 객체들을 콜렉션으로 갖고 있다. observer 등록, 등록해지, 자신을 관찰하는 모든 observer에게 notify 하는 기능을 갖게 된다. 

Observer : 관찰하는 객체이다. 위 UML에서는 상속구조로 되어있지만, 인터페이스로 만들기도 한다. observer 객체들은 Subject가 notify()를 호출할 때마다 Subject 객체의 상태 변경을 수신하게 된다.

 

 

푸시(Push) 방식의 구현

Subject 객체에서 Observer 객체에게 notify를 할 때, 변경된 데이터를 함께 보내는 방식이다. 

notify 함수의 매개변수로 변경된 데이터가 들어간다. 

 

풀(Pull) 방식의 구현

Subject 객체로부터 notify를 받은 Observer 객체가 변경된 데이터를 직접 가져가는 방식이다. 

Observer 객체마다 관찰하는 데이터가 다를 경우 사용되는 방식이다. notify의 매개변수로 Subject 객체, 혹은 Subject 인터페이스를 받은 후 형변환을 통해 데이터를 빼간다. pull 방식의 구현에는 Subject에 getter 가 구현되어 있어야한다.

 

 

장단점

장점 :

1. 객체간의 관계를 인터페이스를 활용해 느슨한 결합 구조를 만들 수 있다. 

 - 느슨한 결합 구조로 인한 장점은 아래와 같다.

  •  Observer를 언제든 새로 추가, 제거할 수 있다.
  • 새로운 형식의 Observer라 해도 Subject는 변경될 필요가 없다.
  • Subject와 Observer는 서로 독립적으로 재사용할 수 있다.
  • Subject나 Object가 바뀌더라도 서로에게 영향을 미치지 않는다.

2. 한 객체(Subject)의 상태변화를 의존하는 객체(Observer)에서 자동으로 알 수 있다.

4. 런타임에 의존 관계를 생성하거나 삭제할 수 있다.

 

단점 :

1. 순서를 예측할 수 없다. 

Subject 내에서 Observer들을 순회하며 Notify 해주는데, 개별 Observer 입장에서는 자신이 호출되는 순서에 대해서 알 수 없다. 따라서 상태 변경에 따른 어떠한 행위를 할 때, 자신의 순서 앞에서 어떤 옵저버가 어떤 행위를 했는지 알 수가 없다.

 

2. Thread-safe 하지 않다. (스레드 안전 문제)

각각의 옵저버들이 호출하는 함수 체인 속에서 어떤 락을 잡고 있는지 알 수 없기에, 만약 A 옵저버가 a락을 잡고 b락을 잡으려고 하고, B 옵저버는 b락을 잡은 상태로 a락을 잡으려고 하고 있다면(a락을 잡아야 b락이 풀린다면) 터지게 된다.  

 

3. 너무 많이 사용하게 되면 상태 관리가 힘들어진다.

Subject가 너무 많은 상태를 갖고 있게 되면, Subject가 변경될 때마다 Observer들이 호출되는 수가 많아지고, 이에 따라 무언가 작업이 꼬였을 때 현재 상태가 올바른 상태인지에 대한 디버깅이 힘들어진다.

 

Reference

https://hamait.tistory.com/885

 

굿바이~ 옵저버 패턴 and FRP

문제 공유 우리는 오랫 동안 상호작용 되는 많은 부분에 있어서 옵저버패턴을 당연하듯 활용해 왔지만, 옵저버(관찰자, 소비자, 리스너) 패턴을 사용하다보면 경험 많은 개발자라면 누구나 "

hamait.tistory.com

https://im-yeobi.io/posts/design-pattern/observer-pattern/

'디자인패턴' 카테고리의 다른 글

발행-구독 패턴(Publisher-Subscirber Pattern)  (1) 2022.06.14

+ Recent posts