Ответ
Apache Kafka — распределенная потоковая платформа. Её применение должно быть обосновано архитектурными требованиями.
✅ Когда Kafka — хороший выбор:
- Обработка потоков событий в реальном времени: логи, телеметрия, клики.
- Высокая пропускная способность и горизонтальное масштабирование.
- Требуется гарантированная доставка и отказоустойчивость (репликация).
- Архитектура на основе событий (Event-Driven Architecture): декoupling сервисов.
- Необходимость повторной обработки данных (хранение сообщений длительное время).
❌ Когда Kafka — избыточна или не подходит:
- Простые синхронные RPC-вызовы между двумя сервисами (используйте REST/gRPC).
- Очереди задач (Job Queues) с одним потребителем на сообщение (рассмотрите RabbitMQ).
- Сценарии с очень низкой нагрузкой, где сложность администрирования Kafka не окупается.
- Требуется строгий глобальный порядок сообщений (Kafka гарантирует порядок только в пределах партиции).
- Транзакции, затрагивающие несколько источников данных (Sagas поверх Kafka сложны).
Пример Producer/Consumer:
// Producer
Properties props = new Properties();
props.put("bootstrap.servers", "localhost:9092");
props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");
props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");
try (Producer<String, String> producer = new KafkaProducer<>(props)) {
producer.send(new ProducerRecord<>("user-events", "user123", "{"action":"login"}"));
}
// Consumer
Properties props = new Properties();
props.put("bootstrap.servers", "localhost:9092");
props.put("group.id", "my-group");
props.put("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
props.put("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
try (KafkaConsumer<String, String> consumer = new KafkaConsumer<>(props)) {
consumer.subscribe(List.of("user-events"));
while (true) {
ConsumerRecords<String, String> records = consumer.poll(Duration.ofMillis(100));
for (ConsumerRecord<String, String> record : records) {
System.out.println("Processed: " + record.value());
}
}
}
Выбор инструмента должен соответствовать задаче.
Ответ 18+ 🔞
Так, слушай сюда, про Кафку. Это ж не просто какая-то очередная хуйня, которую можно воткнуть куда попало, чтобы резюме попижонить. Это, блядь, распределённая потоковая платформа, мощнейший инструмент, но и сложный, как чёртова мать. Его надо применять с умом, а не потому что "ой, все про неё говорят".
✅ Вот когда Кафка — это прям то, что доктор прописал, ёпта:
- Потоки событий в реальном времени: логи, телеметрия, клики — всё это пиздец как летит, а Кафка всё проглотит и не поперхнётся.
- Нагрузка овердохуища и надо масштабироваться: Добавляй брокеров, плоди партиции — она только рада будет.
- Надо, чтобы ни одно сообщение не потерялось: Репликация, гарантии доставки — она за этим следит, как хитрая жопа.
- Архитектура на событиях (EDA): Хочешь, чтобы сервисы не знали друг о друге в лицо, а общались через события? Вот тут её родная стихия.
- Хочешь иметь возможность отмотать время и перечитать данные: Сообщения хранятся — бери и читай с любого места, хоть с позавчера.
❌ А вот когда Кафка — это пиздопроебина и стрельба из пушки по воробьям:
- Простые синхронные вызовы типа "скажи-мне-ответ": Ты чё, обкурился? Для этого есть REST или gRPC. Не надо тут Кафку ебать.
- Очередь задач, где одно сообщение — один работяга: Для этого RabbitMQ или что-то попроще. В Кафке consumer group — это не совсем то.
- Нагрузка — три сообщения в час: Администрировать зоопарк Кафки ради этого — это, блядь, волнение ебать. Не окупится.
- Нужен строгий глобальный порядок на все сообщения: Забудь. В Кафке порядок гарантирован только внутри одной партиции. Если это критично — готовься к боли.
- Сложные распределённые транзакции через несколько баз: Саги поверх Кафки — это тот ещё геморрой. Лучше даже не начинать.
Смотри, как примерно выглядит код, чтоб понимал масштаб:
// Тот, кто отправляет (Producer)
Properties props = new Properties();
props.put("bootstrap.servers", "localhost:9092");
props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");
props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");
try (Producer<String, String> producer = new KafkaProducer<>(props)) {
producer.send(new ProducerRecord<>("user-events", "user123", "{"action":"login"}"));
}
// Тот, кто читает (Consumer)
Properties props = new Properties();
props.put("bootstrap.servers", "localhost:9092");
props.put("group.id", "my-group");
props.put("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
props.put("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
try (KafkaConsumer<String, String> consumer = new KafkaConsumer<>(props)) {
consumer.subscribe(List.of("user-events"));
while (true) {
ConsumerRecords<String, String> records = consumer.poll(Duration.ofMillis(100));
for (ConsumerRecord<String, String> record : records) {
System.out.println("Processed: " + record.value());
}
}
}
Короче, суть в чём: бери инструмент под задачу, а не тащи Кафку везде, куда глаза глядят. Иначе накроешься медным тазом со своей "современной архитектурой".