mcpField
C
cloudflare-queues

cloudflare-queues

github.com/jezwebクラウド・DevOps1.1k339 回インストール3 週間前に更新
リポジトリ

cloudflare-queues について

Cloudflare Workers と Queues でメッセージ駆動型アプリケーションを構築する開発者向けの実用リファレンスです。メッセージの送受信、再試行、デッドレターキュー、HTTP 配信、Cloudflare サービスのイベント購読を扱います。

主な機能

  1. 01単一・バッチメッセージの送信
  2. 02遅延配信と HTTP による公開
  3. 03コンシューマーの確認応答と再試行
  4. 04失敗メッセージのデッドレター処理
  5. 05Cloudflare サービスイベントの購読

活用シーン

  1. 01注文やメールタスクの非同期処理
  2. 02外部サービスからのキューメッセージ公開
  3. 03R2 または KV イベントへの対応
  4. 04失敗メッセージのデッドレターキューへの移動

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/jezweb/claude-skills --skill cloudflare-queues

インストール後、Claude Code で/cloudflare-queuesを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

README.md
.claude-plugin/
plugin.json
references/
best-practices.md
consumer-api.md
producer-api.md
wrangler-commands.md
rules/
cloudflare-queues.md
templates/
queues-consumer-basic.ts
queues-consumer-explicit-ack.ts
queues-dlq-pattern.ts
queues-producer.ts
queues-retry-with-delay.ts

詳細

Cloudflare Queues

ステータス:本番環境対応済み ✅ 最終更新日:2026-01-09 依存関係:cloudflare-worker-base(Worker のセットアップ用) 最新バージョン:[email protected]、@cloudflare/[email protected]

最近の更新(2025):

  • 2025年4月:プルコンシューマーの上限が引き上げられました(キューあたり5,000 msg/s。従来は5分あたり1,200リクエスト)
  • 2025年3月:一時停止・パージ API(wrangler queues pause-delivery、queues purge)
  • 2025年:保持期間をカスタマイズ可能に(60秒~14日。従来は4日固定)
  • 2025年:キューの上限が引き上げられました(アカウントあたり10個から10,000個)

クイックスタート(5分)

# 1. Create queue
npx wrangler queues create my-queue

# 2. Add producer binding to wrangler.jsonc
# { "queues": { "producers": [{ "binding": "MY_QUEUE", "queue": "my-queue" }] } }

# 3. Send message from Worker
await env.MY_QUEUE.send({ userId: '123', action: 'process-order' });

# Or publish via HTTP (May 2025+) from any service
curl -X POST "https://api.cloudflare.com/client/v4/accounts/{account_id}/queues/my-queue/messages" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -d '{"messages": [{"body": {"userId": "123"}}]}'

# 4. Add consumer binding to wrangler.jsonc
# { "queues": { "consumers": [{ "queue": "my-queue", "max_batch_size": 10 }] } }

# 5. Process messages
export default {
  async queue(batch: MessageBatch, env: Env): Promise<void> {
    for (const message of batch.messages) {
      await processMessage(message.body);
      message.ack(); // Explicit acknowledgement
    }
  }
};

# 6. Deploy and test
npx wrangler deploy
npx wrangler tail my-consumer

プロデューサー API

// Send single message
await env.MY_QUEUE.send({ userId: '123', action: 'send-email' });

// Send with delay (max 12 hours)
await env.MY_QUEUE.send({ action: 'reminder' }, { delaySeconds: 600 });

// Send batch (max 100 messages or 256 KB)
await env.MY_QUEUE.sendBatch([
  { body: { userId: '1' } },
  { body: { userId: '2' } },
]);

重要な制限:

  • メッセージサイズ:最大 128 KB(約100バイトのメタデータを含む)
  • 128 KB を超えるメッセージは失敗します。代わりに R2 に保存し、参照を送信してください
  • バッチサイズ:100メッセージ、または合計256 KB
  • 遅延:0~43200秒(最大12時間)

