Topik wawancara representatif

Mendesain Sistem Notifikasi Multi-Saluran

Desain sistemSulit
Tim Redaksi Offer.ccDipublikasikan Diperbarui

Pertanyaan

Rancang sistem notifikasi multi-saluran untuk mobile push, SMS, email, dan pesan dalam aplikasi (in-app message). Sistem harus mengirimkan notifikasi transaksional seperti OTP ke penyedia layanan (provider) dengan latensi rendah, menangani kampanye pemasaran berskala besar, serta mengelola preferensi pengguna, duplikasi pekerjaan, kuota provider, callback yang tidak berurutan, dan pemulihan secara benar.

Masalah dan skenario yang berlaku

Rancang platform notifikasi bersama yang digunakan oleh layanan autentikasi, pemesanan, sosial, dan pemasaran. Platform ini mendukung mobile push, SMS, email, dan in-app message. Pesan transaksional mencakup OTP dan hasil pembayaran; pesan massal (bulk) mencakup pengingat acara dan promosi pemasaran. Pemanggil (caller) dapat mengirim notifikasi secara langsung atau menjadwalkannya. Pengguna dapat memilih keluar (opt-out) berdasarkan saluran dan jenis notifikasi, dan pesan pemasaran harus mematuhi jam tenang (quiet hours) di zona waktu masing-masing pengguna.

Gunakan asumsi wawancara berikut:

  • Sistem membuat satu miliar tugas pengiriman saluran per hari. Satu notifikasi bisnis yang dikirim melalui SMS dan email dihitung sebagai dua tugas.
  • Throughput rata-rata adalah 1,000,000,000 / 86,400 ≈ 11,600 tugas per detik. Perkirakan puncak kampanye pada 20 kali lipat dari rata-rata, atau sekitar 232.000 tugas per detik.
  • Target ketersediaan untuk penerimaan API yang tahan lama (durable) adalah 99,99%, dengan latensi penerimaan p99 di bawah 200 milidetik.
  • Untuk OTP, waktu p99 dari penerimaan hingga penyerahan ke penyedia saluran berada di bawah dua detik. Pekerjaan pemasaran dapat diratakan (smoothed) selama 15 menit. Kedua target tidak menjanjikan kapan perangkat benar-benar menampilkan pesan.
  • Jika amplop tahan lama (durable envelope) untuk satu tugas pengiriman rata-rata 1 KB, penulisan logis adalah sekitar 1 TB per hari dan 30 TB selama 30 hari, sebelum indeks, replika, tanda terima, dan kompresi.

Nilai-nilai ini mendorong keputusan pemartisian (partitioning), backlog, dan isolasi; nilai tersebut bukanlah klaim kinerja provider. Pembuatan templat, algoritma pemilihan audiens, penagihan, dan pengujian A/B berada di luar cakupan. Pertanyaan ini ditujukan untuk peran senior backend, platform, dan system design. Tantangan utamanya adalah mempertahankan prioritas, kemampuan pemulihan (recoverability), dan keteramatan yang jujur (truthful observability) di seluruh saluran eksternal dengan semantik yang berbeda.

Apa yang dievaluasi oleh pewawancara

Sinyal pertama adalah apakah kandidat mendefinisikan "berhasil dikirim". Respons API 202 berarti platform telah menerima pekerjaan secara durable. Respons provider yang berhasil biasanya berarti provider telah menerima permintaan tersebut. Tanda terima perangkat, tampilan sistem operasi, dan pembukaan oleh pengguna adalah status-status berikutnya. Metrik Sends pada Firebase dapat berarti pesan telah diantrekan atau diteruskan ke APNs, sedangkan respons APNs yang berhasil menjelaskan permintaan tersebut. Menggabungkan semua hal ini ke dalam delivered akan merusak metrik operasional dan penanganan insiden.

