Gesaan dan skop
Klien menghantar arahan cipta pesanan. Pelayan mungkin melakukan komit pesanan tersebut, kemudian terputus sambungan sebelum menghantar respons. Klien tidak dapat mengetahui keputusannya dan mencuba semula dengan Idempotency-Key yang sama. Reka bentuk kontrak permintaan, rekod tahan lama, kawalan keserentakan dan aliran pemulihan, serta nyatakan kegagalan mana yang selamat untuk dicuba semula. Kemahiran teras adalah sempadan kesan sampingan, keatoman (atomicity) dan keadaan kegagalan yang boleh diterangkan, jadi ini tergolong dalam backend.
Perkara yang dinilai oleh penemu duga
Jawapan yang kukuh membezakan antara "permintaan tidak pernah sampai", "selesai tetapi respons hilang" dan "masih diproses", kemudian memilih memainkan semula (replay), carian status atau respons sedang diproses. Ia juga merangkumi kunci-sama/parameter-berbeza, permintaan pertama yang serentak, kegagalan storan, tempoh luput, penghalaan berbilang wilayah dan kesan hiliran berbanding hanya menyebut "letakkan kunci dalam Redis".
Soalan untuk dijelaskan terlebih dahulu
- Adakah kunci dijana oleh klien untuk satu arahan logik, atau diterbitkan oleh pelayan daripada medan perniagaan?
- Medan permintaan manakah yang terikat pada kunci, dan ralat apakah yang mewakili ketidakpadanan?
- Adakah penulisan pesanan dan rekod keidempotetan berada dalam satu transaksi pangkalan data? Adakah pembayaran mempunyai kontrak keidempotetan tersendiri?
- Berapa lamakah klien boleh menunggu, berapa lama kunci disimpan, dan adakah tempoh luput boleh mencipta pesanan kedua?
- Adakah perkhidmatan ini satu wilayah atau berbilang wilayah, dan storan manakah yang berwibawa bagi setiap laluan masuk?
Rangka kerja jawapan 30 saat
"Klien mencipta satu kunci yang stabil untuk satu arahan logik dan menggunakannya semula semasa percubaan semula. Pelayan menguatkuasakan kekangan keunikan yang tahan lama ke atas penyewa (tenant), operasi dan kunci, menyimpan cap jari permintaan, keadaan dan respons akhir. Permintaan pertama menuntut processing secara atomik dan menjalankan transaksi pesanan; permintaan kunci-sama/parameter-sama akan menunggu atau dimainkan semula, manakala ketidakpadanan akan ditolak. Selepas ranap sistem, pulihkan daripada transaksi dan bukti hiliran. Buat pertanyaan kesan sampingan yang tidak diketahui sebelum melakukan pampasan, jangan sekali-kali mencuba semula secara membuta tuli. Pengekalan mesti meliputi tetingkap percubaan semula, dan metrik mesti membuktikan sifar kesan sampingan pendua."
Penyelesaian langkah demi langkah
Kontrak harus memerlukan kunci yang tidak kosong dan terikat yang kekal tidak berubah sepanjang percubaan semula bagi satu arahan logik. Pelayan menyimpan (tenant_id, operation, idempotency_key) yang unik bersama-sama dengan cincangan permintaan yang dinormalkan, keadaan, ID sumber, kod respons, badan respons dan tempoh luput. Cincangan ini menghalang penggunaan semula kunci yang sama secara tidak sengaja untuk arahan yang berbeza.
Permintaan pertama harus memasukkan rekod processing yang tahan lama dan mencipta pesanan dalam satu transaksi tempatan, atau menggunakan log transaksi yang menghubungkan kedua-duanya secara jelas. Apabila berlaku konflik keunikan, baca rekod sedia ada: mainkan semula respons yang disimpan untuk succeeded, kembalikan ralat perniagaan yang sama untuk failed, dan tunggu sebentar atau kembalikan status sedang diproses untuk processing. Kunci dalam memori sahaja akan gagal semasa mula semula dan merentasi replika.
Keserentakan ditentukan oleh kekangan keunikan dan kemas kini bersyarat. Hanya permintaan yang memiliki rekod penciptaan boleh memindahkan processing kepada succeeded; sertakan versi atau keadaan yang dijangkakan dalam kemas kini supaya dua pekerja tidak dapat melakukan komit. Jika transaksi pesanan berjaya sebelum proses ranap, percubaan semula akan membaca succeeded dan memainkannya semula. Jika transaksi diundur balik (rolled back), percubaan semula boleh dilaksanakan dengan selamat.
Kesan hiliran mewujudkan tetingkap di mana hasil tempatan tidak diketahui sedangkan kesan jauh mungkin telah berjaya. Pembayaran, penghantaran dan mesej harus menggunakan ID operasi perniagaan yang sama dengan kontrak keidempotetan hiliran, serta mengekalkan permintaan dan hasil. Tanpa keidempotetan hiliran, buat pertanyaan penyelarasan atau terbitkan melalui peti keluar (outbox) dan cuba semula daripada pekerja; jangan sekali-kali mengenakan caj lagi hanya kerana panggilan tempatan tamat masa.
Rekod yang sedang diproses memerlukan pemulihan. Simpan pajakan (lease) dan degupan jantung (heartbeat); pekerja pemulihan menyemak transaksi pesanan, status hiliran atau log transaksi sebelum mara ke keadaan terminal. Jika bukti tidak mencukupi, tandakan unknown dan hantarkannya untuk penyelarasan daripada menganggapnya sebagai kegagalan. Mesin keadaan tidak boleh memindahkan succeeded kembali kepada processing.
Tempoh luput mesti sepadan dengan risiko perniagaan. Kekalkan rekod sepanjang percubaan semula maksimum klien, giliran percubaan semula rangkaian dan tetingkap pampasan. Menggunakan semula kunci yang telah luput harus mengembalikan key_expired yang eksplisit, bukan mencipta pesanan kedua secara senyap. Badan respons lama boleh dimampatkan hanya jika ringkasan audit dan keunikan peringkat sumber kekal.
Dalam penggunaan berbilang wilayah, halakan kunci logik ke satu storan berwibawa atau kuasakan kekangan keunikan global dengan replikasi segerak. Jangan laksanakan sekali lagi pada replika lain semata-mata kerana bacaan processing tertangguh. Ukur konflik kunci, konflik parameter, tamat masa sedang diproses, respons main semula, keadaan tidak diketahui, sekatan sumber pendua dan perbezaan penyelarasan.
Model jawapan berkualiti tinggi
"Saya mentakrifkan kunci keidempotetan sebagai identiti stabil bagi satu arahan cipta logik, bukan ID permintaan baharu pada setiap percubaan semula HTTP. Pelayan menguatkuasakan kekangan keunikan yang tahan lama ke atas penyewa, operasi dan kunci, menyimpan cincangan permintaan, keadaan, ID sumber, respons dan tempoh luput. Permintaan pertama menuntut processing secara atomik dan mencipta pesanan; permintaan kunci-sama/parameter-sama dimainkan semula atau menunggu, dan ketidakpadanan ditolak.
Saya mengekalkan penulisan pesanan dan rekod keidempotetan dalam satu transaksi dan menghantar ID operasi yang sama kepada pembayaran atau kesan hiliran yang lain. Jika respons hilang, percubaan semula membaca hasil yang disimpan; jika keadaan tempatan tidak diketahui, saya membuat pertanyaan rekod hiliran dan penyelarasan daripada meneka dengan satu lagi POST. Pekerja yang dipajak memulihkan processing yang tersekat, dan peralihan bersyarat hanya membawa kepada succeeded, failed atau unknown. Pengekalan merangkumi percubaan semula dan pampasan. Saya menyuntik permintaan pertama yang serentak, proses ranap, kehilangan respons dan kelewatan rentas wilayah, serta memastikan sifar pesanan atau caj pendua."
Kesilapan biasa
- Menjana kunci baharu untuk setiap percubaan semula → pelayan tidak dapat mengenal pasti satu arahan logik → gunakan semula kunci asal.
- Menggunakan hanya kunci dalam memori atau hos tunggal → mula semula dan replika kehilangan penyahduplikasian → kuasakan keunikan yang tahan lama.
- Memainkan semula hasil untuk muatan (payload) yang berbeza → menyembunyikan pepijat klien → simpan cap jari dan tolak ketidakpadanan.
- Memanggil perkhidmatan hiliran serta-merta selepas merekodkan
processing→ ranap sistem menyebabkan kesannya tidak dapat diketahui → gunakan transaksi, peti keluar atau keidempotetan hiliran. - Mengenakan caj lagi selepas tamat masa → caj jauh mungkin telah berjaya → buat pertanyaan dan selaraskan terlebih dahulu.
- Menganggap rekod yang tersekat sebagai gagal dan menjalankan semula → mencipta sumber kedua → kumpulkan bukti semasa pemulihan.
- Meluputkan kunci terlalu cepat → percubaan semula yang tertangguh mencipta pendua → selaraskan pengekalan dengan risiko dan tetingkap percubaan semula.
- Hanya menguji panggilan bersiri → keadaan perlumbaan (race conditions) masih menghasilkan penulisan berganda → uji keserentakan kunci yang sama, ranap sistem dan penghalaan berbilang wilayah.
Soalan susulan dan respons
Soalan susulan 1: Mengapa tidak menggunakan ID pesanan sebagai kunci unik?
ID pesanan biasanya hanya wujud selepas pelayan mencipta sumber tersebut, jadi ia tidak dapat meliputi tetingkap masa sebelum respons pertama diberikan. Kunci keidempotetan wujud sebelum kesan sampingan berlaku dan mengikat percubaan semula kepada satu arahan logik.
Soalan susulan 2: Bagaimana jika muatan berubah dengan kunci yang sama?
Cincang badan permintaan yang dinormalkan dan pengepala yang berkaitan. Cap jari yang berbeza akan mengembalikan ralat konflik parameter tanpa kesan sampingan baharu; klien mesti mencipta kunci baharu untuk arahan baharu.
Soalan susulan 3: Bagaimana jika permintaan pertama kekal dalam processing selama-lamanya?
Gunakan pajakan, degupan jantung dan imbasan tamat masa. Pekerja pemulihan menyemak transaksi tempatan, hasil hiliran dan log mesej; hanya bukti yang mencukupi akan memajukan keadaan, jika tidak ia menjadi unknown untuk penyelarasan.
Soalan susulan 4: Bolehkah Redis menjadi satu-satunya storan keidempotetan?
Jika pangkalan data memiliki kesan sampingan tersebut, pengusiran (eviction) data Redis, kegagalan atau kelengahan replikasi boleh menghapuskan sempadan keselamatan. Redis boleh menyelaraskan kerja jangka pendek, tetapi keadaan akhir dan keunikan harus berada dalam storan tahan lama yang konsisten dengan penulisan perniagaan.
Soalan susulan 5: Apakah yang sepatutnya berlaku selepas kunci luput?
Jangan terima kunci lama secara senyap. Kembalikan ralat luput dan arahkan klien untuk membuat pertanyaan bagi pesanan asal atau mencipta arahan baharu; keunikan perniagaan peringkat sumber harus menyediakan perlindungan lain.
Soalan susulan 6: Bagaimanakah anda membuktikan ketiadaan kesan pendua?
Hantar kunci yang sama secara serentak, tamatkan proses sebelum dan selepas komit, hilangkan respons dan tamatkan masa panggilan hiliran. Semak keunikan sumber, ID operasi, respons yang dimainkan semula, log peralihan keadaan dan penyelarasan. Asersinya adalah paling banyak satu kesan sampingan yang berjaya bagi setiap kunci logik.
Soalan susulan 7: Adakah kunci keidempotetan merupakan pemprosesan tepat sekali (exactly-once)?
Tidak. Ia membolehkan satu perkhidmatan mengenali arahan pendua; ia tidak menjadikan rangkaian rentas perkhidmatan sebagai tepat sekali. Transaksi, penghantaran peti keluar, keidempotetan hiliran, pertanyaan dan penyelarasan masih diperlukan, dengan hasil unknown yang eksplisit.