Ответ
Apache Kafka — это распределённый, отказоустойчивый потоковый брокер сообщений, изначально созданный в LinkedIn. В контексте Node.js-приложений он часто используется для построения высоконагруженных, масштабируемых пайплайнов данных в реальном времени, связывая микросервисы.
Ключевые концепции:
- Топик (Topic): Именованный поток данных (например,
user-events). - Партиция (Partition): Топик делится на партиции для параллельной обработки и масштабирования.
- Производитель (Producer): Приложение (например, наш Node.js-сервис), публикующее сообщения в топик.
- Потребитель (Consumer): Приложение, подписанное на топик и читающее сообщения. Потребители объединяются в Consumer Groups для распределения нагрузки.
- Брокер (Broker): Сервер Kafka, хранящий данные.
Пример использования с библиотекой kafkajs в Node.js:
// producer.js
const { Kafka } = require('kafkajs');
const kafka = new Kafka({
clientId: 'my-node-app',
brokers: ['kafka-server1:9092', 'kafka-server2:9092']
});
const producer = kafka.producer();
async function sendEvent() {
await producer.connect();
await producer.send({
topic: 'order-created',
messages: [
{
key: 'order-123', // Ключ определяет партицию
value: JSON.stringify({ orderId: 123, amount: 99.99, userId: 'user-1' })
}
]
});
console.log('Событие отправлено в Kafka');
await producer.disconnect();
}
sendEvent().catch(console.error);
// consumer.js
const { Kafka } = require('kafkajs');
const kafka = new Kafka({
clientId: 'my-node-consumer',
brokers: ['kafka-server1:9092']
});
const consumer = kafka.consumer({ groupId: 'notification-service' });
async function runConsumer() {
await consumer.connect();
await consumer.subscribe({ topic: 'order-created', fromBeginning: false });
await consumer.run({
eachMessage: async ({ topic, partition, message }) => {
const event = JSON.parse(message.value.toString());
console.log(`Получено событие для заказа ${event.orderId}`);
// Здесь логика обработки: отправить email, уведомление и т.д.
}
});
}
runConsumer().catch(console.error);
Почему Kafka, а не RabbitMQ для Node.js? Kafka лучше подходит для сценариев с очень высокой пропускной способностью, долгосрочным хранением логов событий и потоковой обработкой через Kafka Streams или библиотеки вроде node-rdkafka.
Ответ 18+ 🔞
Давай разберем эту штуку, которая у всех на слуху, но от которой у многих мозг вскипает, как чайник у бабки в деревне. Apache Kafka, блядь. Представь себе не просто очередь сообщений, а такой промышленный конвейер, который жрёт данные, как дракон, и плюётся ими во все стороны с такой скоростью, что глаза слипаются. Изначально его в LinkedIn высидели, ну, там, где все друг на друга смотрят и связи наращивают, так что масштабы им были знакомы не понаслышке.
Суть, если на пальцах:
- Топик (Topic): Это как канал на ютубе, куда ты стримишь. Название, допустим,
user-events. Все твои действия туда летят. - Партиция (Partition): А это когда один хитрый канал делят на несколько потоков, чтобы не создавать очередь из овердохуища сообщений и чтобы несколько потребителей могли одновременно хавать данные. Гениально и просто.
- Производитель (Producer): Это твой Node.js-сервис, который, подгорев от какого-то события, начинает орать в этот топик: «Эй, все, слушайте, у нас тут заказ создался!».
- Потребитель (Consumer): Это другой сервис, который сидит, уши развесил, и слушает этот топик. А чтобы не один мучился, их объединяют в Consumer Groups — стаю таких потребителей, которые делят работу. Один упал — другие подхватят.
- Брокер (Broker): Ну, это сам сервер Кафки, где всё это безобразие физически лежит.
Смотри, как это в коде выглядит, на примере библиотеки kafkajs:
// producer.js – тот, кто кричит
const { Kafka } = require('kafkajs');
// Подключаемся к нашим брокерам. Если один накроется медным тазом – пойдём к другому.
const kafka = new Kafka({
clientId: 'my-node-app',
brokers: ['kafka-server1:9092', 'kafka-server2:9092']
});
const producer = kafka.producer();
async function sendEvent() {
await producer.connect();
// А вот и наш крик в топик 'order-created'
await producer.send({
topic: 'order-created',
messages: [
{
key: 'order-123', // Ключ – чтобы понять, в какую партицию пихать
value: JSON.stringify({ orderId: 123, amount: 99.99, userId: 'user-1' }) // Само сообщение
}
]
});
console.log('Событие отправлено в Kafka. Дело сделано.');
await producer.disconnect();
}
sendEvent().catch(console.error); // Ловим ошибки, а то будет нам хиросима
// consumer.js – тот, кто слушает
const { Kafka } = require('kafkajs');
const kafka = new Kafka({
clientId: 'my-node-consumer',
brokers: ['kafka-server1:9092']
});
// Создаём потребителя и говорим, к какой группе он принадлежит
const consumer = kafka.consumer({ groupId: 'notification-service' });
async function runConsumer() {
await consumer.connect();
// Подписываемся на топик. 'fromBeginning: false' – слушаем только новое, старое не надо.
await consumer.subscribe({ topic: 'order-created', fromBeginning: false });
// А вот тут начинается магия – обработка каждого сообщения
await consumer.run({
eachMessage: async ({ topic, partition, message }) => {
const event = JSON.parse(message.value.toString()); // Выковыриваем данные
console.log(`Получено событие для заказа ${event.orderId}, ёпта!`);
// Тут твоя логика: слать письмо, пинать другой сервис – делай что хочешь.
}
});
}
runConsumer().catch(console.error);
И главный вопрос: нахуя это, если есть RabbitMQ? Вот смотри, RabbitMQ — это как надёжный, умный почтальон, который гарантированно доставит письмо из рук в руки. А Kafka — это, блядь, гигантский ленточный транспортёр на заводе, который непрерывным потоком гонит тонны сырья (данных), и ты можешь в любом месте этого конвейра поставить своего работника (потребителя), чтобы он что-то с этим сырьём делал. Кафка рулит, когда тебе нужно:
- Обрабатывать овердохуища событий в секунду.
- Хранить эти события долго (он же по сути лог).
- Строить сложную потоковую обработку (через Kafka Streams или
node-rdkafka), где данные непрерывно текут и преобразуются.
Короче, если у тебя не просто фантики между сервисами перекидывать, а реально мощный data pipeline в реальном времени — то это твой выбор. А если задача простая — не выёбывайся, бери RabbitMQ и живи спокойно.