HTTP パブリッシング(2025年5月以降)

2025年5月の新機能:任意のサービスやプログラミング言語から、HTTP 経由でキューにメッセージをパブリッシュできます。

出典:Cloudflare Changelog

認証:Queues Edit 権限を持つ Cloudflare API トークンが必要です。

# Single message
curl -X POST "https://api.cloudflare.com/client/v4/accounts/{account_id}/queues/my-queue/messages" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "messages": [
      {"body": {"userId": "123", "action": "process-order"}}
    ]
  }'

# Batch messages
curl -X POST "https://api.cloudflare.com/client/v4/accounts/{account_id}/queues/my-queue/messages" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "messages": [
      {"body": {"userId": "1"}},
      {"body": {"userId": "2"}},
      {"body": {"userId": "3"}}
    ]
  }'

ユースケース:

  • 外部マイクロサービス(Node.js、Python、Go など)からのパブリッシング
  • Cloudflare の外部で実行される cron ジョブ
  • Webhook レシーバー
  • レガシーシステムとの統合
  • Cloudflare Workers SDK を使用しないサービス

イベントサブスクリプション(2025年8月以降)

2025年8月の新機能:Cloudflare サービスのイベントをサブスクライブし、Queues 経由で利用できます。

出典:Cloudflare Changelog

対応するイベントソース:

  • R2(bucket.created、object.uploaded、object.deleted など)
  • Workers KV
  • Workers AI
  • Vectorize
  • Workflows
  • Super Slurper
  • Workers Builds

サブスクリプションの作成:

npx wrangler queues subscription create my-queue \
  --source r2 \
  --events bucket.created,object.uploaded

イベント構造:

interface CloudflareEvent {
  type: string;           // 'r2.bucket.created', 'kv.namespace.created'
  source: string;         // 'r2', 'kv', 'ai', etc.
  payload: any;           // Event-specific data
  metadata: {
    accountId: string;
    timestamp: string;
  };
}

コンシューマーの例:

export default {
  async queue(batch: MessageBatch, env: Env): Promise<void> {
    for (const message of batch.messages) {
      const event = message.body as CloudflareEvent;

      switch (event.type) {
        case 'r2.bucket.created':
          console.log('New R2 bucket:', event.payload.bucketName);
          await notifyAdmin(event.payload);
          break;

        case 'r2.object.uploaded':
          console.log('File uploaded:', event.payload.key);
          await processNewFile(event.payload.key);
          break;

        case 'kv.namespace.created':
          console.log('New KV namespace:', event.payload.namespaceId);
          break;

        case 'ai.inference.completed':
          console.log('AI inference done:', event.payload.modelId);
          break;
      }

      message.ack();
    }
  }
};

ユースケース:

  • R2 へのアップロードをトリガーとするカスタムワークフローの構築
  • インフラストラクチャの変更(新しい KV 名前空間、バケットなど)の監視
  • AI 推論ジョブの追跡
  • アカウントアクティビティの監査
  • カスタム Webhook を使わないイベント駆動型アーキテクチャ

コンシューマー API

export default {
  async queue(batch: MessageBatch, env: Env, ctx: ExecutionContext): Promise<void> {
    for (const message of batch.messages) {
      // message.id - unique UUID
      // message.timestamp - Date when sent
      // message.body - your content
      // message.attempts - retry count (starts at 1)

      await processMessage(message.body);
      message.ack(); // Explicit ack (critical for non-idempotent ops)
    }
  }
};

// Retry with exponential backoff
message.retry({ delaySeconds: Math.min(60 * Math.pow(2, message.attempts - 1), 3600) });

// Batch methods
batch.ackAll();   // Ack all messages
batch.retryAll(); // Retry all messages

