Event-Driven Architecture #

Event-Driven Architecture (EDA) adalah pola arsitektur di mana komponen sistem berkomunikasi melalui event — notifikasi bahwa sesuatu telah terjadi — daripada saling memanggil secara langsung. Alih-alih komponen A memanggil komponen B dan menunggu respons, komponen A mempublikasikan event “sesuatu terjadi” dan komponen yang tertarik akan merespons secara independen. Pola ini sangat natural di cloud dan menjadi fondasi banyak arsitektur modern yang scalable.

Masalah yang Dipecahkan EDA #

Untuk memahami mengapa EDA ada, perlu melihat masalah yang muncul ketika semua komunikasi antar komponen dilakukan secara sinkron.

Arsitektur Sinkron (Request-Response):

  User → Order Service → [panggil langsung] → Inventory Service
                       → [panggil langsung] → Payment Service
                       → [panggil langsung] → Notification Service
                       → [panggil langsung] → Analytics Service
                       → kirim response ke user

  Masalah:
  ✗ Tight coupling — Order Service harus tahu alamat semua service lain
  ✗ Cascading failure — jika Notification Service lambat,
    seluruh order request melambat
  ✗ Sulit menambah consumer baru — harus ubah kode Order Service
    setiap kali ada service baru yang butuh data order
  ✗ Latensi bertambah — response time = jumlah waktu semua panggilan

Konsep Dasar EDA #

EDA memiliki tiga aktor utama yang bekerja bersama.

Tiga Aktor EDA:

  Producer (Publisher):
    → Komponen yang menghasilkan event
    → Tidak tahu dan tidak peduli siapa yang akan menerima event ini
    → Hanya fokus: "apa yang terjadi" → publish event

  Event Broker (Message Bus):
    → Perantara yang menerima, menyimpan, dan mendistribusikan event
    → Menjamin event terkirim ke semua consumer yang tertarik
    → Contoh: Kafka, RabbitMQ, SQS, Pub/Sub, EventBridge

  Consumer (Subscriber):
    → Komponen yang menerima dan merespons event
    → Mendaftar (subscribe) ke tipe event yang relevan
    → Memproses event secara independen dari producer

  Alur:
  Producer → [Event Broker] → Consumer A
                            → Consumer B
                            → Consumer C

Pola Utama EDA #

Pub/Sub (Publish-Subscribe) #

Pub/Sub Pattern:

  Order Service publish event: "order.created"
  Event: { orderId: "123", userId: "u1", items: [...], total: 150000 }
       │
       ▼
  [Event Broker / Message Bus]
       │
       ├── Inventory Service  → kurangi stok
       ├── Payment Service    → proses pembayaran
       ├── Notification Service → kirim email konfirmasi
       └── Analytics Service  → catat untuk laporan

  Keunggulan:
  ✓ Order Service tidak tahu tentang consumer lain
  ✓ Consumer baru bisa ditambahkan tanpa ubah Order Service
  ✓ Jika Notification Service lambat, tidak mempengaruhi Order Service
  ✓ Setiap consumer bisa scale independen

Event Streaming #

Event Streaming vs Pub/Sub:

  Pub/Sub (message queue):
    → Event dikonsumsi oleh satu consumer (atau beberapa di grup)
    → Setelah dikonsumsi, event biasanya dihapus
    → Cocok untuk: task queue, perintah yang perlu dieksekusi sekali

  Event Streaming (Kafka, Kinesis):
    → Event disimpan dalam urutan (log yang tidak terhapus)
    → Banyak consumer bisa baca event yang sama secara independen
    → Consumer bisa replay event dari posisi manapun
    → Cocok untuk: audit log, real-time analytics, event sourcing

  Contoh perbedaan:
  Queue: "proses order ini" → satu worker ambil → selesai → dihapus
  Stream: "order ini dibuat" → inventory service baca, payment baca,
          analytics baca, audit log baca — semua dari stream yang sama

EDA dan Async Processing #

Salah satu kekuatan EDA adalah kemampuan untuk memisahkan “menerima request” dari “memproses request”.

Sinkron (user menunggu semua selesai):

  User submit order
      → Semua proses berjalan
      → Inventory check ✓
      → Payment processing (2-3 detik) ⌛
      → Email sent ✓
      → Analytics updated ✓
      → Response ke user (setelah semua selesai: 3-4 detik)

  User experience: menunggu lama

