๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
IT

Pub-Sub Pattern: ์ด๋ฒคํŠธ ๊ธฐ๋ฐ˜ ํ†ต์‹ ์˜ ํ•ต์‹ฌ

by ๐Ÿ’ฒ๐ŸŽตโœ–๏ธโœ”๏ธโ˜ผ 2024. 3. 2.
728x90

Pub-Sub Pattern: ์ด๋ฒคํŠธ ๊ธฐ๋ฐ˜ ํ†ต์‹ ์˜ ํ•ต์‹ฌ

์†Œ๊ฐœ

Pub-Sub Pattern(๋ฐœํ–‰-๊ตฌ๋… ํŒจํ„ด)์€ ์†Œํ”„ํŠธ์›จ์–ด ์•„ํ‚คํ…์ฒ˜์—์„œ ์ด๋ฒคํŠธ ๊ธฐ๋ฐ˜ ํ†ต์‹ ์„ ๊ตฌํ˜„ํ•˜๋Š” ํŒจํ„ด ์ค‘ ํ•˜๋‚˜์ž…๋‹ˆ๋‹ค. ์ด ํŒจํ„ด์€ ํŠน์ • ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ–ˆ์„ ๋•Œ, ๋ฐœํ–‰์ž(Publisher)๊ฐ€ ๋ฉ”์‹œ์ง€๋ฅผ ๋ณด๋‚ด๊ณ , ํ•ด๋‹น ์ด๋ฒคํŠธ์— ๊ด€์‹ฌ์ด ์žˆ๋Š” ์—ฌ๋Ÿฌ ๊ฐœ์˜ ๊ตฌ๋…์ž(Subscriber)๊ฐ€ ์ด๋ฅผ ์ˆ˜์‹ ํ•˜๋Š” ๊ตฌ์กฐ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

Pub-Sub Pattern์˜ ๊ตฌ์„ฑ์š”์†Œ

  1. Publisher(๋ฐœํ–‰์ž): ์ด๋ฒคํŠธ๋ฅผ ๋ฐœ์ƒ์‹œํ‚ค๋Š” ์ฃผ์ฒด๋กœ, ์ด๋ฒคํŠธ์™€ ๊ด€๋ จ๋œ ๋ฉ”์‹œ์ง€๋ฅผ ์ƒ์„ฑํ•˜๊ณ  Pub-Sub ์‹œ์Šคํ…œ์— ์ „์†กํ•ฉ๋‹ˆ๋‹ค.

  2. Subscriber(๊ตฌ๋…์ž): ํŠน์ • ์ด๋ฒคํŠธ์— ๊ด€์‹ฌ์ด ์žˆ๋Š” ์ฃผ์ฒด๋กœ, ๋ฐœํ–‰์ž๊ฐ€ ๋ณด๋‚ธ ๋ฉ”์‹œ์ง€๋ฅผ ์ˆ˜์‹ ํ•˜๊ณ  ๊ทธ์— ๋”ฐ๋ฅธ ๋™์ž‘์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.

  3. Topic(์ฃผ์ œ ๋˜๋Š” ์ฑ„๋„): ์ด๋ฒคํŠธ์˜ ์œ ํ˜• ๋˜๋Š” ์นดํ…Œ๊ณ ๋ฆฌ๋ฅผ ๋‚˜ํƒ€๋‚ด๋ฉฐ, ๋ฐœํ–‰์ž๋Š” ํŠน์ • ์ฃผ์ œ๋กœ ๋ฉ”์‹œ์ง€๋ฅผ ๋ณด๋‚ด๊ณ , ํ•ด๋‹น ์ฃผ์ œ์— ๊ด€์‹ฌ์ด ์žˆ๋Š” ๊ตฌ๋…์ž๋Š” ํ•ด๋‹น ์ด๋ฒคํŠธ๋ฅผ ์ˆ˜์‹ ํ•ฉ๋‹ˆ๋‹ค.

Pub-Sub Pattern์˜ ์—ญํ• 

  1. ์ด๋ฒคํŠธ ๊ธฐ๋ฐ˜ ํ†ต์‹ : ๋น„๋™๊ธฐ์ ์œผ๋กœ ์ปดํฌ๋„ŒํŠธ ๊ฐ„์— ํ†ต์‹ ์„ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•˜๋ฉฐ, ๋А์Šจํ•œ ๊ฒฐํ•ฉ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

  2. ํ™•์žฅ์„ฑ: ์ƒˆ๋กœ์šด ์ด๋ฒคํŠธ๋‚˜ ์ฃผ์ œ๋ฅผ ๊ฐ„๋‹จํ•˜๊ฒŒ ์ถ”๊ฐ€ํ•˜์—ฌ ์‹œ์Šคํ…œ์„ ํ™•์žฅํ•˜๊ธฐ ์šฉ์ดํ•ฉ๋‹ˆ๋‹ค.

  3. ์œ ์—ฐ์„ฑ: ๋ฐœํ–‰์ž์™€ ๊ตฌ๋…์ž ๊ฐ„์˜ ๊ด€๊ณ„๊ฐ€ ๋…๋ฆฝ์ ์ด๋ฏ€๋กœ, ๋ณ€ํ™”์— ๋Œ€์‘ํ•˜๊ธฐ ์‰ฝ์Šต๋‹ˆ๋‹ค.

