Гарантии доставки

Давно хотел сделать памятку, так как на собеса про это могут спросить, и вот руки дошли

At-most-once (Не более одного раза): Сообщение может потеряться, но никогда не дублируется. (Fire-and-forget).

At-least-once (Как минимум один раз): Сообщение никогда не потеряется, но при сбоях может быть доставлено повторно (дубли).

Exactly-once (Точно один раз): Сообщение не теряется и обрабатывается строго один раз.

А теперь по брокерам)

Кафка: At-most-once - это еще надо постараться. Например считывать сообщение консьюмером говорить что прочитали и только потом класть в базу. Из коробки такого нет At-least-once - дефолт, паблишер ждёт ака что отправили, консьюмер сохраняет к себе и потом комитет оффсет Exactly-onceУ Kafka есть транзакции. Можно у паблишера сделать enable.idempotence=true и отправлять в транзакции(в коде) А у консьюмера isolation.level=read_committed это все имеет смысл скорее для пачек сообщений. Просто exactly-once скорее не нужен в таком виде, а просто используют at-least-once и индемпотентность

Rabbit At-most-once если везде стоит autoack и на констюмере и продюсер, в целом можно At-least-once дефолт. Достигается включением Publisher Confirm (брокер подтверждает паблишеру, что сохранил сообщение) и auto-ack = false у консюмера Exactly-once Сам по себе RabbitMQ не гарантирует exactly-once end-to-end.

Nats At-most-once: Это базовое поведение Core NATS. Если консюмер не подключен в момент публикации сообщения, оно теряется безвозвратно. At-least-once: Достигается при использовании JetStream. Сообщения сохраняются в стрим. Консюмер должен отправить подтверждение (ACK) об успешной обработке. Если ACK не получен в течение AckWait, JetStream отправит сообщение повторно. Exactly-once Реализуемо в JetStream. NATS использует механизм дедупликации на основе уникального MsgId, который задается паблишером. Брокер хранит окно дедупликации (по умолчанию 2 минуты) и игнорирует дубликаты от паблишера.