이 패턴은 메시지를 보내는 발행자(Publisher)와 메시지를 받는 구독자(Subscriber) 사이의 느슨한 결합(Loose Coupling)을 제공하는 메시징 패턴으로, 발행자는 메시지를 특정 주제(Topic)나 채널로 발행하고, 해당 주제를 구독하는 모든 구독자들이 그 메시지를 받게 된다.
Publisher-Subscriber Pattern(게시자-구독자 패턴)은 소프트웨어 아키텍처에서 중요한 디자인 패턴 중 하나로, 분산 시스템에서 비동기 통신을 구현하는 데 널리 사용된다. 이 패턴은 메시지를 보내는 발행자(Publisher)와 메시지를 받는 구독자(Subscriber) 사이의 느슨한 결합(Loose Coupling)을 제공하는 메시징 패턴으로, 발행자는 메시지를 특정 주제(Topic)나 채널로 발행하고, 해당 주제를 구독하는 모든 구독자들이 그 메시지를 받게 된다. 이 패턴은 컴포넌트 간의 느슨한 결합을 제공하여 확장성과 유연성을 높이는 데 기여한다.
// publisher.js
constRedis=require('ioredis');constpublisher=newRedis();classNewsPublisher{constructor(){this.publisher=publisher;}// 뉴스 발행 메서드
asyncpublishNews(category,newsData){try{constmessage={id:Date.now(),category,content:newsData,timestamp:newDate().toISOString()};// 카테고리별 채널로 뉴스 발행
awaitthis.publisher.publish(`news:${category}`,JSON.stringify(message));console.log(`Published news to ${category}:`,message);returntrue;}catch(error){console.error('Error publishing news:',error);returnfalse;}}}// subscriber.js
constRedis=require('ioredis');constsubscriber=newRedis();classNewsSubscriber{constructor(categories){this.subscriber=subscriber;this.categories=categories;this.setup();}setup(){// 각 카테고리 채널 구독
this.categories.forEach(category=>{this.subscriber.subscribe(`news:${category}`);});// 메시지 수신 이벤트 처리
this.subscriber.on('message',(channel,message)=>{constnews=JSON.parse(message);this.handleNews(channel,news);});}handleNews(channel,news){console.log(`Received news on ${channel}:`,news);// 실제 뉴스 처리 로직 구현
}}// 메시지 브로커 역할을 하는 이벤트 버스
classEventBus{constructor(){this.redis=newRedis();this.channels=newMap();}// 메시지 필터링 및 전달 관리
asynchandleMessage(channel,message){constsubscribers=this.channels.get(channel)||[];constparsedMessage=JSON.parse(message);// 메시지 유효성 검사
if(!this.validateMessage(parsedMessage)){console.error('Invalid message format:',parsedMessage);return;}// 구독자들에게 메시지 전달
subscribers.forEach(subscriber=>{try{subscriber.handleNews(channel,parsedMessage);}catch(error){console.error('Error delivering message to subscriber:',error);}});}validateMessage(message){returnmessage.id&&message.category&&message.content;}}