Topik temu duga representatif

Temu Duga Reka Bentuk Sistem: Bagaimanakah anda membina penghantaran webhook yang selamat daripada serangan ulang main (replay-safe)?

Reka bentuk sistemSukar
Pasukan Editorial Offer.ccDiterbitkan Dikemas kini

Soalan

Reka bentuk platform webhook yang menghantar peristiwa pembayaran kepada ribuan titik akhir (endpoints) pelanggan. Ia mesti bertahan daripada tamat masa (timeouts), penghantaran pendua, serangan ulang main (replay attacks), dan pelanggan yang berada di luar talian selama berjam-jam.

Senario dan penetapan

Pengeluar peristiwa mengeluarkan peristiwa perniagaan ke titik akhir HTTP luaran. Platform mesti mengekalkan peristiwa secara tahan lasak, menghantar sekurang-kurangnya sekali (at least once), memastikan pendua selamat dikendalikan, dan memberikan setiap penyewa kawalan percubaan semula dan ulang main (replay) yang jelas.

Perkara yang diuji oleh penemu duga

  • Memilih jaminan penghantaran yang eksplisit dan bukannya menjanjikan tepat sekali (exactly once) melalui HTTP.
  • Mengasingkan penyerapan (ingestion), penjadualan, percubaan penghantaran, dan kesan sampingan pihak pelanggan.
  • Menggabungkan ID peristiwa, cap masa tandatangan, dasar percubaan semula, pengendalian dead-letter, dan keadilan (fairness).

Soalan penjelasan sebelum menjawab

  • Apakah volum peristiwa, saiz muatan (payload), bilangan titik akhir, dan kelewatan penghantaran maksimum?
  • Adakah susunan peristiwa diperlukan bagi setiap penyewa, setiap titik akhir, atau tidak langsung?
  • Bolehkah pengguna memproses peristiwa secara idempoten, dan berapa lamakah keadaan penyahduplikasian mesti disimpan?
  • Apakah keperluan ulang main, pemadaman, privasi, dan audit yang dikenakan ke atas muatan?

Kerangka jawapan 30 saat

Saya akan mengekalkan peristiwa tak berubah (immutable) dengan ID yang stabil, memasukkan percubaan penghantaran ke dalam barisan gilir, dan kembali dengan pantas daripada laluan penerima. Pekerja (workers) menandatangani muatan mentah bersama cap masa, menggunakan pengunduran eksponen (exponential backoff) dengan jitter, dan mengklasifikasikan respons kepada kegagalan yang boleh dicuba semula dan kegagalan terminal. Pengguna menyahduplikasi mengikut ID peristiwa sebelum melaksanakan kesan sampingan. Penjadual bagi setiap penyewa, pemutus litar (circuit breaker), dan barisan gilir dead-letter menghalang satu titik akhir luar talian daripada menjejaskan yang lain; ulang main mencipta percubaan baharu tanpa mengubah identiti peristiwa asal.

Analisis mendalam langkah demi langkah

1. Jadikan peristiwa tahan lasak terlebih dahulu

Tulis peristiwa perniagaan dan rekod penghantarannya secara transaksi atau melalui peti keluar (outbox) yang boleh dipercayai. Rekod penghantaran menyimpan penyewa, titik akhir, ID peristiwa, bilangan percubaan, masa percubaan seterusnya, dan status. Kegagalan sistem (crash) selepas menghantar tetapi sebelum merekodkan kejayaan sememangnya dijangka; ia menghasilkan percubaan lain, jadi pengguna mesti bertoleransi terhadap pendua.

2. Sahkan dan tandatangan secara selamat

Tandatangani bait mentah yang tepat berserta cap masa, dan sertakan ID peristiwa dalam mesej yang ditandatangani. Stripe mendokumenkan tandatangan bercap masa untuk mengehadkan serangan ulang main. Pengguna mengesahkan tandatangan sebelum menghuraikan (parsing), menolak cap masa di luar toleransi yang dikonfigurasikan, dan memutar kunci rahsia tanpa membatalkan peristiwa yang sudah berada dalam barisan gilir secara tidak sengaja.

3. Klasifikasikan respons dan cuba semula

Kendalikan tamat masa rangkaian, kegagalan sambungan, dan respons 5xx terpilih sebagai boleh dicuba semula. Kendalikan pengesahan yang tidak betul, versi peristiwa yang tidak disokong, dan kebanyakan respons 4xx sebagai terminal atau disemak oleh pengendali. Gunakan pengunduran eksponen dengan jitter, tetingkap percubaan maksimum, dan status dead-letter. Jangan cuba semula tanpa had terhadap titik akhir yang gagal secara kekal.

4. Jadikan pendua dan ulang main eksplisit

Pengguna menyimpan ID peristiwa yang telah diproses dengan kekangan keunikan yang tahan lasak dan melakukan komit rekod tersebut bersama kesan sampingan perniagaan jika boleh. Ulang main manual menggunakan semula muatan peristiwa yang tidak berubah dan merekodkan percubaan penghantaran baharu, manakala papan pemuka membezakan penghantaran asal, percubaan semula automatik, dan ulang main oleh pengendali. Kesan sampingan exactly-once memerlukan transaksi di pihak pengguna; rangkaian itu sendiri hanya menyediakan penghantaran at-least-once.

5. Skalakan tanpa kebuluran sumber merentas penyewa (cross-tenant starvation)

Bahagikan (partition) barisan gilir mengikut penyewa atau titik akhir, laksanakan had konkurensi dan kadar bagi setiap penyewa, dan tempah kapasiti untuk penyewa yang sihat. Pemutus litar menjeda titik akhir selepas kegagalan berulang. Metrik harus merangkumi usia peristiwa tertunda yang paling lama, kependaman kejayaan, taburan percubaan, kadar pendua, kegagalan tandatangan, dan volum dead-letter.

Contoh jawapan berkualiti tinggi

“Saya akan mengekalkan setiap peristiwa dengan ID yang stabil sebelum menjadualkan penghantaran dan menjanjikan semantik at-least-once. Setiap percubaan menandatangani muatan mentah dengan ID peristiwa dan cap masa. Pekerja mengklasifikasikan tamat masa dan respons 5xx untuk percubaan semula dengan jitter, manakala respons 4xx terminal dipindahkan ke dead letter. Pengguna menyahduplikasi ID peristiwa di dalam transaksi kesan sampingan mereka. Barisan gilir setiap penyewa, pemutus litar, amaran berasaskan usia peristiwa, dan aliran kerja ulang main menghalang pelanggan luar talian daripada memonopoli sumber penyewa lain dan menjadikan pemulihan boleh diaudit.”

Kesilapan lazim

  • Menjanjikan exactly-once melalui HTTP → kegagalan sistem menghasilkan keputusan yang kabur → nyatakan at-least-once dan wajibkan pengguna yang idempoten.
  • Menandatangani JSON yang dihuraikan dan bukannya bait mentah → pemformatan yang serupa boleh gagal dalam pengesahan → tandatangani dan sahkan bait muatan yang tepat.
  • Mencuba semula setiap 4xx selama-lamanya → kegagalan kekal menggunakan kapasiti → klasifikasikan ralat dan masukkan kes terminal ke dalam dead-letter.
  • Menggunakan satu barisan gilir global → satu penyewa boleh menyebabkan kebuluran sumber untuk semua → bahagikan, hadkan kadar, dan peruntukkan kapasiti setiap penyewa.

Soalan susulan dan jawapan

Berapa lamakah keadaan penyahduplikasian patut disimpan?

Sekurang-kurangnya sepanjang tempoh percubaan semula automatik dan tetingkap ulang main yang disokong, ditambah margin keselamatan. Jika ulang main boleh berlaku beberapa bulan kemudian, simpan lejar peristiwa yang padat atau wajibkan pengguna memilih identiti ulang main dan dasar pengekalan secara eksplisit.

Patutkah ulang main menerima ID peristiwa baharu?

Biasanya tidak: identiti peristiwa perniagaan kekal stabil, manakala percubaan penghantaran mendapat ID dan rekod auditnya sendiri. Ini membolehkan pengguna mengenali ulang main sebagai peristiwa yang sama dan mengelakkan kesan perniagaan pendua.

Bagaimana jika pengguna mengembalikan 200 sebelum kesan sampingannya dikomit?

Kontrak pengguna telah dilanggar; platform tidak dapat membuat kesimpulan kejayaan daripada respons tersebut. Pengguna harus memberikan perakuan (acknowledge) selepas penerimaan yang tahan lasak, menggunakan peti masuk (inbox) atau rekod penyahduplikasian bertransaksi, dan menyediakan penyesuaian (reconciliation) untuk hasil yang kabur.

Sumber awam

Soalan berkaitan

Alat temu duga berkaitan

Gunakan Jawab untuk jawapan reka bentuk sistem

Jelaskan keperluan terlebih dahulu, kemudian teruskan dengan skala, seni bina, pilihan komponen dan pertukaran (trade-off).

Lihat alat