Sinyal kedua adalah apakah prioritas didukung oleh isolasi sumber daya. Antrean bersama dengan bidang prioritas tetap dapat mengalami situasi di mana disk, koneksi konsumen, dan kuota provider-nya dihabiskan oleh kampanye 50 juta pengguna. Desain yang kuat memisahkan antrean transaksional dan massal, konsumen, serta anggaran saluran yang dilindungi sambil mengizinkan lalu lintas massal meminjam kapasitas yang menganggur (idle). Lalu lintas OTP juga membutuhkan batas atasnya sendiri; label "kritis" tidak boleh melewati setiap perlindungan.

Sinyal ketiga adalah bahasa jaminan pengiriman yang presisi. Antrean standar dapat mengirimkan tugas lebih dari sekali, sehingga pekerja (workers) harus memproses delivery_id yang stabil secara idempoten. Jika batas waktu jaringan (network timeout) terjadi setelah provider menerima permintaan, deduplikasi internal tidak dapat membatalkan efek samping eksternal tersebut. Tanpa API pengiriman idempoten di sisi provider, platform dapat mengurangi probabilitas duplikasi, mencatat hasil yang tidak pasti, dan memilih percobaan ulang atau failover berdasarkan risiko pesan. Platform tidak dapat menjanjikan pengiriman end-to-end exactly-once.

Sinyal keempat adalah loop kegagalan tertutup (closed failure loop). Kegagalan permanen berhenti mencoba lagi dan menonaktifkan endpoint yang tidak valid jika ada justifikasi. Respons HTTP 429, 5xx, dan kegagalan jaringan menggunakan backoff dengan jitter. Tugas yang kedaluwarsa akan dihentikan. Pemutaran ulang dead-letter (dead-letter replay) mempertahankan delivery_id asli dan memeriksa ulang status kedaluwarsa serta opt-out. Tanda terima dapat terduplikasi dan tiba tidak berurutan, sehingga sistem menyimpan event mentah sebelum mendapatkan status saat ini melalui transisi khusus saluran.

Pertanyaan untuk diklarifikasi sebelum menjawab

  • Apa arti "terkirim" (delivered) bagi bisnis? Target OTP yang dapat dikontrol harus berakhir pada penerimaan provider karena perangkat offline, operator seluler, dan izin pengguna berada di luar platform. Jika bisnis memerlukan status "dibaca", diperlukan tanda terima saluran atau event klien yang didukung, dengan cakupan yang diungkapkan secara transparan.
  • Siapa yang menetapkan jenis dan prioritas notifikasi? Server memiliki katalog jenis terkontrol yang memetakan jenis ke prioritas, saluran yang diizinkan, templat, dan aturan opt-out. Mengizinkan pemanggil mengirimkan critical=true membuat setiap tim bersaing untuk mendapatkan jalur darurat.
  • Pesan mana yang boleh mengabaikan jam tenang atau opt-out? Hanya jenis transaksi yang disetujui untuk pengecualian tersebut yang boleh melakukannya. Preferensi pemasaran diperiksa tepat sebelum pengantrean saluran, sehingga pengguna yang memilih keluar setelah penjadwalan akan dikecualikan.
  • Apakah fallback lintas saluran diizinkan? Mengganti SMS yang gagal dengan push akan mengubah biaya, keterjangkauan, dan ekspektasi pengguna. Konfigurasikan grafik fallback berdasarkan jenis notifikasi dan bedakan penolakan eksplisit dari hasil yang tidak diketahui; failover setelah hasil yang tidak diketahui dapat menghubungi pengguna dua kali.
  • Pengurutan seperti apa yang diperlukan? Pesan pengaturan ulang kata sandi untuk satu pengguna mungkin memerlukan pengurutan, sementara peringatan sosial biasa biasanya tidak memerlukan pengurutan global. Pertahankan urutan hanya pada kunci seperti (user_id, notification_type) untuk menghindari serialisasi seluruh sistem.
  • Apa batas retensi dan privasi? Isi pesan mungkin sensitif. Simpan versi templat dan parameter minimal dalam antrean, enkripsi bidang tertentu, terapkan batas retensi, dan jangan pernah mencatat OTP, nomor telepon lengkap, atau isi email ke dalam log.

Kerangka jawaban 30 detik

