메시지 큐(Message Queue)는 프로세스 또는 프로그램 간에 데이터를 교환할 때 사용하는 통신 방법 중에 하나로, 메시지 지향 미들웨어(Message Oriented Middleware:MOM)를 구현한 시스템을 의미
MOM(Message Oriented Middleware)
비동기 메세지를 사용하는 프로그램 간 데이터 송수신
주문을 하고 결제를 할 때 시간이 과하게 오래 걸릴 때, 결제창으로 바로 넘어가고 주문한 데이터를 메세지 큐에 보관한다. 결제를 처리하고 나면 주문한 데이터를 창고에 전달하는 등 비동기적으로 프로그램을 다룰 때 쓰인다.

publish/subscribe의 줄임말이며, 비동기식 메세징 패턴
이벤트(메시지)를 발행하는 Publisher가 존재하며,
Publisher는 특정 Channel(혹은 Topic)에 이벤트를 전송
특정 Channel(혹은 Topic)을 구독하는 Subscriber가 존재하며,
Publisher에 관계없이 발행된 이벤트를 수신
publisher(게시자)
message를 생성해 topic에 전달하는 서버
message(메세지)
publisher로부터 subscriber에게 최종적으로 전달되는 데이터와 속성(property)의 조합
pub/sub 사이에서 중간다리 역할을 하는 브로커, 혹은 버스라고 불리는 존재가 추가적으로 존재
publisher -> producer
subscribe -> consumer

Producer는 Topic에 이벤트를 보낸다.
이 이벤트는 Topic의 각 Partition에 분산되어 저장된다.
Topic을 구독하고 있는 Consumer group 내의 Consumer는 각각 1개 이상의 partition으로부터 이벤트를 가져온다.
(항상 partition 수를 consumer보다 같거나 크게 해주는 것이 좋다.)
코드는 블로그 를 따라갔다.
// producer.js
const express = require('express')
const app = express()
const port = 3000
const { Kafka } = require('kafkajs')
const kafka = new Kafka({
clientId: 'my-app-pro',
brokers: ['localhost:9092']
})
const producer = kafka.producer()
const initKafka = async () => {
await producer.connect()
}
app.post('/events/:event', async (req, res) => {
await producer.send({
topic: 'quickstart-events',
messages: [
{ value: req.params.event },
],
})
res.send('successfully stored event : '+ req.params.event + '\n')
})
app.listen(port, async () => {
console.log(`kafka app listening on port ${port}`)
})
initKafka().catch(e => console.error(`[example/consumer] ${e.message}`, e));
vscode에서 cmd를 실행한다.
> node producer.js
실행하고 나면 3000포트에 서버가 켜지고, [post] /events/:event 를 postman등으로 메세지를 보내본다.

다음은 보낸 메세지를 받아보는 과정이다.
// consumer.js
const { Kafka } = require('kafkajs')
const kafka = new Kafka({
clientId: 'my-app-cus',
brokers: ['localhost:9092']
})
const consumer = kafka.consumer({ groupId: 'test-group' })
const topic = 'quickstart-events'
const initKafka = async () => {
console.log('start subscribe')
await consumer.connect()
await consumer.subscribe({ topic, fromBeginning: true })
await consumer.run({
eachMessage: async ({ topic, partition, message }) => {
console.log({
topic,
value: message.value.toString(),
})
},
})
}
initKafka().catch(e => console.error(`[example/consumer] ${e.message}`, e))
vscode에서 cmd를 하나 더 켜서 consumer를 실행한다.
> node consumer.js
producer에서 보낸 메세지가 consumer에 도착해 있는 것을 확인할 수 있다.

전에 기술 블로그를 구경하다가 docker와 spring을 이용한 Kafka 구성하는 걸 봤을 땐 좀 어렵게 다가왔는데, 이 글을 읽으면서 개념부터 사용방향, 구성 과정까지 한 번에 볼 수 있어서 이해하기에 수월했던 것 같습니다! 글 잘 봤습니다ㅏ!!