Async dengan EDA (user dapat response cepat):

  User submit order
      → Order diterima dan disimpan
      → Event "order.created" dipublish
      → Response ke user: "Order diterima, sedang diproses" (< 200ms)

  Di background (tanpa user menunggu):
      → Payment Service proses pembayaran
      → Inventory Service update stok
      → Notification Service kirim email
      → Analytics Service catat data

  User experience: respons instan, update via notifikasi

Trade-off EDA #

EDA bukan solusi yang cocok untuk semua situasi. Ia membawa kompleksitas tersendiri.

Keunggulan EDA:
  ✓ Loose coupling — producer tidak tahu tentang consumer
  ✓ Independen scalability — setiap consumer scale sesuai bebannya
  ✓ Resiliensi — consumer yang lambat tidak mempengaruhi producer
  ✓ Extensibility — tambah consumer baru tanpa ubah producer
  ✓ Natural fit untuk cloud — managed broker tersedia di semua provider

Tantangan EDA:
  ✗ Eventual consistency
      Event tidak langsung diproses → data mungkin belum konsisten
      saat user melihatnya
      → Perlu desain UI yang mengelola expectation pengguna

  ✗ Debugging lebih sulit
      Request tidak mengikuti alur linear yang mudah di-trace
      → Distributed tracing menjadi wajib

  ✗ At-least-once delivery
      Broker biasanya menjamin event terkirim minimal sekali
      → Consumer harus idempotent: proses event yang sama dua kali
        tidak boleh menghasilkan efek yang berbeda

  ✗ Ordering tidak selalu terjamin
      Event dari producer yang sama mungkin diterima tidak berurutan
      → Jika urutan penting, butuh mekanisme ordering tambahan
Idempotency adalah konsep kritis di EDA yang sering diabaikan. Jika event “payment.processed” diterima dua kali (karena retry atau duplikasi), sistem pembayaran tidak boleh memproses pembayaran dua kali. Selalu rancang consumer dengan asumsi event bisa datang lebih dari sekali.

Kapan EDA Tepat Digunakan #

EDA cocok untuk:
  ✓ Proses yang tidak perlu diselesaikan secara sinkron
      → Email, notifikasi, update analytics
      → User tidak perlu menunggu semua selesai
  
  ✓ Sistem dengan banyak consumer dari satu sumber event
      → Satu order → banyak sistem yang butuh tahu
  
  ✓ Integrasi antar sistem yang independent
      → Sistem yang berbeda tim, berbeda siklus deployment
  
  ✓ Workload yang perlu di-buffer
      → Spike trafik yang tidak harus diproses real-time

EDA kurang cocok untuk:
  ✗ Operasi yang butuh konsistensi immediate
      → "Apakah stok masih ada?" harus dijawab sekarang, bukan eventual
  
  ✗ Alur yang simple dan linear
      → Dua service yang cukup komunikasi langsung tidak perlu broker
  
  ✗ Tim yang belum familiar dengan async pattern
      → Learning curve yang signifikan sebelum bisa beroperasi efektif

Ringkasan #

  • EDA memisahkan producer dari consumer melalui event broker — producer tidak tahu siapa yang merespons eventnya, consumer tidak tahu siapa yang menghasilkan event.
  • Loose coupling adalah keunggulan utama — menambah consumer baru tidak memerlukan perubahan di producer.
  • Pub/Sub untuk pesan yang dikonsumsi sekali, streaming untuk event yang perlu direplay — keduanya punya use case yang berbeda.
  • Async processing memungkinkan respons cepat ke user — terima request, publish event, respons segera, proses di background.
  • Idempotency adalah wajib di EDA — consumer harus aman jika event yang sama diterima lebih dari sekali.
  • Eventual consistency adalah trade-off yang harus dikelola — data mungkin belum konsisten segera setelah event dipublish; desain UI dan sistem harus mengakomodasi ini.

← Sebelumnya: Immutable Infrastructure   Berikutnya: Twelve-Factor App →

About | Author | Content Scope | Editorial Policy | Privacy Policy | Disclaimer | Contact