重要:

  • message.ack() - 成功としてマークします。後でハンドラーが失敗しても再試行されません
  • 冪等でない操作(データベースへの書き込み、API 呼び出し、支払い)には明示的な ack を使用してください
  • 暗黙的な ack - ack() を呼び出さずにハンドラーが正常に戻ると、すべてのメッセージが自動的に ack されます
  • 順序は保証されません - メッセージが FIFO 順に届くとは限りません

重要なコンシューマーパターン

明示的な確認応答(冪等でない操作)

**次の操作には必ず明示的な ack() を使用してください:**データベースへの書き込み、API 呼び出し、金融取引

export default {
  async queue(batch: MessageBatch, env: Env): Promise<void> {
    for (const message of batch.messages) {
      try {
        await env.DB.prepare('INSERT INTO orders (id, amount) VALUES (?, ?)')
          .bind(message.body.orderId, message.body.amount).run();
        message.ack(); // Only ack on success
      } catch (error) {
        console.error(`Failed ${message.id}:`, error);
        // Don't ack - will retry
      }
    }
  }
};

理由:バッチ内のメッセージが1つ失敗した場合の重複書き込みを防ぎます。失敗したメッセージは個別に再試行されます。


レート制限された API の指数バックオフ
export default {
  async queue(batch: MessageBatch, env: Env): Promise<void> {
    for (const message of batch.messages) {
      try {
        await fetch('https://api.example.com/process', {
          method: 'POST',
          body: JSON.stringify(message.body),
        });
        message.ack();
      } catch (error) {
        if (error.status === 429) {
          const delaySeconds = Math.min(60 * Math.pow(2, message.attempts - 1), 3600);
          message.retry({ delaySeconds });
        } else {
          message.retry();
        }
      }
    }
  }
};

デッドレターキュー(DLQ) - 本番環境で必須

⚠️ DLQ がない場合、失敗したメッセージは max_retries 到達後に完全に削除されます

npx wrangler queues create my-dlq

wrangler.jsonc:

{
  "queues": {
    "consumers": [{
      "queue": "my-queue",
      "max_retries": 3,
      "dead_letter_queue": "my-dlq"  // Messages go here after 3 failed retries
    }]
  }
}

DLQ コンシューマー:

export default {
  async queue(batch: MessageBatch, env: Env): Promise<void> {
    for (const message of batch.messages) {
      console.error('PERMANENTLY FAILED:', message.id, message.body);
      await env.DB.prepare('INSERT INTO failed_messages (id, body) VALUES (?, ?)')
        .bind(message.id, JSON.stringify(message.body)).run();
      message.ack(); // Remove from DLQ
    }
  }
};

既知の問題を防ぐ

このスキルは、文書化された13件の問題を防ぎます:

問題 #1:複数の開発コマンド - キューはプロセス間で共有されない

エラー:ある wrangler dev プロセスで送信されたキューメッセージが、別の wrangler dev コンシューマープロセスに表示されない 出典:GitHub Issue #9795

原因:wrangler が使用する仮想キューはプロセス内メモリにあります。別々の開発プロセス間でキューの状態を共有できません。

予防策:

# ❌ Don't run producer and consumer as separate processes
# Terminal 1: wrangler dev (producer)
# Terminal 2: wrangler dev (consumer)  # Won't receive messages!

# ✅ Option 1: Run both in single dev command
wrangler dev -c producer/wrangler.jsonc -c consumer/wrangler.jsonc

# ✅ Option 2: Use Vite plugin with auxiliaryWorkers
# vite.config.ts:
export default defineConfig({
  plugins: [
    cloudflare({
      auxiliaryWorkers: ['./consumer/wrangler.jsonc']
    })
  ]
})

Issue #2:キュープロデューサーバインディングにより、リモート開発で500エラーが発生する

エラー:キューバインディングを使用して wrangler dev --remote を実行すると、すべてのルートで500 Internal Server Errorが返されます 出典:GitHub Issue #9642

発生する理由:wrangler dev --remote モードでは、キューはまだサポートされていません。キューバインディングを使用しないルートでも失敗します。

予防策:

