발행(publisher) 구독(subscriber) 패턴은 옵저버(Observer) 패턴과 유사한 부분이 많다.
발행-구독 패턴이 무엇인지, 옵저버 패턴과 어떤 차이가 있는지 살펴보자.
발행구독 패턴
발행자와 구독자가 있고 그 사이에 브로커(=메시지 큐)가 존재하는 형태이다.
이것의 특징을 나열하면 아래와 같다.
1. 발행자 메시지의 수신자가 정해져 있지 않다.
2. 메시지는 정해진 범주에 따라서 구독을 신청한 수신자에게 전달이 된다.
3. 수신자는 발행자에 대한 정보 없이 원하는 메시지를 수신할 수 있다.
4. 메시지큐 패러다임과 마치 형제같은 관계로 대형 메시지 지향 미들웨어 솔루션의 일부라고 한다.
발행자(=pub)와 구독자(=sub) 은 아래와 같은 특징을 가진다.
1. pub 이 sub 의 선언 위치나 존재를 알 필요가 없다.
- 메시지 큐와 같은 브로커 역할을 하는 중간 지점에 메시지를 던져 두기만 하면, 브로커가 알아서 처리한다.
2. sub 역시 pub 의 선언 위치나 존재를 알 필요가 없다.
- 브로커에 할당된 작업만을 모니터링하고, 원하는 작업이 발행하면 할당받아 작업을 수행하면 된다.
브로커와 메시지큐에 대한 추가적인 설명은 아래를 참고하자.
브로커?
발행자와 구독자 사이에 위치하고 있다.
주로 메시지 큐가 브로커의 역할을 수행하며, pub 과 sub 두 객체 사이에서 구독과 발행 이후의 메시지를 처리해준다.
즉, 브로커가 모든 들어오는 메시지를 필터링 하며, 타겟들(=구독자) 에게 메세지를 배포하는 역할을 한다.
메시지 큐?
메시지 큐는 프로세스나 프로그램 인스턴스가 데이터 상호 교환 시 사용하는 통신 방법이며 주로 대용량 데이터 처리를 위한 배치 작업이나 채팅 서비스, 비동기 데이터 처리등에 이용한다.
이는, 메시지 지향 미들웨어(MOM = Message Oriented Middleware)를 구현한 시스템을 의미하고, SOA(Service Oriented Architecture) 개발에 도움을 준다.
(여기서 MOM이란? 비동기 메시지를 사용하는 응용 프로그램 간 데이터 송수신을 의미한다.)
메시지 큐의 장점은 아래 같다.
- 비동기(Asynchronous) : 큐에 넣어서 나중에 처리 가능
- 비동조(Decoupling) : 앱과 분리 가능
- 탄력성(Resilience) : 일부 실패가 전체에 영향x
- 과잉(Redunadancy) : 실패할 경우 재실행 가능
- 보증(Guarantees) : 작업 처리 확인 가능
- 확장성(Scalable) : 다수 프로세스들이 큐에 메시지 보내기 가능
메시지 큐의 단점은 아래와 같다.
- '큐'이기 때문에 사용자가 많아지거나, 데이터가 많아지면 요청에 대한 응답이 늦어지게 된다.
- 즉 과도한 트래픽이 몰리게 되면, 대기 시간 지연으로 인해 서비스가 망가질 위험이 있다.
메시지 큐의 사용 예시는 아래와 같다.
- 다른 곳의 API로부터 데이터 송수신이 가능하다.
- 다양한 앱과 비동기 통신이 가능하다.
- 이메일 발송, 문서 업로드가 가능하다.
- 많은 양의 프로세스를 처리 가능하다.
발행구독 패턴과 옵저버 패턴의 차이
옵저버 패턴에서 객체(subject)가 옵저버(observer)에게 객체의 상태를 알려준다는 부분이 publisher-subscriber 패턴과 유사하다. (subject = publisher, observer = subscriber)
publisher-subscriber 패턴에서 메시지 송신자(publisher)는 정해진 수신자(specific receivers called subscriber)와 직접적 메시지를 통신하지 않는다. 그 둘 사이에 브로커 또는 메시지 브로커 또는 이벤트 버스(broker or message broker or event bus)라고 불리는 제 3의 구성요소가 있다.
옵저버 패턴과 발행구독 패턴의 차이를 정리해보면 다음과 같다.
1. 옵저버 패턴은 두 객체 간 서로를 알고 있느나, 발행구독 패턴에서는 서로를 몰라도 상관 없다.
옵저버 패턴은 구독을 하고 notify하는 과정에서, 옵저버와 옵저버블의 직접적인 소통이 이루어져야 한다.
(=옵저버 패턴 포스팅에서 살펴봤듯이, 옵저버블이 옵저버의 메서드를 호출하는 방식으로 동작한다.)
반면 발행구독 패턴은 발행 객체와 구독 객체 사이에 직접적인 소통을 하지 않아도 된다.
소통의 역할을 옵저버와 옵저버블 외에 브로커라고 하는 제 3의 구성요소가 수행하기 때문이다.
브로커는 옵저버와 옵저버블 사이에서 메시지를 필터링하여 다시 배포하는 역할을 한다.
그러므로 옵저버와 옵저버블은 서로를 알지 못해도 브로커에 의해 소통 할 수 있다.
2. 발행구독 패턴이 옵저버 패턴보다 더 낮은 결합도를 가진다.
옵저버 패턴에서는 옵저버와 옵저버블이 서로를 모른 채 소통할 수 없다.
그러나 발행구독 패턴에서는 pub(=observable) sub(=observer)가 서로를 몰라도 중간 메시지큐에 의해 소통할 수 있다.
그러므로 발행구독에서는 pub, sub이 서로 존재를 알 필요가 없으므로, 소스코드가 겹치거나 서로 의존할 일이 없겠다.
3. 옵저버 패턴은 주로 동기적으로 동작하며, 발행구독 패턴은 비동기적으로 동작하게 된다.
옵저버 패턴은 대부분 옵저버블에서 옵저버 메서드를 호출하며 동기적으로 동작한다고 했다.
발행구독 패턴에서는 pub, sub 사이에 브로커가 존재하여 각각 브로커에 메시지를 전달하며 비동기적으로 동작하게 된다.
(= 브로커로 메시지큐가 자주 사용된다는 점으로 미루어 보아 비동기적으로 동작함을 짐작할 수 있다.)
4. 옵저버 패턴은 단일 도메인(=하나의 앱) 에서 동작해야 하며 발행 구독 패턴은 크로스 도메인(=다른 앱) 상황에서도 동작이 가능하다.
크로스 도메인이란, 네이버나 카카오 같은 서로 다른 도메인을 의미한다.
또는 API 서버, 파일 서버, 소켓 서버 등 동일한 사이트에서 다른 목적으로 서버를 나눈 경우에도 크로스 도메인에 속한다.
발행구독 패턴에서 pub, sub은 서로를 몰라도 된다는 점을 이용하는 것이다.
pub, sub이 각각 브로커와 소통할 수 있다면, 앱의 도메인이 다르더라도 처리가 가능하기 때문이다.
구독-발행 패턴은 옵저버 패턴의 변화된 형태라 보면 좋겠다. 개념적으로 상당히 유사하기 때문이다.
출처
'디자인 패턴' 카테고리의 다른 글
프로토타입 (Prototype) 패턴 (0) | 2022.06.29 |
---|---|
추상 팩토리 (Abstract factory) 패턴 (0) | 2022.06.19 |
팩토리 메소드 패턴 (Factory Method Pattern) (0) | 2022.06.14 |
싱글톤 패턴 (Singleton Pattern) (0) | 2022.06.04 |
프록시(proxy) 패턴 (0) | 2022.05.03 |