Pembatasan laju permintaan
Pembatasan laju permintaan menentukan berapa banyak permintaan yang dapat dilakukan organisasi Anda dalam satu jendela waktu. Gunakan header respons untuk mengatur laju lalu lintas, dan gunakan jeda percobaan ulang untuk memulihkan permintaan yang ditolak.
Cara batas ditentukan
Organisasi Anda berbagi satu batas regional untuk setiap kebijakan, di seluruh kunci API dan workspace-nya. Membuat kunci tambahan tidak menambah kapasitas. Organisasi yang berbeda memiliki batas terpisah.
Setiap permintaan mengonsumsi satu kebijakan pelanggan. Kebijakan produk memiliki kapasitas independen: mengambil status pesan tidak mengonsumsi batas pengambilan resource umum, dan mengirim email tidak mengonsumsi batas pembuatan resource.
Login, reset kata sandi, dan operasi sensitif keamanan lainnya memiliki perlindungan penyalahgunaan tambahan. Pemeriksaan supplier dan batas koneksi juga dapat menolak permintaan secara independen dari batas laju paket Anda.
Grup
Operasi API biasa menggunakan kebijakan berikut:
| Kebijakan | Operasi |
|---|---|
api_get | Mengambil satu resource |
api_list | Mencantumkan atau mencari koleksi |
api_create | Membuat resource |
api_update | Memperbarui atau upsert resource |
api_delete | Menghapus resource |
Operasi produk menggunakan kebijakan bernama sebagai pengganti kebijakan API biasa. Contohnya meliputi email_send, email_batch, sms_send, whatsapp_send, lookup, dan message_status_read. Kebijakan batch menghitung permintaan pengiriman; jumlah penerima batch tidak mengonsumsi unit kebijakan tambahan. Lihat pengiriman batch email dan pengiriman batch SMS untuk batas ukuran batch.
Email REST dan pengiriman SMTP berbagi kapasitas email_send. Satu pengiriman DATA SMTP mengonsumsi satu unit; autentikasi SMTP tidak. Jika kebijakan menolak pengiriman, server mengembalikan 452 4.3.1 sementara dengan jeda percobaan ulang dan tidak menerima pesan tersebut. Simpan pesan dalam antrean dan coba lagi setelah jeda tersebut.
Membuat broadcast menggunakan api_create; memulai broadcast yang sudah ada menggunakan api_update. Pengiriman latar belakang ke penerimanya tidak mengonsumsi email_send. Kuota pengiriman dan pengaturan laju pengiriman tetap merupakan kontrol terpisah.
Kebijakan voice_call membatasi penerimaan panggilan masuk dan keluar. Kebijakan yang habis menolak panggilan dan mencatat calls_per_second_exceeded; tidak ada respons HTTP yang terlibat. Lihat Panggilan yang ditolak.
Cara batas Anda ditentukan
Setiap produk memiliki paketnya sendiri, dan setiap paket menetapkan nilai untuk kebijakan produk tersebut: paket SMS menetapkan sms_send dan sms_batch, paket Voice menetapkan voice_call, dan seterusnya. Tingkat yang lebih tinggi menetapkan nilai yang lebih tinggi. Kebijakan bersama, seperti grup api_*, verify_send, verify_check, dan message_status_read, dapat ditetapkan oleh paket produk mana pun.
Laju efektif Anda untuk suatu kebijakan ditentukan dengan urutan berikut:
- Override organisasi yang aktif, jika ada.
- Nilai tertinggi di antara paket produk aktif organisasi Anda yang menetapkan kebijakan tersebut.
- Nilai default kebijakan, yaitu nilai dasar bayar sesuai pemakaian.
Override dapat menaikkan atau menurunkan laju. Jendela waktu kebijakan tetap sama, nilai mana pun yang berlaku.
Baca kuota efektif Anda dari header respons RateLimit-Policy, yang mencantumkan kunci kebijakan beserta laju dan jendela yang berlaku untuk panggilan tersebut. Untuk membandingkan tingkat, baca rate_limits setiap paket dari katalog paket publik (bird billing plans list --commercial-product sms) atau tabel perbandingan di halaman harga.
Menaikkan batas
Jika tidak ada override organisasi yang berlaku untuk kebijakan tersebut, tingkatkan paket produk pemilik kebijakan itu di halaman paket produk tersebut, di Billing and payments > Overview. Periksa dulu rate_limits paket tujuan: laju baru hanya berlaku jika nilainya lebih tinggi daripada nilai yang sudah diberikan paket Anda yang lain. Untuk kebijakan bersama, seperti api_get atau verify_send, paket produk mana pun yang menetapkan kebijakan tersebut dapat menaikkannya. Laju yang lebih tinggi berlaku setelah pembayaran peningkatan berhasil; Perubahan & perpanjangan paket menjelaskan waktunya. Paket juga menaikkan kuota yang bukan batas laju, seperti panggilan serentak Voice.
Override organisasi yang aktif tetap berlaku apa pun paket yang Anda pilih, dan nilainya bisa lebih rendah daripada nilai paket. Jika header RateLimit-Policy menunjukkan laju di bawah nilai yang dipublikasikan untuk paket Anda, hubungi dukungan dengan menyertakan kunci kebijakan agar override tersebut ditinjau.
Jika Anda memerlukan lebih dari yang disediakan paket tertinggi yang dipublikasikan, hubungi tim penjualan dengan kunci kebijakan dan perkiraan lalu lintas Anda.
Header respons
Evaluasi pembatasan laju permintaan menyediakan dua header dalam format IETF Structured Fields (RFC 9651):
RateLimit-Policy: "email_send";q=1000;w=60
RateLimit: "email_send";r=842;t=35| Header | Arti |
|---|---|
RateLimit-Policy | Kebijakan yang berlaku: q adalah kuota (unit maksimum) dan w adalah jendela dalam detik. |
RateLimit | Status Anda saat ini: r adalah jumlah unit tersisa dan t adalah detik hingga jendela direset. |
String yang dikutip menamai kebijakan. Dalam contoh ini, organisasi memiliki batas email_send efektif sebesar 1.000 pengiriman per 60 detik, dengan 842 tersisa dan 35 detik hingga reset.
Gunakan r dan t untuk memperlambat permintaan sebelum menerima 429. Nilai t adalah jeda relatif dalam detik, bukan Unix timestamp.
Saat Anda mencapai batas
Integrasi Anda harus menangani respons 429 sebagai bagian dari operasi normal. Minimal, patuhi Retry-After dan coba lagi dengan backoff. Klien yang juga mengatur lajunya berdasarkan header RateLimit aktif (lihat Header respons) menghindari tercapainya batas.
Kebijakan pelanggan yang habis mengembalikan 429 Too Many Requests dengan Retry-After dalam detik dan header pembatasan laju permintaan yang menunjukkan r=0. Perlindungan penyalahgunaan atau supplier independen dapat mengembalikan 429 meskipun kebijakan pelanggan Anda masih memiliki kapasitas tersisa. Ikuti Retry-After untuk menentukan kapan harus mencoba lagi; nilainya bisa berbeda dari nilai t kebijakan.
Body menggunakan respons kesalahan standar:
{
"error": {
"type": "rate_limit_error",
"code": "E01003",
"name": "RateLimited",
"message": "Too many requests. Please retry after the period indicated in the Retry-After header.",
"doc_url": "https://bird.com/docs/api/errors/E01003",
"request_id": "req_01ky7qavkff7qr88vadv6bv948"
}
}Buat percabangan berdasarkan type: rate_limit_error, karena pesan yang dapat dibaca manusia dapat berubah. Baca kunci kebijakan dan waktu untuk mencoba lagi dari header:
async function sendWithBackoff(url, headers, payload, maxAttempts = 5) {
for (let attempt = 0; attempt < maxAttempts; attempt++) {
const response = await fetch(url, {
method: "POST",
headers,
body: JSON.stringify(payload),
});
if (response.status !== 429) return response;
const retryAfter = Number(response.headers.get("Retry-After") ?? 2 ** attempt);
await new Promise((resolve) => setTimeout(resolve, retryAfter * 1000));
}
throw new Error("rate limited after max retries");
}import time
import requests
def send_with_backoff(url, headers, payload, max_attempts=5):
for attempt in range(max_attempts):
response = requests.post(url, headers=headers, json=payload)
if response.status_code != 429:
return response
retry_after = int(response.headers.get("Retry-After", 2 ** attempt))
time.sleep(retry_after)
raise RuntimeError("rate limited after max retries")func sendWithBackoff(req *http.Request, maxAttempts int) (*http.Response, error) {
for attempt := range maxAttempts {
if attempt > 0 && req.Body != nil {
if req.GetBody == nil {
return nil, errors.New("request body cannot be replayed")
}
body, err := req.GetBody()
if err != nil {
return nil, err
}
req.Body = body
}
resp, err := http.DefaultClient.Do(req)
if err != nil {
return nil, err
}
if resp.StatusCode != http.StatusTooManyRequests {
return resp, nil
}
resp.Body.Close()
wait := 1 << attempt
if s, err := strconv.Atoi(resp.Header.Get("Retry-After")); err == nil {
wait = s
}
time.Sleep(time.Duration(wait) * time.Second)
}
return nil, errors.New("rate limited after max retries")
}function sendWithBackoff(ClientInterface $http, RequestInterface $request, int $maxAttempts = 5): ResponseInterface
{
for ($attempt = 0; $attempt < $maxAttempts; $attempt++) {
$response = $http->sendRequest($request);
if ($response->getStatusCode() !== 429) {
return $response;
}
$retryAfter = (int) ($response->getHeaderLine('Retry-After') ?: 2 ** $attempt);
sleep($retryAfter);
}
throw new RuntimeException('rate limited after max retries');
}Untuk percobaan ulang operasi yang sama, gunakan kembali kunci idempotensi-nya. Jangan ubah body permintaan.
Lihat konsep SDK untuk perilaku percobaan ulang otomatis dan backoff.
Mode kegagalan
Pembatas laju gagal terbuka: jika Bird tidak dapat mengevaluasi batas, permintaan tetap dilanjutkan alih-alih menerima penolakan palsu. Pembatasan laju permintaan melindungi kapasitas layanan. Autentikasi dan otorisasi tetap menjadi batas keamanan. Gangguan pembatas di sisi Bird tidak menyebabkan 429.
Langkah selanjutnya
- Error: respons kesalahan dan cara melakukan percabangan berdasarkan tipe error
- Idempotensi: percobaan ulang yang aman untuk permintaan yang mengubah data
- Konsep SDK: perilaku percobaan ulang otomatis dan backoff
Sumber daya terkait
Lanjutkan dengan dokumentasi, panduan, dan contoh untuk topik ini.