Skip to Content
Go Realm v1 is released 🎉
RabbitMQDay 7: Pub/Sub and Event Design

Day 7

Pub/Sub and Event-Driven Design

āφāϜāϕ⧇ āφāĻŽāϰāĻž asynchronous architecture-āĻāϰ design thinking āĻļāĻŋāĻ–āĻŦāĨ¤ RabbitMQ āĻļ⧁āϧ⧁ code API āύāĻž, āĻāϟāĻŋ system boundary design āĻ•āϰāĻžāϰ āϟ⧁āϞāĨ¤

Pub/Sub āĻŽāĻžāύ⧇ āϕ⧀?

āĻāĻ•āϟāĻŋ event publish āĻšāϞ⧇ multiple independent consumers āϏ⧇āϟāĻŋ āĻĒ⧇āϤ⧇ āĻĒāĻžāϰ⧇āĨ¤ āωāĻĻāĻžāĻšāϰāĻŖ:

  • order created -> payment
  • order created -> analytics
  • order created -> email notification

Fanout Example

err := ch.ExchangeDeclare("orders.broadcast", "fanout", true, false, false, false, nil) if err != nil { log.Fatal(err) } err = ch.Publish("orders.broadcast", "", false, false, amqp.Publishing{ ContentType: "application/json", Body: []byte(`{"order_id":77,"status":"created"}`), }) if err != nil { log.Fatal(err) }

Command vs Event

TypeMeaningExample
Command“āĻāϟāĻŋ āĻ•āĻ°ā§‹â€send.invoice.email
Event“āĻāϟāĻŋ āĻšā§Ÿā§‡ āϗ⧇āĻ›ā§‡â€invoice.generated

Architecture Choice

Situation: User signup āĻšāϞ⧇ profile service, email service, analytics service, audit log service react āĻ•āϰāĻŦ⧇āĨ¤

Goal: Work queue āύāĻž pub/sub?

What to think about:

  • āϏāĻŦ consumer event āĻĒāĻžāĻŦ⧇
  • āĻāĻ• consumer-āĻāϰ failure āĻ…āĻ¨ā§āϝāϟāĻžāϕ⧇ block āĻ•āϰāĻŦ⧇ āύāĻž
  • Future-āĻ āύāϤ⧁āύ subscriber āϝ⧋āĻ— āĻšāϤ⧇ āĻĒāĻžāϰ⧇
āϏāĻŽā§āĻ­āĻžāĻŦā§āϝ āϏāĻŽāĻžāϧāĻžāύ āĻĻ⧇āϖ⧁āύ

Pub/sub pattern bestāĨ¤ Fanout āĻŦāĻž topic exchange āĻĻāĻŋā§Ÿā§‡ multiple independent queue bind āĻ•āϰāĻž āϝāĻžāĻŦ⧇āĨ¤ Work queue āĻšāϞ⧇ event āĻāĻ• worker consume āĻ•āϰ⧇āχ āĻļ⧇āώ āĻšā§Ÿā§‡ āϝāĻžāĻŦ⧇, āϝāĻž āϭ⧁āϞ behaviourāĨ¤

Naming tip

Checkpoint

āύāĻŋāĻœā§‡ āϭ⧇āĻŦ⧇ āĻĻ⧇āĻ–ā§‹: same payload payment āφāϰ analytics service āĻ­āĻŋāĻ¨ā§āύāĻ­āĻžāĻŦ⧇ consume āĻ•āϰāϞ⧇ producer-āĻāϰ āĻ•āĻŋāϛ⧁ āĻŦāĻĻāϞāĻžāύ⧋ āϞāĻžāĻ—āĻž āωāϚāĻŋāϤ āĻ•āĻŋ?

  • āύāĻž, ideally āύāĻž
  • consumer-specific logic producer-āĻ leak āĻšāĻ“ā§ŸāĻž āωāϚāĻŋāϤ āύāĻž
  • āĻāϟāĻžāχ loose coupling-āĻāϰ value