"Saya akan memisahkan penerimaan tahan lama (durable acceptance), penerimaan provider, pengiriman perangkat, dan pembacaan pengguna ke dalam status-status yang berbeda. Ingress secara atomik menulis notifikasi dan sebuah outbox, lalu mengembalikan 202. Fan-out penerima bersifat asinkron, dan kebijakan diperiksa mendekati waktu pengiriman untuk preferensi, jam tenang, masa kedaluwarsa, dan deduplikasi. Setiap saluran memiliki antrean dan konsumen terpisah untuk transaksional, normal, dan massal, dengan kapasitas provider yang dilindungi untuk lalu lintas transaksional dan kapasitas menganggur dipinjamkan ke pekerjaan massal. Pekerja memproses tugas setidaknya-sekali (at-least-once) di bawah delivery_id yang stabil, mengklasifikasikan kegagalan permanen, batas laju (rate-limit), dan sementara, serta menggunakan exponential backoff dengan jitter untuk kasus sementara. Callback provider ditambahkan sebagai event dan diproses melalui state machine saluran, sehingga event 'terkirim' yang datang terlambat tidak dapat menurunkan status 'diterima'. Saya akan menguji lonjakan pemasaran bersamaan dengan OTP, tugas duplikat, dan callback yang diurutkan ulang untuk membuktikan SLO dua detik dan pemulihan backlog."

Pembahasan mendalam langkah demi langkah

API ingress tidak memanggil provider SMS atau push secara sinkron. API ini mengautentikasi pemanggil, memvalidasi jenis notifikasi yang terkontrol, menetapkan versi templat, memvalidasi parameter minimal, dan menulis notifikasi beserta catatan outbox dalam satu transaksi basis data:

~~~text POST /v1/notifications { request_id, notification_type, recipients | audience_id, template_version, template_params, schedule_at, expire_at }

202 Accepted { notification_id, accepted_at } ~~~

request_id mendeduplikasi percobaan ulang pemanggil, notification_id mengidentifikasi satu notifikasi bisnis, dan delivery_id mengidentifikasi satu pengiriman saluran-pengguna. Ketiganya tidak dapat berupa satu pengidentifikasi yang sama karena satu notifikasi dapat disebarkan (fan-out) ke banyak pengguna dan saluran. Relai outbox hanya memublikasikan setelah transaksi ingress di-commit, menutup celah antara commit basis data dan publikasi pesan. Untuk kampanye 50 juta penerima, ingress menyimpan referensi snapshot audiens dan kursor; ingress tidak membuat 50 juta baris di dalam satu permintaan atau transaksi.

Layanan fan-out membaca snapshot dalam partisi dan membuat batch perencanaan kecil. Menjelang waktu pengiriman, layanan kebijakan memuat aturan jenis notifikasi dan preferensi pengguna saat ini, lalu mengevaluasi opt-out, jam tenang, ketersediaan saluran, kebijakan frekuensi, masa kedaluwarsa, dan urutan fallback. Jam tenang menggunakan zona waktu IANA pengguna dan menangani transisi daylight-saving time. Jika tidak ada zona waktu yang diketahui, produk menggunakan default eksplisit daripada secara diam-diam menggunakan waktu server. Tugas yang difilter menerima SUPPRESSED ditambah alasan yang dapat dibaca mesin sehingga tim dukungan dapat menjelaskan mengapa pesan tidak dikirim.

Data inti dapat dibagi menjadi tiga catatan:

~~~text Notification( notificationid, tenantid, notification_type, templateversion, scheduleat, expire_at )

Delivery( deliveryid, notificationid, user_id, channel, trafficclass, state, provider, providermessage_id, attemptcount, nextattemptat, stateversion )

DeliveryEvent( deliveryid, providereventid, eventtype, providertime, receivedat, rawpayloadref ) ~~~

