Ключ. kafkaTemplate.send("orders", order.id().toString(), event) — все события заказа попадут в одну партицию и будут обработаны по порядку. Без ключа порядок не гарантирован.
Асинхронность. send сразу возвращает CompletableFuture<SendResult> (в Spring Kafka 3; раньше — ListenableFuture). Если ошибку не обработать, сообщение может потеряться незаметно: логировать в whenComplete, при необходимости повторять или сохранять в outbox. Синхронный .get() с таймаутом — когда нужно гарантировать отправку до ответа клиенту.
Надёжность продюсера (spring.kafka.producer.*): acks=all, enable.idempotence=true (по умолчанию с Kafka 3.0), retries и delivery.timeout.ms, на топике min.insync.replicas=2.
Сериализация: JsonSerializer (с заголовком типа) или Avro/Protobuf со Schema Registry для контрактов между командами.
Согласованность с базой: сохранить заказ в базе и отправить событие — две разные системы. Если упасть между ними, событие потеряется или уйдёт без записи в базе. Решения — transactional outbox (событие в таблицу в той же транзакции, публикация отдельным процессом) или CDC. Транзакции Kafka (transactional.id) делают атомарной отправку в несколько топиков и коммит offset, но не запись в базу.