Какова цель использования Kafka в проекте
Что проверяют
Понимаете ли вы, какую проблему Kafka решает в конкретной архитектуре, и отличаете ли её от обычной очереди. Для .NET ещё и то, как вы работаете с ней из кода. Следом почти всегда спрашивают, почему не RabbitMQ.
Как отвечать
Kafka это распределённый журнал событий. Сообщения пишутся в топик, разбитый на партиции, хранятся заданное время (retention) и не удаляются после чтения. Отсюда реальные причины её выбрать:
- развязка сервисов: сервис заказов публикует событие, а склад и уведомления читают его независимо, каждый своей consumer group;
- повторное чтение: новый или исправленный после бага потребитель перечитывает историю с нужного offset;
- буфер под пики: продюсер пишет быстро, потребители разбирают в своём темпе;
- порядок по ключу: сообщения с одним ключом попадают в одну партицию и читаются по порядку. Порядка между партициями нет;
- поток изменений из базы: CDC через Kafka Connect и Debezium.
В .NET обычно берут пакет Confluent.Kafka, обёртку над librdkafka: ProducerBuilder, ConsumerBuilder, потребитель живёт в BackgroundService. Вызов Consume блокирующий, поэтому цикл выносят в отдельный долгоживущий поток, а не занимают им поток пула. Для надёжности отключают EnableAutoOffsetStore и сохраняют смещение только после успешной обработки, у продюсера включают EnableIdempotence. Согласованность записи в базу и публикации даёт паттерн Outbox.
Где спотыкаются
Называют Kafka просто очередью. Параллелизм группы ограничен числом партиций: в топике с тремя партициями четвёртый потребитель будет простаивать. Подтвердить сообщение поштучно, как в RabbitMQ, нельзя, коммитится смещение.
Верят, что exactly-once получается само. При правильном коммите доставка at-least-once, и дубль после ребалансировки или рестарта обязательно придёт, поэтому обработчик должен быть идемпотентным. А с настройками по умолчанию смещение может закоммититься раньше обработки, и сообщение потеряется при падении.
Не думают о «ядовитых» сообщениях. Встроенной очереди недоставленных у клиента нет: если обработчик падает на одном сообщении и не коммитит, потребитель застревает. Нужны retry-топик и DLQ, свои или из библиотеки.