Topik wawancara representatif

Wawancara Desain Sistem: Bagaimana Anda membangun pengiriman webhook yang aman dari replay (replay-safe)?

Desain sistemSulit
Tim Redaksi Offer.ccDipublikasikan Diperbarui

Pertanyaan

Rancang platform webhook yang mengirimkan event pembayaran ke ribuan endpoint pelanggan. Sistem harus tahan terhadap timeout, pengiriman duplikat, serangan replay, dan subscriber yang offline selama berjam-jam.

Konteks dan skenario

Sebuah produsen event menghasilkan event bisnis ke endpoint HTTP eksternal. Platform harus menyimpan event secara tahan lama (durable), mengirimkannya setidaknya satu kali (at least once), memastikan duplikat aman untuk diproses, serta memberikan kontrol percobaan ulang (retry) dan pemutaran ulang (replay) yang jelas bagi setiap penyewa.

Hal yang diuji oleh pewawancara

  • Memilih jaminan pengiriman yang eksplisit alih-alih menjanjikan exactly once melalui HTTP.
  • Memisahkan penyerapan (ingestion), penjadwalan, upaya pengiriman, dan efek samping (side effects) di sisi subscriber.
  • Menggabungkan ID event, stempel waktu tanda tangan, kebijakan retry, penanganan dead-letter, dan keadilan distribusi beban (fairness).

Pertanyaan klarifikasi sebelum menjawab

  • Berapa volume event, ukuran payload, jumlah endpoint, dan batas keterlambatan pengiriman maksimum?
  • Apakah urutan event diperlukan per penyewa, per endpoint, atau tidak sama sekali?
  • Apakah konsumen dapat memproses event secara idempoten, dan berapa lama status deduplikasi harus disimpan?
  • Persyaratan replay, penghapusan, privasi, dan audit apa yang berlaku untuk payload?

Kerangka jawaban 30 detik

Saya akan menyimpan event yang tidak dapat diubah (immutable) dengan ID yang stabil, memasukkan upaya pengiriman ke dalam antrean, dan segera mengembalikan respons dari jalur penerimaan. Worker menandatangani raw payload dengan stempel waktu, menerapkan backoff eksponensial dengan jitter, dan mengklasifikasikan respons menjadi kegagalan yang dapat diulang atau permanen. Konsumen melakukan deduplikasi berdasarkan ID event sebelum menjalankan efek samping. Penjadwal per penyewa, circuit breaker, dan dead-letter queue mencegah satu endpoint yang offline menghabiskan kapasitas untuk endpoint lain; replay membuat upaya baru tanpa mengubah identitas event asli.

Pembahasan mendalam langkah demi langkah

1. Buat event tahan lama (durable) terlebih dahulu

Tulis event bisnis dan catatan pengirimannya secara transaksional atau melalui pola outbox yang andal. Catatan pengiriman menyimpan penyewa, endpoint, ID event, jumlah percobaan, waktu percobaan berikutnya, dan status. Sistem yang mengalami crash setelah pengiriman tetapi sebelum mencatat keberhasilan adalah hal yang wajar; hal ini akan memicu percobaan lain, sehingga konsumen harus mampu menangani duplikasi.

2. Verifikasi dan tanda tangani dengan aman

Tandatangani raw bytes yang tepat beserta stempel waktu, dan sertakan ID event di dalam pesan yang ditandatangani. Stripe mendokumentasikan tanda tangan berstempel waktu untuk membatasi serangan replay. Konsumen memverifikasi tanda tangan sebelum melakukan parsing, menolak stempel waktu di luar toleransi yang dikonfigurasi, dan merotasi secret tanpa membatalkan event yang sudah berada di dalam antrean secara tidak sengaja.

3. Klasifikasikan respons dan lakukan percobaan ulang

Perlakukan batas waktu jaringan (network timeout), kegagalan koneksi, dan respons 5xx tertentu sebagai masalah yang dapat dicoba ulang. Perlakukan autentikasi yang salah, versi event yang tidak didukung, dan sebagian besar respons 4xx sebagai kegagalan permanen atau yang memerlukan tinjauan operator. Gunakan backoff eksponensial dengan jitter, jendela batas percobaan maksimum, dan status dead-letter. Jangan melakukan percobaan ulang tanpa henti terhadap endpoint yang gagal secara permanen.

