Prompt dan Konteks Berkenaan
Reka bentuk penghad kadar untuk platform API pelbagai penyewa: penyewa percuma mendapat 100 permintaan seminit, penyewa berbayar mendapat 10,000, dan platform berjalan merentasi pelbagai instans aplikasi dan rantau. Bandingkan algoritma dan terangkan keadaan dikongsi, respons 429, penurunan fungsi kegagalan, dan pengesahan.
Ini sesuai untuk temu duga bahagian belakang (backend), platform, dan reka bentuk sistem. Rekod temu duga awam membentangkan masalah pengekodan token-bucket bagi setiap pengguna dengan pengisian semula berasaskan masa; bahan reka bentuk sistem menganggap pengehadan kadar sebagai perbincangan standard API pelbagai penyewa. Kemahiran teras adalah keadaan dikongsi, dasar penyewa, dan perlindungan trafik—bukan menghafal tetapan penyedia awan tertentu.
Perkara yang Dinilai oleh Penemu Duga
- Sama ada anda membezakan kadar purata, kapasiti lonjakan (burst), keadilan penyewa, dan perlindungan global.
- Sama ada anda boleh menerangkan sempadan dan kos token bucket, fixed window, dan sliding window.
- Sama ada keadaan dikongsi dikemas kini secara atomik merentas instans sementara hot key, pemecahan bahagian (partitions), dan jam ditangani.
- Sama ada respons 429, petunjuk percubaan semula, penurunan fungsi, dan telemetri menghalang penghad daripada menjadi titik kegagalan tunggal.
Soalan Penjelasan Sebelum Menjawab
- Adakah subjek berupa kunci API, penyewa, pengguna, IP, atau gabungan? Bagaimanakah permintaan tanpa nama dikumpulkan?
- Adakah dasarnya merupakan kadar purata, sliding window yang ketat, atau lonjakan terkawal? Adakah terdapat juga kuota harian?
- Adakah pelbagai rantau memerlukan penguatkuasaan global yang tepat, atau adakah lebihan jangka pendek boleh diterima demi ketersediaan?
- Patutkah permintaan yang ditolak menerima 429 serta-merta atau memasuki barisan terikat (bounded queue)? Bolehkah kebergantungan bertolak ansur dengan lonjakan sama sekali?
Rangka Jawapan 30 Saat
Saya akan meletakkan perlindungan IP kasar dan tidak disahkan di gerbang (gateway), kemudian menguatkuasakan dasar peka-penyewa dalam lapisan aplikasi. Jika API bertolak ansur dengan lonjakan pendek, saya akan bermula dengan token bucket. Setiap baldi penyewa menyimpan token dan masa pengisian semula terakhir dalam keadaan dikongsi secara atomik. Permintaan melebihi had menerima 429 dengan petunjuk percubaan semula yang boleh dikira. Jika pengiraan global yang tepat tidak diperlukan, kuota serantau dan pemantauan lebihan global mengorbankan sedikit ketepatan demi kependaman (latency); kegagalan storan menggunakan dasar fail-open atau fail-closed yang eksplisit berserta amaran.
Huraian Terperinci Langkah demi Langkah
Tentukan Belanjawan dan Keadilan
Seratus permintaan seminit adalah belanjawan jangka panjang penyewa percuma, dan 10,000 adalah belanjawan penyewa berbayar. Kedua-duanya juga memerlukan kapasiti lonjakan bebas; satu pembilang global tidak dapat menyatakan mana-mana dasar. Perlindungan global harus mengehadkan RPS agregat supaya satu penyewa besar tidak dapat menghabiskan sambungan pangkalan data. Kunci dasar harus merangkumi ID penyewa, tindakan API, dan versi dasar supaya titik akhir yang tidak berkaitan tidak berkongsi peruntukan secara tidak sengaja.
Pilih Algoritma
| Algoritma | Semantik utama | Kos dan risiko | Kesesuaian |
|---|---|---|---|
| Token bucket | Kadar purata terikat dengan lonjakan terkawal | Dua nilai keadaan; pengisian semula dan penggunaan mestilah atomik | API berhadapan pengguna yang bertolak ansur dengan lonjakan pendek |
| Fixed window | Mengira permintaan dalam tempoh tetap | Sempadan boleh menghampiri dua kali ganda kadar yang dikonfigurasikan | Peraturan mudah di mana anggaran boleh diterima |
| Sliding window log | Kiraan tepat dalam tetingkap aktif | Menyimpan cap masa; memori dan pembersihan adalah mahal | Populasi kecil yang memerlukan ketepatan yang ketat |
| Sliding window counter | Anggaran berpemberat dari tetingkap bersebelahan | Anggaran tetapi cekap memori; ralat mesti dinyatakan | Had keadilan skala besar |
AWS API Gateway mendokumentasikan pendikit (throttling) token-bucket: kadar token menyatakan trafik keadaan mantap dan lonjakan menyatakan kapasiti baldi. Ia boleh mengembalikan 429, tetapi had tersebut adalah sasaran usaha terbaik dan bukannya siling matematik mutlak. Pastikan niat dasar diasingkan daripada jaminan platform.
Invarian Token-Bucket
Kiraan token sentiasa kekal dalam [0, capacity]. Semasa ketibaan, isi semula mengikut masa berlalu didarabkan dengan kadar pengisian semula, hadkan pada kapasiti, dan kemudian periksa sekurang-kurangnya satu token; permintaan yang dibenarkan menggunakan satu token. Susunan ini bermakna tempoh melahu hanya terkumpul sehingga had lonjakan dan bukannya mencipta kredit tanpa had selepas masa henti.
~~~text allow(key, now): state = atomicRead(key) elapsed = max(0, now - state.lastRefill) refilled = min(capacity, state.tokens + elapsed * rate) if refilled < 1: atomicWrite(key, refilled, now) return reject(429) atomicWrite(key, refilled - 1, now) return allow ~~~
Dalam pengeluaran, pseudokod mesti berjalan sebagai satu skrip Lua, transaksi, atau operasi compare-and-swap yang setara. Dua panggilan baca dan tulis yang bebas boleh terlebih menjual token di bawah konkurensi. Cap masa harus datang daripada sumber monotonik yang dipercayai; klien tidak boleh menyerahkannya.
Penempatan dan Keadaan Dikongsi
Gerbang menyekat banjir IP yang jelas dan volum yang tidak disahkan; lapisan aplikasi menggunakan dasar penyewa, pengguna, atau titik akhir. Jika setiap instans mengira hanya dalam memori tempatan, pengimbangan beban membolehkan satu penyewa menyebarkan panggilan merentasi instans dan menerima pelbagai peruntukan. Redis yang dikongsi, stor nilai kunci atomik, atau pangkalan data yang ditulis secara bersyarat boleh memegang keadaan; pilihan bergantung pada kependaman, ketepatan, dan model kegagalan.
Pilihan pelbagai rantau adalah jelas: satu stor global memberikan peruntukan yang lebih tepat pada kependaman rentas rantau; baldi serantau bebas adalah pantas tetapi boleh terlebih buat seketika; peruntukan serantau ditambah perlindungan global berada di antara kedua-duanya. Tanya sama ada ketepatan lebih penting daripada ketersediaan sebelum mendakwa had ketat global.
Penolakan, Penurunan Fungsi, dan Telemetri
Kembalikan 429 dengan pengepala Retry-After atau baki kuota. Klien harus menggunakan pengunduran terikat (bounded backoff) daripada mencuba semula serta-merta ke dalam gelung maklum balas. Jika storan penghad gagal, penulisan berisiko tinggi biasanya fail-closed atau memasuki barisan terikat; pembacaan berisiko rendah mungkin fail-open seketika, tetapi memerlukan pemutus litar tempatan, tamat tempoh, dan had agregat. Pantau kadar benar dan tolak, penggunaan kuota setiap penyewa, kependaman storan, hot key, ralat skrip, dan beban hiliran sebenar secara berasingan.
Contoh Jawapan Berkualiti Tinggi
Saya akan menggunakan dua lapisan: gerbang melindungi daripada banjir IP dan trafik tidak disahkan, manakala aplikasi menguatkuasakan dasar penyewa dan titik akhir. Penyewa percuma dan berbayar mempunyai nilai kadar dan lonjakan yang berasingan. Saya akan menggunakan token bucket secara lalai kerana API biasanya boleh bertolak ansur dengan lonjakan pendek sambil tetap menguatkuasakan purata jangka panjang. Setiap baldi menyimpan token dan masa pengisian semula terakhirnya, dan satu skrip atomik melakukan pengisian semula, semakan, dan penggunaan dalam storan dikongsi.
Jika rantau tidak memerlukan hasil global yang tepat untuk setiap permintaan, saya akan memperuntukkan kuota serantau dan menggunakan telemetri global untuk mengesan lebihan yang luar biasa. Jika pembayaran atau penyelesaian kuota mestilah ketat, saya akan menggunakan titik keputusan ketekalan yang lebih kukuh dan menerima kependaman. Permintaan yang melebihi had menerima 429 dan panduan percubaan semula; kegagalan storan memilih fail-closed, fail-open singkat, atau barisan terikat mengikut risiko titik akhir. Saya kemudiannya akan menguji beban bagi kapasiti lonjakan, sempadan tetingkap, keadilan penyewa, pemulihan kegagalan, dan beban hiliran—bukan sekadar bilangan respons 429.
Kesilapan Biasa
- “Gunakan pembilang Redis” → tiada semantik dasar atau keatoman → tentukan keadaan baldi, sempadan skrip, dan tingkah laku kegagalan.
- Satu kuota untuk setiap penyewa → penyewa besar menjejaskan penyewa kecil → bahagikan dasar mengikut penyewa dan titik akhir, kemudian tambah perlindungan global.
- Menganggap fixed window sebagai siling seminit yang ketat → trafik sempadan boleh menghampiri dua kali ganda kadar → nyatakan ralat dan pilih sliding window atau token bucket apabila diperlukan.
- Membuka laluan sepenuhnya apabila storan penghad gagal → kebergantungan akan tumbang terlebih dahulu → pilih penurunan fungsi terikat mengikut risiko perniagaan dan berikan amaran mengenainya.
- Memberitahu klien untuk mencuba semula 429 serta-merta → trafik yang ditolak menjadi beban tambahan → sediakan panduan percubaan semula, jitter, dan had maksimum.
Soalan Susulan dan Jawapan
Bagaimanakah anda menghalang satu penyewa daripada menggandakan peruntukan merentasi 20 instans?
Letakkan keadaan baldi dalam storan dikongsi yang boleh dilihat oleh setiap instans dan kemas kini secara atomik di bawah kunci dasar penyewa. Jika hanya pembilang tempatan yang tersedia, nyatakan hasilnya sebagai anggaran dan tambah had peringkat gerbang; jangan mendakwa ketepatan global.
Bagaimana jika 100 permintaan seminit mesti dikuatkuasakan secara ketat merentasi rantau?
Gunakan titik keputusan global dengan ketekalan yang lebih kukuh atau siriaskan potongan melalui rantau asal penyewa. Kosnya ialah kependaman rentas rantau dan ketersediaan yang lebih rendah semasa kegagalan serantau. Jika lebihan jangka pendek boleh diterima, gunakan kuota serantau serta penyesuaian (reconciliation) dan tuliskan ralat tersebut ke dalam SLO.
Bagaimanakah anda menghalang penghad yang perlahan daripada memperlahankan API?
Tetapkan had masa tamat (timeout) yang ketat dan pemutus litar di sekeliling panggilan penghad. Kekalkan had keselamatan tempatan untuk gangguan storan dan turunkan fungsi mengikut risiko titik akhir. Jejaki kependaman penghad, masa tamat, dan kegagalan skrip secara berasingan daripada kadar kejayaan perniagaan.
Bilakah anda patut memasukkan ke dalam barisan dan bukannya mengembalikan 429?
Masukkan ke dalam barisan hanya apabila kerja adalah tak segerak (asynchronous), masa menunggu sesuai dengan belanjawan pengguna, dan kebergantungan memerlukan perataan beban. Barisan mestilah terikat dan menolak apabila penuh. Pembacaan interaktif atau penantian tanpa batas biasanya harus mengembalikan 429 secara jujur.
Bagaimanakah anda menguji kelemahan sempadan fixed-window?
Hantar satu lonjakan sejurus sebelum tetingkap tamat dan satu lagi sejurus selepas ia bermula, kemudian kira permintaan dalam setiap selang berguling (rolling interval). Ulangi dengan pengisian semula semasa melahu bagi token-bucket, lonjakan baldi penuh, dan penggunaan serentak menggunakan jam yang dikawal.