Delivery adalah tampilan saat ini yang dimaterialisasi (materialized view); DeliveryEvent mempertahankan fakta tanda terima provider. Konten mentah dan data pribadi berada di penyimpanan terkontrol, dengan hanya referensi di tabel event. Jika provider menyediakan provider_event_id, terapkan keunikan (uniqueness). Jika tidak, lakukan hashing pada bidang tanda terima yang dinormalisasi untuk deduplikasi. Verifikasi tanda tangan webhook sebelum menulis event dan pertahankan bidang yang tidak dikenal secara kompatibel; bidang provider baru tidak boleh merusak callback yang valid.

Minimal, bedakan status-status berikut:

~~~text ACCEPTED -> PLANNED -> QUEUED -> SENDING -> PROVIDER_ACCEPTED | v DELIVERED -> READ

Terminal side states: SUPPRESSED, EXPIRED, FAILED_PERMANENT ~~~

Diagram ini mengekspresikan tahapan bisnis, bukan urutan kedatangan callback yang dijamin. Provider dapat mengirimkan delivered sebelum sent, dan webhook duplikat sering terjadi. Handler menambahkan event idempoten, lalu memperbarui proyeksi dengan tabel transisi yang dikunci berdasarkan saluran, status saat ini, dan event baru. sent yang terlambat tidak dapat menurunkan status SMS yang sudah berada di DELIVERED; saluran dengan tanda terima baca dapat maju dari DELIVERED ke READ. Event yang tidak terpetakan tetap berada di tabel mentah dan memicu peringatan (alert) alih-alih memaksakan status tebakan.

Data plane pengiriman memisahkan antrean berdasarkan saluran dan kelas lalu lintas, seperti sms.transactional, sms.bulk, dan push.transactional. Setiap grup memiliki metrik usia backlog, konkurensi konsumen, dan antrean percobaan ulang yang independen. Misalkan kontrak provider SMS mengizinkan 10.000 permintaan per detik. Penjadwal dapat melindungi 3.000 per detik untuk lalu lintas transaksional, membiarkan lalu lintas massal meminjam kapasitas yang tidak terpakai, dan mengambilnya kembali saat lalu lintas transaksi meningkat. Ini adalah contoh konfigurasi; nilai sebenarnya berasal dari kontrak provider dan uji beban. Penjadwalan adil per penyewa (per-tenant fair scheduling) mencegah satu kampanye menghabiskan anggaran massal, sementara penuaan (aging) mencegah pekerjaan normal kelaparan (starving) selamanya.

Antrean terpisah membutuhkan lebih banyak topik, koneksi, dan konfigurasi operasional daripada antrean tunggal dengan bidang prioritas, tetapi mereka mengisolasi backlog disk dan sumber daya konsumen. Pada skala yang lebih kecil dengan satu saluran, antrean bersama ditambah weighted fair scheduling bisa lebih sederhana. Ketika SLO transaksi dan batas waktu massal berbeda beberapa kali lipat, isolasi fisik lebih mudah dibuktikan. Dalam kedua desain tersebut, satu penjadwal saluran menegakkan kuota aktual provider. Masing-masing konsumen tidak boleh berasumsi bahwa mereka memiliki kuota penuh.

Pekerja saluran menerima tugas setidaknya-sekali dan secara atomik mengklaim percobaan di bawah delivery_id. Jika pengiriman sudah dalam status terminal, pekerja mengonfirmasi (acknowledge) tugas antrean. Jika tidak, pekerja memeriksa expire_at, merender templat, memanggil provider, dan menyimpan respons. Tugas antrean duplikat tidak dapat membuat catatan pengiriman kedua. Batas waktu eksternal masih memiliki tiga kemungkinan hasil: provider tidak menerima permintaan, menerimanya tetapi responsnya hilang, atau memiliki hasil pemrosesan yang tidak diketahui. Gunakan kembali kunci idempotensi provider jika ada. Tanpa fitur tersebut, tandai percobaan sebagai UNKNOWN dan lakukan rekonsiliasi melalui kueri provider atau tanda terima. Notifikasi kritis dapat dicoba kembali setelah bisnis secara eksplisit menerima risiko duplikasi; pemasaran biasanya dapat menunggu rekonsiliasi atau kedaluwarsa.

Klasifikasi kesalahan menentukan tindakan selanjutnya:

  • Parameter tidak valid, templat tidak valid, dan token perangkat yang dikonfirmasi tidak valid bersifat permanen. Pindahkan ke FAILED_PERMANENT dan nonaktifkan endpoint hanya jika buktinya mendukung. APNs 410 berarti token perangkat tidak lagi aktif untuk topik tersebut.
  • Respons HTTP 429, 5xx dari provider, dan kegagalan koneksi umumnya dapat dicoba ulang. Gunakan exponential backoff, full jitter, jumlah percobaan maksimum, dan batas waktu keseluruhan. Percobaan ulang tetap melewati kontrol kapasitas saluran sehingga pemulihan tidak menciptakan lonjakan kedua.
  • Kegagalan autentikasi atau konfigurasi akun adalah insiden platform. Jeda saluran provider yang terpengaruh dan beri peringatan; mencoba ulang setiap pesan akan memperbesar kegagalan.
  • OTP atau pengingat usang yang mencapai expire_at menjadi EXPIRED. Pemutaran ulang dead-letter tidak dapat memperpanjang masa kedaluwarsa aslinya atau menetapkan delivery_id baru untuk melewati deduplikasi.

Penerimaan provider tidak membuktikan pengiriman perangkat. APNs mengembalikan status dan apns-id untuk setiap POST; keberhasilan membuktikan keberhasilan tingkat permintaan. Firebase juga menghitung pengantrean atau serah terima ke APNs sebagai Sends. Provider SMS mungkin menawarkan status queued, sent, delivered, undelivered, dan read di kemudian waktu, dan webhook-nya bisa tidak berurutan. Oleh karena itu, API publik mengembalikan status berlapis ditambah status_reason. Laporan secara terpisah menghitung tingkat penerimaan, penerimaan-provider, pengiriman-teramati, dan pembacaan-teramati. Jika saluran tidak mengekspos suatu status, laporkan tidak diketahui daripada menghitungnya sebagai keberhasilan atau kegagalan.

Untuk skalabilitas, partisi tabel notifikasi dan pengiriman berdasarkan notification_id atau waktu, dan skalakan antrean kerja berdasarkan saluran, kelas, dan kunci partisi. Pekerjaan yang membutuhkan pengurutan per pengguna menggunakan kunci partisi pengguna yang stabil; tugas massal yang tidak berurutan dapat di-hash secara lebih merata. Menyimpan seluruh amplop logis 30 TB selama 30 hari dalam indeks online yang mahal tidaklah perlu. Simpan status pengiriman terbaru secara online, kompres dan arsipkan event lama, dan pertahankan hanya indeks yang diperlukan untuk kepatuhan dan dukungan. Perencanaan kapasitas secara terpisah menambahkan replika, indeks, amplifikasi tanda terima, dan penulisan percobaan ulang.

Uji penerimaan yang menentukan adalah "lonjakan massal tidak boleh menunda OTP." Pertahankan sekitar 232.000 tugas kampanye per detik, lalu tambahkan lalu lintas transaksi. Verifikasi bahwa p99 OTP dari penerimaan hingga penyerahan provider tetap di bawah dua detik dan backlog massal terkuras dalam jendela 15 menitnya. Masukkan respons 429 dan 5xx lalu konfirmasikan bahwa backoff tidak tersinkronisasi menjadi gelombang percobaan ulang. Kirimkan tugas antrean yang sama lebih dari sekali dan verifikasi bahwa tugas tersebut menggunakan kembali delivery_id asli. Kirim callback dalam urutan delivered -> sent -> delivered dan verifikasi bahwa status tidak pernah mengalami regresi. Cakup juga opt-out tepat sebelum pengiriman, transisi daylight-saving, dead letter yang kedaluwarsa, dan hasil provider yang tidak diketahui. Hasil skenario kegagalan tersebut membuat kata "andal" dapat diuji secara nyata.

Contoh jawaban berkualitas tinggi