Pub-Sub Pattern์˜ ์žฅ๋‹จ์ 

์žฅ์ 

  1. ๋А์Šจํ•œ ๊ฒฐํ•ฉ: ๋ฐœํ–‰์ž์™€ ๊ตฌ๋…์ž ๊ฐ„์˜ ์ƒํ˜ธ ์˜์กด์„ฑ์ด ์ค„์–ด๋“ค์–ด ์œ ์—ฐ์„ฑ๊ณผ ์œ ์ง€๋ณด์ˆ˜์„ฑ์ด ํ–ฅ์ƒ๋ฉ๋‹ˆ๋‹ค.

  2. ํ™•์žฅ์„ฑ: ์ƒˆ๋กœ์šด ์ด๋ฒคํŠธ๋‚˜ ๊ตฌ๋…์ž๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๋ฐ ์šฉ์ดํ•˜๋ฉฐ, ์‹œ์Šคํ…œ์˜ ํ™•์žฅ์ด ์‰ฝ์Šต๋‹ˆ๋‹ค.

  3. ๋ถ„๋ฆฌ๋œ ์—ญํ• : ๊ฐ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์ž์‹ ์˜ ์—ญํ• ์—๋งŒ ์ง‘์ค‘ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ด์ค๋‹ˆ๋‹ค.

๋‹จ์ 

  1. ๋ฉ”์‹œ์ง€ ์ „๋‹ฌ ์ง€์—ฐ: ๋น„๋™๊ธฐ์  ํ†ต์‹ ์œผ๋กœ ์ธํ•ด ๋ฉ”์‹œ์ง€์˜ ์ „๋‹ฌ์ด ์ง€์—ฐ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  2. ๋””๋ฒ„๊น… ์–ด๋ ค์›€: ์ด๋ฒคํŠธ์˜ ํ๋ฆ„์ด ๋ถ„์‚ฐ๋˜์–ด ์žˆ์–ด ๋””๋ฒ„๊น…์ด ์–ด๋ ค์šธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Pub-Sub Pattern์˜ ์˜ˆ์ œ ์ฝ”๋“œ

๋‹ค์Œ์€ JavaScript์—์„œ์˜ ๊ฐ„๋‹จํ•œ Pub-Sub ํŒจํ„ด ์˜ˆ์ œ ์ฝ”๋“œ์ž…๋‹ˆ๋‹ค.

// Pub-Sub ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ
class PubSub {
    constructor() {
        this.subscribers = {};
    }

    subscribe(topic, callback) {
        if (!this.subscribers[topic]) {
            this.subscribers[topic] = [];
        }
        this.subscribers[topic].push(callback);
    }

    publish(topic, data) {
        if (this.subscribers[topic]) {
            this.subscribers[topic].forEach(callback => callback(data));
        }
    }
}

// ๋ฐœํ–‰์ž
class Publisher {
    constructor(pubSub) {
        this.pubSub = pubSub;
    }

    fireEvent() {
        console.log('Event fired!');
        this.pubSub.publish('event', { message: 'Hello, subscribers!' });
    }
}

// ๊ตฌ๋…์ž
class Subscriber {
    constructor(pubSub) {
        this.pubSub = pubSub;
        this.pubSub.subscribe('event', this.handleEvent.bind(this));
    }

    handleEvent(data) {
        console.log('Event handled:', data.message);
    }
}

// ์‚ฌ์šฉ ์˜ˆ์ œ
const pubSub = new PubSub();
const publisher = new Publisher(pubSub);
const subscriber = new Subscriber(pubSub);

publisher.fireEvent();

์—ฐ๊ด€๋œ ๊ธฐ์ˆ 

Pub-Sub ํŒจํ„ด์€ ์ด๋ฒคํŠธ ๊ธฐ๋ฐ˜ ์‹œ์Šคํ…œ์—์„œ ์ฃผ๋กœ ์‚ฌ์šฉ๋˜๋ฉฐ, ์ด์— ๊ด€๋ จ๋œ ๊ธฐ์ˆ ๋กœ๋Š” MQTT, Apache Kafka, RabbitMQ ๋“ฑ์ด ์žˆ์Šต๋‹ˆ๋‹ค
Pub-Sub ํŒจํ„ด์€ ๋‹ค์–‘ํ•œ ๋ถ„์•ผ์—์„œ ์‚ฌ์šฉ๋˜๋ฉฐ, ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ์˜ ๋น„๋™๊ธฐ ํ†ต์‹ , ๋ถ„์‚ฐ ์‹œ์Šคํ…œ์—์„œ์˜ ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ ๋“ฑ์— ์ ์šฉ๋ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์œ ์—ฐ์„ฑ๊ณผ ํ™•์žฅ์„ฑ์„ ํ–ฅ์ƒ์‹œํ‚ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋Œ“๊ธ€