Gesaan dan skop
Soalan ini menguji sama ada jurutera backend boleh meletakkan kawalan keserentakan pada sempadan HTTP. Terangkan perbezaan antara pengesahan cache dan perlindungan penulisan, cara pelayan membandingkan tag entiti, status yang dikembalikannya, dan cara penulisan pangkalan data serta pengepala respons kekal sejajar.
Perkara yang dinilai oleh penemu duga
- Sama ada anda memahami maksud berbeza bagi ETag, If-Match dan If-None-Match.
- Sama ada pengesah kukuh (strong validator) melindungi penulisan daripada versi lapuk.
- Sama ada 412, 428 dan 409 mempunyai sempadan prasyarat dan konflik perniagaan yang berbeza.
- Sama ada anda mengambil kira cache proksi, percubaan semula, pengesahan (authorization) dan keterlihatan replika.
Soalan penjelasan untuk ditanya terlebih dahulu
Sahkan sama ada kemas kini menggantikan keseluruhan sumber atau hanya medan tertentu, sama ada klien mesti menghantar versi, sama ada penyuntingan luar talian dan penggabungan (merge) disokong, sama ada ETag mewakili perwakilan penuh atau versi perniagaan, dan sama ada bacaan dan penulisan melalui cache, pengimbang beban (load balancer) atau beberapa replika pangkalan data.
Struktur jawapan 30 saat
Kembalikan ETag bersama setiap perwakilan sumber. Wajibkan If-Match pada mutasi, bandingkannya dengan versi semasa di dalam sempadan penulisan, dan kembalikan 412 jika tidak sepadan atau 428 apabila prasyarat yang diperlukan tiada. Jika berjaya, tingkatkan (increment) versi dan kembalikan ETag baharu. GET dengan If-None-Match boleh mengembalikan 304, tetapi pengesahan cache tidak melindungi penulisan.
Jawapan mendalam
1. Asingkan pengesahan cache daripada perlindungan penulisan
If-None-Match berguna untuk pengesahan cache GET: perwakilan yang tidak berubah boleh menghasilkan 304. If-Match memerlukan perwakilan semasa sepadan dan lazim digunakan pada PUT, PATCH atau DELETE. Cache hit tidak memberikan kebenaran untuk menulis ganti sumber semasa; arah perbandingan dan tingkah laku kegagalan adalah berbeza.
2. Pilih ETag yang selamat untuk dibandingkan
Gunakan ETag kukuh (strong ETag) untuk perlindungan penulisan supaya bait atau versi yang ditentukan sepadan dengan tepat. ETag lemah (weak ETag) sesuai untuk perwakilan cache yang setara secara semantik dan tidak seharusnya membenarkan kemas kini yang tepat. Tag tersebut tidak sepatutnya mendedahkan jujukan dalaman atau data sensitif; terbitkan ia daripada perwakilan kanonikal dan versi dengan salt yang tidak dapat diramalkan, selepas menggunakan penapisan kebenaran (authorization filtering).
3. Kekalkan perbandingan dan kemas kini dalam satu sempadan
Baca versi semasa, bandingkan If-Match, dan kemas kini dalam satu penulisan pangkalan data bersyarat seperti UPDATE ... WHERE id = ? AND version = ?. Sifar baris yang terjejas bermaksud 412; kemas kini yang berjaya akan meningkatkan versi dan menghasilkan ETag baharu. Jangan buat pertanyaan dalam kod aplikasi dan kemudian mengeluarkan penulisan tanpa syarat.
4. Reka bentuk respons kegagalan dan laluan percubaan semula
Kembalikan 428 apabila prasyarat yang diperlukan tiada, 412 apabila ETag tidak sepadan, dan 409 untuk konflik keadaan perniagaan yang berasingan. Sertakan perwakilan semasa atau petunjuk untuk mengambil semula, tetapi jangan menulis ganti secara senyap bagi pihak klien. Selepas 412, klien harus melakukan GET sekali lagi, menunjukkan perbezaan (diff), atau menggunakan penggabungan medan yang jelas dan mencuba semula dengan ETag baharu; percubaan semula automatik memerlukan percubaan yang terhad dan keidempotenan yang jelas.
5. Kendalikan cache, replika dan operasi
Bacaan yang mencipta ETag mesti melihat penulisan terkini, atau sistem mesti mentakrifkan kelewatan baca-selepas-tulis (read-after-write delay) yang terhad. Proksi mesti memajukan ETag, If-Match dan If-None-Match dengan betul, berserta kawalan cache yang sesuai untuk sumber sensitif. Log ID permintaan, versi lama dan baharu, hasil serta kadar konflik untuk mengesan klien yang menggunakan perwakilan lapuk atau replika yang ketinggalan.
Contoh jawapan yang kukuh
Saya akan mengembalikan strong ETag dengan setiap GET, yang diterbitkan daripada perwakilan kanonikal dan versi. PUT, PATCH dan DELETE memerlukan If-Match; pangkalan data melakukan kemas kini bersyarat versi, mengembalikan 412 apabila tiada baris yang sepadan. Prasyarat yang tiada mengikut dasar antara muka dan mengembalikan 428, manakala kejayaan akan meningkatkan versi dan mengembalikan ETag baharu. GET dengan If-None-Match yang sepadan mengembalikan 304 untuk penjimatan cache sahaja. Selepas 412, klien membaca semula, menunjukkan diff atau melakukan penggabungan medan yang jelas, dan mencuba semula dengan tag baharu. Bacaan merentasi replika mesti melihat versi semasa, dan proksi mesti memajukan pengepala bersyarat. Pantau konflik, permintaan versi lapuk dan kelengahan replika.
Kesilapan biasa
- Hanya membandingkan cap masa klien dan mengabaikan herotan jam (clock skew) atau perbezaan perwakilan.
- Menggunakan weak ETag untuk membenarkan penulisan yang tepat.
- Menanyakan versi terlebih dahulu dan kemudian menulis tanpa syarat, meninggalkan keadaan berlumba (race condition).
- Menganggap 412, 409 dan 428 sebagai satu ralat generik yang tidak memberi langkah seterusnya kepada klien.
- Membiarkan pelayan menulis ganti konflik secara senyap dan menghilangkan suntingan klien.
- Menjana tag hanya pada nod aplikasi tanpa mempertimbangkan keterlihatan cache dan replika.
Soalan susulan
Bolehkah ETag menjadi versi auto-inkremen pangkalan data?
Ia boleh menjadi input dalaman, tetapi kodkan nilai tersebut untuk HTTP dan elakkan daripada mendedahkan maklumat perniagaan yang sensitif. Jika perwakilan berubah mengikut penapisan medan atau kebenaran, jana tag tersebut pada sempadan perwakilan berkenaan.
Bolehkah dua medan PATCH yang tidak bertindih digabungkan secara automatik?
Tawarkan protokol penggabungan peringkat medan yang jelas, tetapi tetap sahkan ETag mana yang digunakan oleh klien. Terbitkan peraturan gabung dan tidak gabung serta audit keputusan tersebut; medan yang berbeza tidak menjadikan setiap konflik perniagaan selamat untuk diabaikan.
Mengapa tidak mengembalikan 409 sahaja?
412 bermaksud prasyarat gaya If-Match gagal, 428 meminta klien menyediakannya, dan 409 menerangkan konflik berasingan dengan keadaan sumber semasa atau operasi perniagaan. Perbezaan ini memberitahu klien sama ada perlu mengambil semula, menambah pengepala atau menukar tindakan.
Bagaimanakah anda mengelakkan penulisan lapuk melalui CDN?
Halakan mutasi ke asal yang berwibawa (authoritative origin) dan gunakan cache untuk bacaan. Majukan pengepala bersyarat mengikut spesifikasi, batalkan entri yang terjejas selepas kemas kini berjaya atau hadkan kelapukan, dan pantau perbezaan antara versi asal dengan tag sisi (edge tag).