// When using remote dev, temporarily comment out queue bindings
{
  "queues": {
    // "producers": [{ "queue": "my-queue", "binding": "MY_QUEUE" }]
  }
}

// Or use local dev instead
// wrangler dev (without --remote)

Issue #3:キューのリモート設定時にD1リモートが動作しなくなる

エラー:キュープロデューサーバインディングに remote: true を設定すると、D1のリモートバインディングが動作しなくなります 出典:GitHub Issue #11106

発生する理由:ローカル開発とリモート開発の混在に影響するバインディングの競合です。

予防策:

// ❌ Don't mix D1 remote with queue remote
{
  "d1_databases": [{
    "binding": "DB",
    "database_id": "...",
    "remote": true
  }],
  "queues": {
    "producers": [{
      "binding": "QUEUE",
      "queue": "my-queue",
      "remote": true  // ❌ Breaks D1 remote
    }]
  }
}

// ✅ Avoid remote on queues when using D1 remote
{
  "d1_databases": [{ "binding": "DB", "remote": true }],
  "queues": {
    "producers": [{ "binding": "QUEUE", "queue": "my-queue" }]
  }
}

ステータス:現在、回避策はありません。最新情報についてはIssueを確認してください。


Issue #4:ローカル/リモートのバインディング混在時にキューコンシューマーが見つからない

エラー:ローカルキューとリモートのAI/Vectorizeバインディングを混在させると、キューコンシューマーバインディングが表示されません 出典:GitHub Issue #9887

発生する理由:Wranglerは、同じWorker内でローカルとリモートのバインディングを混在させることをサポートしていません。

予防策:

// ❌ Don't mix local queues with remote AI
{
  "queues": {
    "consumers": [{ "queue": "my-queue" }]
  },
  "ai": {
    "binding": "AI",
    "experimental_remote": true  // ❌ Breaks queue consumer
  }
}

// ✅ Option 1: All local (no remote bindings)
wrangler dev

// ✅ Option 2: Separate workers for queues vs AI
// Worker 1: Queue processing (local)
// Worker 2: AI operations (remote)

Issue #5:http_pullタイプによりWorkerコンシューマーが実行されない

エラー:type: "http_pull" を使用したキューコンシューマーが本番環境で実行されません 出典:GitHub Issue #6619

発生する理由:http_pull は外部のHTTPベースのコンシューマー向けであり、Workerベースのコンシューマー向けではありません。

予防策:

// ❌ Don't use type: "http_pull" for Worker consumers
{
  "queues": {
    "consumers": [{
      "queue": "my-queue",
      "type": "http_pull",  // ❌ Wrong for Workers
      "max_batch_size": 10
    }]
  }
}

// ✅ Omit type field for push-based Worker consumers
{
  "queues": {
    "consumers": [{
      "queue": "my-queue",
      "max_batch_size": 10
      // No "type" field - defaults to Worker consumer
    }]
  }
}

破壊的変更と非推奨

プロデューサー設定のdelivery_delay(今後削除予定)

警告:プロデューサーバインディングの delivery_delay パラメーターは、今後のwranglerのバージョンで削除されます。

出典:GitHub Issue #10286

// ❌ Will be removed - don't use
{
  "queues": {
    "producers": [{
      "binding": "MY_QUEUE",
      "queue": "my-queue",
      "delivery_delay": 300  // ❌ Don't use this
    }]
  }
}

移行方法:メッセージごとの遅延を使用してください:

// ✅ Correct approach - per-message delay
await env.MY_QUEUE.send({ data }, { delaySeconds: 300 });

理由:Workerがキューレベルの設定に影響を与えるべきではありません。複数のプロデューサーがある場合、最後にデプロイされたプロデューサーの設定が適用され、予測できない動作を引き起こします。


コミュニティのヒント

注:これらのヒントは、コミュニティでの議論やGitHub Issueに基づいています。ご使用のwranglerのバージョンに照らして確認してください。

