Как обеспечить exactly-once delivery?

Senior
379 просмотров
AFK Offer AI

Exactly-once delivery — гарантия, что сообщение обработается ровно один раз. В распределённых системах это святой грааль, потому что в чистом виде невозможен. На практике используют exactly-once semantics — комбинацию at-least-once delivery и идемпотентной обработки.

Три уровня гарантий:

  • At-most-once: отправил и забыл. Может потеряться.
  • At-least-once: retry до подтверждения. Может быть дубликат.
  • Exactly-once: ровно один раз. Достигается через идемпотентность.
func handleEvent(ctx context.Context, event Event) error {
    // идемпотентность через уникальный ID события
    if processed, _ := redis.Exists(ctx, "event:"+event.ID); processed {
        return nil // уже обработано
    }
    
    err := processEvent(ctx, event)
    if err != nil {
        return err
    }
    
    redis.Set(ctx, "event:"+event.ID, true, 7*24*time.Hour)
    return nil
}

Kafka поддерживает exactly-once через transactional producer + consumer в одной consumer group. Но между сервисами — только at-least-once + idempotency. Храни ID обработанных событий и проверяй перед обработкой.

Следующий вопрос

Как Go 1.14 изменил preemption?