4. Buat duplikat dan replay menjadi eksplisit

Konsumen menyimpan ID event yang telah diproses dengan batasan keunikan yang tahan lama dan melakukan commit catatan tersebut bersamaan dengan efek samping bisnis jika memungkinkan. Replay manual menggunakan kembali payload event yang tidak dapat diubah dan mencatat upaya pengiriman baru, sementara dasbor membedakan pengiriman asli, retry otomatis, dan replay oleh operator. Efek samping exactly-once memerlukan transaksi di sisi konsumen; jaringan itu sendiri hanya menyediakan pengiriman at-least-once.

5. Skalakan tanpa kelaparan sumber daya lintas penyewa (cross-tenant starvation)

Partisi antrean berdasarkan penyewa atau endpoint, terapkan batas konkurensi dan laju permintaan per penyewa, serta cadangkan kapasitas untuk penyewa yang sehat. Circuit breaker menghentikan sementara pengiriman ke endpoint setelah kegagalan berulang. Metrik harus mencakup usia event tertunda yang paling lama, latensi keberhasilan, distribusi percobaan, tingkat duplikasi, kegagalan tanda tangan, dan volume dead-letter.

Contoh jawaban berkualitas tinggi

“Saya akan menyimpan setiap event dengan ID yang stabil sebelum menjadwalkan pengiriman dan menjanjikan semantik at-least-once. Setiap percobaan menandatangani raw payload dengan ID event dan stempel waktu. Worker mengklasifikasikan timeout dan respons 5xx untuk retry dengan jitter, sementara respons 4xx permanen dipindahkan ke dead letter. Konsumen melakukan deduplikasi ID event di dalam transaksi efek samping mereka. Antrean per penyewa, circuit breaker, peringatan berbasis usia event, dan alur kerja replay mencegah subscriber yang offline menghabiskan sumber daya pihak lain serta membuat proses pemulihan dapat diaudit.”

Kesalahan umum

  • Menjanjikan exactly-once melalui HTTP → crash menghasilkan status yang ambigu → nyatakan at-least-once dan wajibkan konsumen yang idempoten.
  • Menandatangani JSON hasil parsing alih-alih raw bytes → pemformatan yang serupa dapat menyebabkan kegagalan verifikasi → tandatangani dan verifikasi raw bytes dari payload secara tepat.
  • Mengulang setiap 4xx selamanya → kegagalan permanen menghabiskan kapasitas → klasifikasikan error dan masukkan kasus permanen ke dead-letter.
  • Menggunakan satu antrean global → satu penyewa dapat memonopoli sumber daya bagi semua → lakukan partisi, pembatasan laju (rate limiting), dan alokasikan kapasitas per penyewa.

Pertanyaan lanjutan dan tanggapan

Berapa lama status deduplikasi harus disimpan?

Setidaknya selama jendela retry otomatis dan replay yang didukung, ditambah margin keamanan. Jika replay dapat terjadi beberapa bulan kemudian, pertahankan buku besar event yang ringkas atau wajibkan konsumen untuk memilih identitas replay dan kebijakan retensi secara eksplisit.

Haruskah sebuah replay mendapatkan ID event baru?

Biasanya tidak: identitas event bisnis tetap stabil, sedangkan upaya pengiriman mendapatkan ID dan catatan auditnya sendiri. Hal ini memungkinkan konsumen mengenali replay sebagai event yang sama dan mencegah efek bisnis ganda.

Bagaimana jika konsumen mengembalikan 200 sebelum efek sampingnya di-commit?

Kontrak konsumen dilanggar; platform tidak dapat menyimpulkan keberhasilan dari respons tersebut. Konsumen harus mengirim konfirmasi setelah penerimaan yang tahan lama, menggunakan inbox atau catatan deduplikasi transaksional, dan menyediakan rekonsiliasi untuk hasil yang ambigu.

Sumber publik

Pertanyaan terkait

Alat wawancara terkait

Gunakan Jawab untuk jawaban desain sistem

Perjelas persyaratan terlebih dahulu, lalu lanjutkan dengan skala, arsitektur, pilihan komponen, dan trade-off.

Lihat alat