ヒント:max_batch_timeoutによりローカル開発で問題が発生する場合があります

出典:GitHub Issue #6619 確度:MEDIUM 対象:wrangler dev を使用したローカル開発

キューコンシューマーがローカルで実行されない場合は、max_batch_timeout を削除してみてください:

{
  "queues": {
    "consumers": [{
      "queue": "my-queue",
      "max_batch_size": 10
      // Remove max_batch_timeout for local dev
    }]
  }
}

これはバージョン固有の問題と思われるため、すべての環境に影響するとは限りません。


ヒント:プロデューサーバインディングではキュー名を取得できません

出典:GitHub Issue #10131 確度:HIGH 対象:複数環境へのデプロイ(ステージング、PRプレビュー、テナント固有のキュー)

キュー名を取得できるのはコンシューマーハンドラーの batch.queue 経由のみで、プロデューサーバインディングからは取得できません。このため、email-queue-staging や email-queue-pr-123 など、環境固有のキュー名で問題が発生します。

現在の制限事項:

// ❌ Can't access queue name from producer binding
const queueName = env.MY_QUEUE.name; // Doesn't exist!

// ❌ Must hardcode or normalize in consumer
switch (batch.queue) {
  case 'email-queue':           // What about email-queue-staging?
  case 'email-queue-staging':   // Must handle all variants
  case 'email-queue-pr-123':    // Dynamic env names break this
}

回避策:

// In consumer: Normalize queue name
function normalizeQueueName(queueName: string): string {
  return queueName.replace(/-staging|-pr-\d+|-dev/g, '');
}

switch (normalizeQueueName(batch.queue)) {
  case 'email-queue':
    // Handle all email-queue-* variants
}

ステータス:機能リクエストは内部で追跡されています:MQ-923


コンシューマーの設定

{
  "queues": {
    "consumers": [{
      "queue": "my-queue",
      "max_batch_size": 100,           // 1-100 (default: 10)
      "max_batch_timeout": 30,         // 0-60s (default: 5s)
      "max_retries": 5,                // 0-100 (default: 3)
      "retry_delay": 300,              // Seconds (default: 0)
      "max_concurrency": 10,           // 1-250 (default: auto-scale)
      "dead_letter_queue": "my-dlq"    // REQUIRED for production
    }]
  }
}

重要な設定:

  • バッチ処理 - いずれかの条件(max_batch_sizeまたはmax_batch_timeout)を満たすと、コンシューマーが呼び出されます
  • max_retries - リトライ上限に達した後:DLQがある場合はDLQに送信され、DLQがない場合は完全に削除されます
  • max_concurrency - 上流にレート制限または接続数制限がある場合にのみ設定してください。それ以外の場合は、自動スケーリング(最大250件の同時呼び出し)のため、未設定のままにしてください
  • DLQ - 別途作成してください:npx wrangler queues create my-dlq

Wranglerのコマンド

# Create queue
npx wrangler queues create my-queue
npx wrangler queues create my-queue --message-retention-period-secs 1209600  # 14 days

# Manage queues
npx wrangler queues list
npx wrangler queues info my-queue
npx wrangler queues delete my-queue  # ⚠️ Deletes ALL messages!

# Pause/Purge (March 2025 - NEW)
npx wrangler queues pause-delivery my-queue   # Pause processing, keep receiving
npx wrangler queues resume-delivery my-queue
npx wrangler queues purge my-queue            # ⚠️ Permanently deletes all messages!

# Consumer management
npx wrangler queues consumer add my-queue my-consumer-worker \
  --batch-size 50 --batch-timeout 10 --message-retries 5
npx wrangler queues consumer remove my-queue my-consumer-worker

制限とクォータ

