← Cloudflare Queues / queues / návody
Řešení rate limitů externích API
Tento tutoriál vysvětluje, jak pomocí Queues řešit omezení rychlosti externích API při tvorbě aplikace, která odesílá e-mailová oznámení pomocí Resend ↗. Tento postup ale můžete použít i ke zvládnutí limitů rychlosti u libovolného externího API.
Resend je služba, která umožňuje odesílat e-maily z vaší aplikace prostřednictvím API. Resend má výchozí limit frekvence požadavků ↗ dva požadavky za sekundu. Queues použijete ke zpracování tohoto limitu rychlosti u Resend.
Předpoklady
- Zaregistrujte si účet Cloudflare ↗.
- Nainstalujte
Node.js↗.
Správce verzí Node.js
Použijte správce verzí Node, jako je Volta ↗ nebo nvm ↗ abyste se vyhnuli problémům s oprávněními a mohli měnit verze Node.js. Wrangler, o kterém se dozvíte dále v této příručce, vyžaduje verzi Node 16.17.0 nebo novější.
-
Zaregistrujte se k Resend ↗ a vygenerovat klíč API podle postupu v Dokumentace Resend ↗.
-
Dále budete potřebovat přístup ke Cloudflare Queues.
Queues jsou zahrnuty v měsíčním poplatku za plán Workers Paid a účtují se podle operací provedených s vašimi frontami. Omezená verze Queues je k dispozici i v plánu Workers Free. Další informace najdete v Ceny pro další podrobnosti.
Než budete moci Queues používat, musíte je aktivovat přes Cloudflare dashboard ↗. K aktivaci Queues potřebujete plán Workers Paid.
Jak povolit Queues:
-
V dashboardu Cloudflare přejděte na Queues stránce.
Přejděte na Queues ↗ -
Vyberte Povolit Queues.
1. Vytvořte novou aplikaci Workers
Pro začátek vytvořte aplikaci Worker pomocí create-cloudflare CLI ↗. Otevřete okno terminálu a spusťte následující příkaz:
npm create cloudflare@latest -- resend-rate-limit-queuePři nastavení vyberte následující možnosti:
- Pro S čím byste chtěli začít?, vyberte
Hello World example. - Pro Jakou šablonu chcete použít?, vyberte
Worker only. - Pro Jaký jazyk chcete použít?, vyberte
TypeScript. - Pro Chcete používat git pro správu verzí?, vyberte
Yes. - Pro Chcete nasadit svou aplikaci?, vyberte
No(před nasazením provedeme ještě několik změn).
Poté přejděte do nově vytvořeného adresáře:
cd resend-rate-limit-queue2. Nastavte frontu
Je potřeba vytvořit frontu a vazbu (binding) k Workeru. Následujícím příkazem vytvořte frontu s názvem rate-limit-queue:
npx wrangler queues create rate-limit-queueCreating queue rate-limit-queue.
Created queue rate-limit-queue.Přidejte vazby na frontu do vašeho Konfigurační soubor Wrangler
Do souboru Wrangler přidejte následující:
{
"queues": {
"producers": [
{
"binding": "EMAIL_QUEUE",
"queue": "rate-limit-queue"
}
],
"consumers": [
{
"queue": "rate-limit-queue",
"max_batch_size": 2,
"max_batch_timeout": 10,
"max_retries": 3
}
]
}
}[[queues.producers]]
binding = "EMAIL_QUEUE"
queue = "rate-limit-queue"
[[queues.consumers]]
queue = "rate-limit-queue"
max_batch_size = 2
max_batch_timeout = 10
max_retries = 3Je důležité uvést max_batch_size dva pro spotřebitelskou frontu je důležité, protože API Resend má výchozí limit rychlosti dva požadavky za sekundu. Tato velikost dávky umožňuje frontě zpracovávat zprávy v dávkách o velikosti dva. Pokud je velikost dávky menší než dva, fronta počká 10 sekund, než shromáždí další zprávu. Pokud již žádné další zprávy nejsou k dispozici, fronta zprávu v dávce zpracuje. Další informace najdete v Dokumentace k dávkování, opakování a zpožděním
Výsledný soubor Wrangler by měl vypadat podobně jako v příkladu níže.
{
"$schema": "./node_modules/wrangler/config-schema.json",
"name": "resend-rate-limit-queue",
"main": "src/index.ts",
// Set this to today's date
"compatibility_date": "2026-08-28",
"compatibility_flags": [
"nodejs_compat"
],
"queues": {
"producers": [
{
"binding": "EMAIL_QUEUE",
"queue": "rate-limit-queue"
}
],
"consumers": [
{
"queue": "rate-limit-queue",
"max_batch_size": 2,
"max_batch_timeout": 10,
"max_retries": 3
}
]
}
}"$schema" = "./node_modules/wrangler/config-schema.json"
name = "resend-rate-limit-queue"
main = "src/index.ts"
# Set this to today's date
compatibility_date = "2026-08-28"
compatibility_flags = [ "nodejs_compat" ]
[[queues.producers]]
binding = "EMAIL_QUEUE"
queue = "rate-limit-queue"
[[queues.consumers]]
queue = "rate-limit-queue"
max_batch_size = 2
max_batch_timeout = 10
max_retries = 33. Přidejte vazby do prostředí
Přidejte vazby do rozhraní prostředí v worker-configuration.d.ts, aby TypeScript správně typoval vazby. Fronta má typ Queue<Message>, kde Message je definován v následujícím kroku.
interface Env {
EMAIL_QUEUE: Queue<Message>;
}4. Odešlete zprávu do fronty
Aplikace odešle zprávu do fronty ve chvíli, kdy Worker přijme požadavek. Pro zjednodušení pošlete jako zprávu do fronty rovnou e-mailovou adresu. Nová zpráva se do fronty odešle se zpožděním jedné sekundy.
export default {
async fetch(req, env, ctx): Promise<Response> {
try {
await env.EMAIL_QUEUE.send(
{ email: await req.text() },
{ delaySeconds: 1 },
);
return new Response("Success!");
} catch (e) {
return new Response("Error!", { status: 500 });
}
},
} satisfies ExportedHandler<Env>;Tímto se budou přijímat požadavky na libovolnou podcestu a tělo požadavku se předá dál. Očekává se, že tělo požadavku obsahuje pouze e-mailovou adresu. V produkčním prostředí byste měli ověřit, že požadavek byl typu POST požadavek. Měli byste se také vyvarovat přímého odesílání takto citlivých informací (e-mailu) do fronty. Místo toho můžete do fronty odeslat zprávu obsahující jedinečný identifikátor uživatele. Vaše spotřebitelská fronta pak může tento identifikátor použít k vyhledání e-mailové adresy v databázi a k jejímu odeslání.
5. Zpracujte zprávy ve frontě
Jakmile je zpráva odeslána do fronty, zpracuje ji Worker konzumenta. Ten zprávu zpracuje a odešle e-mail.
Protože jste zatím nenakonfigurovali Resend, zpráva se zapíše do konzole. Jakmile Resend nakonfigurujete, použijete ho k odeslání e-mailu.
Přidejte queue() handler, jak je uvedeno níže:
interface Message {
email: string;
}
export default {
async fetch(req, env, ctx): Promise<Response> {
try {
await env.EMAIL_QUEUE.send(
{ email: await req.text() },
{ delaySeconds: 1 },
);
return new Response("Success!");
} catch (e) {
return new Response("Error!", { status: 500 });
}
},
async queue(batch, env, ctx): Promise<void> {
for (const message of batch.messages) {
try {
console.log(message.body.email);
// After configuring Resend, you can send email
message.ack();
} catch (e) {
console.error(e);
message.retry({ delaySeconds: 5 });
}
}
},
} satisfies ExportedHandler<Env, Message>;Výše uvedený queue() handler zaznamená e-mailovou adresu do konzole a odešle e-mail. Pokud se odeslání e-mailu nezdaří, zprávu rovněž zopakuje. Handler delaySeconds je nastaven na pět sekund, aby se zabránilo příliš rychlému odeslání e-mailu.
Chcete-li aplikaci otestovat, spusťte následující příkaz:
npm run devPomocí následujícího příkazu cURL odešlete požadavek do aplikace:
curl -X POST -d "[email protected]" http://localhost:8787/[wrangler:inf] POST / 200 OK (2ms)
QueueMessage {
attempts: 1,
body: { email: '[email protected]' },
timestamp: 2024-09-12T13:48:07.236Z,
id: '72a25ff18dd441f5acb6086b9ce87c8c'
}6. Nastavte Resend
Chcete-li volat rozhraní Resend API, musíte nakonfigurovat klíč Resend API. Vytvořte .dev.vars soubor v kořenovém adresáři projektu a přidejte následující:
RESEND_API_KEY='your-resend-api-key'Nahraďte your-resend-api-key svým skutečným API klíčem Resend.
Dále aktualizujte Env rozhraní v worker-configuration.d.ts a zahrňte RESEND_API_KEY proměnná.
interface Env {
EMAIL_QUEUE: Queue<Message>;
RESEND_API_KEY: string;
}Nakonec nainstalujte resend balíček ↗ pomocí následujícího příkazu:
npm i resendNyní můžete použít RESEND_API_KEY proměnná ve vašem kódu.
7. Odešlete e-mail pomocí Resend
Ve vašem src/index.ts souboru importujte balíček Resend a aktualizujte queue() handler pro odeslání e-mailu.
import { Resend } from "resend";
interface Message {
email: string;
}
export default {
async fetch(req, env, ctx): Promise<Response> {
try {
await env.EMAIL_QUEUE.send(
{ email: await req.text() },
{ delaySeconds: 1 },
);
return new Response("Success!");
} catch (e) {
return new Response("Error!", { status: 500 });
}
},
async queue(batch, env, ctx): Promise<void> {
// Initialize Resend
const resend = new Resend(env.RESEND_API_KEY);
for (const message of batch.messages) {
try {
console.log(message.body.email);
// send email
const sendEmail = await resend.emails.send({
from: "[email protected]",
to: [message.body.email],
subject: "Hello World",
html: "<strong>Sending an email from Worker!</strong>",
});
// check if the email failed
if (sendEmail.error) {
console.error(sendEmail.error);
message.retry({ delaySeconds: 5 });
} else {
// if success, ack the message
message.ack();
}
message.ack();
} catch (e) {
console.error(e);
message.retry({ delaySeconds: 5 });
}
}
},
} satisfies ExportedHandler<Env, Message>; queue() handler nyní odešle e-mail pomocí Resend API. Zároveň kontroluje, zda se odeslání e-mailu nezdařilo, a v takovém případě zprávu zopakuje.
Konečný skript najdete níže:
import { Resend } from "resend";
interface Message {
email: string;
}
export default {
async fetch(req, env, ctx): Promise<Response> {
try {
await env.EMAIL_QUEUE.send(
{ email: await req.text() },
{ delaySeconds: 1 },
);
return new Response("Success!");
} catch (e) {
return new Response("Error!", { status: 500 });
}
},
async queue(batch, env, ctx): Promise<void> {
// Initialize Resend
const resend = new Resend(env.RESEND_API_KEY);
for (const message of batch.messages) {
try {
// send email
const sendEmail = await resend.emails.send({
from: "[email protected]",
to: [message.body.email],
subject: "Hello World",
html: "<strong>Sending an email from Worker!</strong>",
});
// check if the email failed
if (sendEmail.error) {
console.error(sendEmail.error);
message.retry({ delaySeconds: 5 });
} else {
// if success, ack the message
message.ack();
}
} catch (e) {
console.error(e);
message.retry({ delaySeconds: 5 });
}
}
},
} satisfies ExportedHandler<Env, Message>;Chcete-li aplikaci otestovat, spusťte vývojový server pomocí následujícího příkazu:
npm run devPomocí následujícího příkazu cURL odešlete požadavek do aplikace:
curl -X POST -d "[email protected]" http://localhost:8787/Na dashboardu Resend byste měli vidět, že e-mail byl odeslán na zadanou e-mailovou adresu.
8. Nasaďte svůj Worker
Chcete-li nasadit svůj Worker, spusťte následující příkaz:
npx wrangler deployNakonec přidejte klíč Resend API pomocí následujícího příkazu:
npx wrangler secret put RESEND_API_KEYZadejte hodnotu svého API klíče. API klíč se přidá do vašeho projektu. Nyní můžete použít RESEND_API_KEY proměnná ve vašem kódu.
Úspěšně jste vytvořili Worker, který dokáže odesílat e-maily pomocí Resend API při dodržení limitů četnosti požadavků.
Pro otestování Workeru můžete použít následující požadavek cURL. Nahraďte <YOUR_WORKER_URL> URL adresou vašeho nasazeného Workeru.
curl -X POST -d "[email protected]" <YOUR_WORKER_URL>Viz Repozitář GitHub ↗ pro úplný kód tohoto tutoriálu. Pokud používáte Hono ↗, můžete se podívat na Příklad s Hono ↗.