"Saya akan mendefinisikan empat hasil terpisah: penerimaan platform yang tahan lama, penerimaan provider, pengiriman perangkat yang dapat diamati, dan pembacaan pengguna. API hanya menjanjikan yang pertama. API menulis notifikasi dan outbox, lalu mengembalikan 202. Fan-out bersifat asinkron, dan aturan opt-out terbaru, jam tenang, ketersediaan saluran, serta masa kedaluwarsa dievaluasi mendekati waktu pengiriman sebelum menetapkan delivery_id yang stabil.

Satu miliar tugas saluran per hari rata-rata sekitar 11.600 per detik, dengan puncak kampanye 20 kali lipat sekitar 232.000 per detik. OTP harus mencapai provider dalam waktu dua detik, sementara pemasaran dapat diratakan selama 15 menit. Oleh karena itu, saya akan memisahkan antrean dan konsumen berdasarkan saluran serta kelas transaksional, normal, dan massal, melindungi kapasitas provider untuk transaksi, dan membiarkan massal hanya meminjam kapasitas yang menganggur. Setiap penyewa juga mendapatkan bagian yang adil.

Pekerja mengasumsikan konsumsi setidaknya-sekali. Pekerjaan antrean duplikat mengklaim delivery_id yang sama. Kesalahan permanen dihentikan, sementara kegagalan 429, 5xx, dan jaringan menggunakan backoff dengan jitter yang dibatasi oleh batas waktu keseluruhan. Batas waktu provider mungkin telah menghasilkan efek samping eksternal. Saya menggunakan kembali kunci idempotensi provider jika tersedia; jika tidak, saya menandainya sebagai UNKNOWN dan melakukan rekonsiliasi alih-alih mengklaim exactly-once secara menyeluruh.

Tanda terima adalah event yang tidak dapat diubah (immutable) yang diproses melalui tabel transisi saluran, sehingga event terkirim yang terlambat tidak dapat menimpa status diterima. Uji peluncuran saya menggabungkan puncak pemasaran dengan lalu lintas OTP, lalu menyuntikkan pekerjaan duplikat, respons 429, batas waktu provider, callback yang tidak berurutan, dan opt-out di menit-menit terakhir. Metrik utamanya adalah usia antrean per kelas, latensi penyerahan provider, kelas kegagalan, jumlah UNKNOWN, dan percobaan regresi status."

Kesalahan umum

  • Mencatat status terkirim saat API mengembalikan 202 → hanya penerimaan tahan lama yang selesai → pisahkan ACCEPTED, PROVIDER_ACCEPTED, DELIVERED, dan READ.
  • Menempatkan semua pekerjaan dalam satu antrean prioritas → backlog massal masih berbagi disk, konsumen, dan kuota provider → isolasi sumber daya berdasarkan saluran dan kelas lalu lintas, dengan peminjaman terkontrol.
  • Membiarkan lalu lintas kritis melewati semua batas → lalu lintas OTP yang tidak normal dapat membebani platform dan provider → berikan lalu lintas transaksi batas atasnya sendiri, peringatan, dan keadilan antar-penyewa.
  • Mengklaim pengguna menerima tepat satu kali karena antrean bersifat setidaknya-sekali → panggilan provider mungkin berhasil sementara responsnya hilang → buat pekerjaan internal idempoten berdasarkan delivery_id, rekonsiliasi hasil eksternal yang tidak diketahui, dan ungkapkan risiko duplikasi.
  • Mencoba ulang setiap kesalahan secara langsung → kesalahan permanen membuang kapasitas dan kegagalan 429/5xx menciptakan badai percobaan ulang → klasifikasikan kegagalan permanen, sementara, pembatasan (throttling), dan konfigurasi platform; lakukan backoff pada kasus sementara dengan jitter.
  • Menimpa status saat ini secara langsung → callback yang tidak berurutan dapat mengubah status diterima kembali menjadi terkirim → simpan event idempoten terlebih dahulu, lalu perbarui proyeksi dengan tabel transisi saluran.
  • Membekukan preferensi pengguna pada saat penjadwalan → pengguna yang memilih keluar belakangan masih menerima pesan pemasaran → periksa kembali preferensi dan aturan kepatuhan menjelang pengantrean saluran.
  • Menetapkan ID baru selama pemutaran ulang dead-letter → deduplikasi dilewati dan notifikasi usang dapat terkirim → gunakan kembali delivery_id asli dan periksa kembali opt-out serta masa kedaluwarsa.
  • Menggunakan pengurutan global demi kesederhanaan → pengguna yang tidak terkait saling memblokir dan satu partisi membatasi throughput → pertahankan hanya pengurutan lokal yang benar-benar dibutuhkan oleh jenis notifikasi pengguna.