機能制限
アカウントごとのキュー数10,000
メッセージサイズ128 KB(約100バイトのメタデータを含む)
メッセージの再試行回数最大100
バッチサイズ1~100メッセージ
バッチタイムアウト0~60秒
sendBatch あたりのメッセージ数100(または合計256 KB)
キューのスループットキューごとに毎秒5,000メッセージ
メッセージの保持期間4日間(デフォルト)、14日間(最大)
キューのバックログサイズキューごとに25 GB
同時コンシューマー数250(プッシュ型、自動スケーリング)
コンシューマーの実行時間15分(実時間)
コンシューマーのCPU時間30秒(デフォルト)、5分(最大)
可視性タイムアウト12時間(プル型コンシューマー)
メッセージの遅延最大12時間
API レート制限1200リクエスト / 5分

料金

Workers Paid プランが必要です(月額$5)

操作の料金:

  • 月間最初の1,000,000操作:無料
  • それ以降:100万操作あたり$0.40

操作としてカウントされるもの:

  • 書き込み、読み取り、または削除される64 KBごとのチャンク
  • 64 KBを超えるメッセージは複数の操作としてカウントされます:
    • 65 KBのメッセージ = 2操作
    • 127 KBのメッセージ = 2操作
    • 128 KBのメッセージ = 2操作

一般的なメッセージのライフサイクル:

  • 書き込み1回 + 読み取り1回 + 削除1回 = 3操作

再試行:

  • 再試行1回につき、追加の読み取り操作が発生します
  • メッセージを3回再試行 = 書き込み1回 + 読み取り4回 + 削除1回 = 6操作

デッドレターキュー:

  • DLQ への書き込み = 追加の書き込み操作

料金の例:

  • 月間100万メッセージ(再試行なし):((1M × 3) - 1M) / 1M × $0.40 = $0.80
  • 月間1,000万メッセージ:((10M × 3) - 1M) / 1M × $0.40 = $11.60
  • 月間1億メッセージ:((100M × 3) - 1M) / 1M × $0.40 = $119.60

エラー処理

よくあるエラー
1. メッセージが大きすぎます
// ❌ Bad: Message >128 KB
await env.MY_QUEUE.send({
  data: largeArray, // >128 KB
});

// ✅ Good: Check size before sending
const message = { data: largeArray };
const size = new TextEncoder().encode(JSON.stringify(message)).length;

if (size > 128000) {
  // Store in R2, send reference
  const key = `messages/${crypto.randomUUID()}.json`;
  await env.MY_BUCKET.put(key, JSON.stringify(message));
  await env.MY_QUEUE.send({ type: 'large-message', r2Key: key });
} else {
  await env.MY_QUEUE.send(message);
}

2. スループット超過
// ❌ Bad: Exceeding 5000 msg/s per queue
for (let i = 0; i < 10000; i++) {
  await env.MY_QUEUE.send({ id: i }); // Too fast!
}

// ✅ Good: Use sendBatch
const messages = Array.from({ length: 10000 }, (_, i) => ({
  body: { id: i },
}));

// Send in batches of 100
for (let i = 0; i < messages.length; i += 100) {
  await env.MY_QUEUE.sendBatch(messages.slice(i, i + 100));
}

// ✅ Even better: Rate limit with delay
for (let i = 0; i < messages.length; i += 100) {
  await env.MY_QUEUE.sendBatch(messages.slice(i, i + 100));
  if (i + 100 < messages.length) {
    await new Promise(resolve => setTimeout(resolve, 100)); // 100ms delay
  }
}

3. コンシューマーのタイムアウト
// ❌ Bad: Long processing without CPU limit increase
export default {
  async queue(batch: MessageBatch): Promise<void> {
    for (const message of batch.messages) {
      await processForMinutes(message.body); // CPU timeout!
    }
  },
};

// ✅ Good: Increase CPU limit in wrangler.jsonc

wrangler.jsonc:

{
  "limits": {
    "cpu_ms": 300000  // 5 minutes (max allowed)
  }
}

4. バックログの増加
// Issue: Consumer too slow, backlog growing