Pertanyaan lanjutan dan tanggapan

Lanjutan 1: Lima puluh juta pengguna menginginkan kampanye pada pukul 09.00 waktu setempat. Apa yang berubah?

Selama fan-out, buat wadah waktu (time buckets) berdasarkan zona waktu IANA dan tanggal lokal, lalu hasilkan batch yang dikontrol lajunya sebelum jendela waktu mereka. Tambahkan jitter di dalam setiap jendela target daripada merilis setiap tugas tepat pada jam tersebut. Tentukan perilaku produk untuk waktu lokal yang tidak ada atau berulang selama perubahan daylight-saving time, seperti beralih ke saat valid berikutnya dan mengirim tidak lebih dari sekali per hari. "Pukul 09.00" harus diartikan sebagai jendela penyerahan ke provider karena tampilan perangkat tetap berada di luar kendali platform.

Lanjutan 2: Provider mengembalikan respons sukses tetapi tidak pernah mengirimkan tanda terima pengiriman. Apa statusnya?

Pertahankan PROVIDER_ACCEPTED; jangan menaikkannya ke DELIVERED. Setelah jendela observasi saluran berakhir, sistem dapat mengekspos DELIVERY_UNKNOWN untuk operasi, tetapi status tidak diketahui tidak boleh dihitung sebagai kegagalan. Jika provider menawarkan API kueri atau laporan agregat, lakukan rekonsiliasi secara asinkron dan ungkapkan keterlambatan serta cakupan data tersebut.

Lanjutan 3: Bagaimana jika callback delivered tiba sebelum sent?

Tambahkan kedua event secara idempoten. Proyeksi dapat maju dari PROVIDER_ACCEPTED atau SENDING ke DELIVERED; sent yang datang belakangan akan memperkaya riwayat audit tanpa menurunkan status. Jika provider yang sama kemudian mengeluarkan pencabutan atau kesalahan yang terdokumentasi, modelkan transisi khusus provider tersebut secara eksplisit alih-alih menebak urutan dari bilangan bulat global.

Lanjutan 4: Bisakah dua provider SMS melakukan failover secara otomatis?

Failover masuk akal setelah penolakan eksplisit, kegagalan sebelum koneksi, atau circuit breaker di seluruh provider terpicu. Batas waktu setelah pengiriman mungkin berarti provider utama telah berhasil mengirimkan, sehingga failover langsung meningkatkan risiko SMS duplikat. OTP dapat melakukan failover jika pemilik biaya dan keamanan secara eksplisit menerima risiko tersebut, sementara pemasaran biasanya menunggu kueri, tanda terima, atau kedaluwarsa. Konfigurasikan keputusan ini berdasarkan jenis notifikasi daripada secara global.

Lanjutan 5: Bagaimana Anda membuktikan bahwa isolasi prioritas berfungsi?

Gunakan uji beban tertutup yang menggabungkan tiga tekanan: backlog massal yang berkelanjutan, penyewa yang sibuk (hot tenant), dan respons 429 provider yang berulang. Penerimaan mensyaratkan p99 penyerahan provider OTP di bawah dua detik, tidak ada pekerjaan massal pada konsumen transaksi, tingkat provider agregat berada dalam konfigurasi, dan pemulihan massal dalam batas waktu 15 menit. Kemudian gagalkan satu partisi konsumen transaksi dan konfirmasikan bahwa instans yang tersisa mengambil alih kapasitas yang dilindungi. Throughput rata-rata saja tidak dapat membuktikan isolasi.

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