// ✅ Solution 1: Increase batch size
{
  "queues": {
    "consumers": [{
      "queue": "my-queue",
      "max_batch_size": 100  // Process more per invocation
    }]
  }
}

// ✅ Solution 2: Let concurrency auto-scale (don't set max_concurrency)

// ✅ Solution 3: Optimize consumer code
export default {
  async queue(batch: MessageBatch, env: Env): Promise<void> {
    // Process in parallel
    await Promise.all(
      batch.messages.map(async (message) => {
        await process(message.body);
        message.ack();
      })
    );
  },
};

重要なルール

必ず行うこと:

  • ✅ 本番環境では DLQ を設定する(コンシューマー設定の dead_letter_queue)
  • ✅ 冪等でない操作(DB 書き込み、API 呼び出し)には明示的な message.ack() を使用する
  • ✅ 送信前にメッセージサイズが128 KB未満であることを検証する
  • ✅ 複数のメッセージには sendBatch() を使用する(より効率的です)
  • ✅ 指数バックオフを実装する:60 * Math.pow(2, message.attempts - 1)
  • ✅ 同時実行数は自動スケーリングに任せる(上流にレート制限がない限り、max_concurrency を設定しない)

絶対に行わないこと:

  • ❌ FIFO 順序を前提にしない(保証されません)
  • ❌ 冪等でない操作に暗黙的な ack を使用しない。明示的な ack() を使用する
  • ❌ 128 KBを超えるメッセージを送信しない(失敗します。代わりに R2 に保存してください)
  • ❌ 本番環境で DLQ を省略しない(DLQ がないと、失敗したメッセージは完全に削除されます)
  • ❌ キューごとに毎秒5,000メッセージを超えない(プッシュ型コンシューマーではレート制限が適用されます)
  • ❌ メッセージを同期的に処理しない。並列処理には Promise.all() を使用する

トラブルシューティング

問題:メッセージがコンシューマーに配信されない

考えられる原因:

  1. コンシューマーがデプロイされていない
  2. wrangler.jsonc のキュー名が間違っている
  3. 配信が一時停止されている
  4. コンシューマーがエラーをスローしている

解決方法:

# Check queue info
npx wrangler queues info my-queue

# Check if delivery paused
npx wrangler queues resume-delivery my-queue

# Check consumer logs
npx wrangler tail my-consumer

問題:1つのメッセージが失敗すると、バッチ全体が再試行される

原因: 冪等でない操作に暗黙的な acknowledge を使用している

解決方法: 明示的な ack() を使用する

// ✅ Explicit ack
for (const message of batch.messages) {
  try {
    await dbWrite(message.body);
    message.ack(); // Only ack on success
  } catch (error) {
    console.error(`Failed: ${message.id}`);
    // Don't ack - will retry
  }
}

問題:処理されずにメッセージが削除される

原因: デッドレターキューが設定されていない

解決方法:

# Create DLQ
npx wrangler queues create my-dlq

# Add to consumer config
{
  "queues": {
    "consumers": [{
      "queue": "my-queue",
      "dead_letter_queue": "my-dlq"
    }]
  }
}

問題:コンシューマーが自動スケーリングされない

考えられる原因:

  1. max_concurrency が1に設定されている
  2. コンシューマーがエラーを返している(処理していない)
  3. バッチ処理が速すぎる(バックログがない)

解決方法:

{
  "queues": {
    "consumers": [{
      "queue": "my-queue",
      // Don't set max_concurrency - let it auto-scale
      "max_batch_size": 50  // Increase batch size instead
    }]
  }
}

関連ドキュメント


最終更新日:2026-01-21 バージョン:2.0.0 変更内容:HTTP パブリッシング(2025年5月)、イベントサブスクリプション(2025年8月)、既知の問題の防止(13件)、破壊的変更のセクション、コミュニティのヒントを追加しました。エラー数:0 → 13。主な機能を追加し、問題に関する包括的なドキュメントを整備しました。 メンテナー:Jeremy Dawes | [email protected]

コメント