コンテンツにスキップ

サービスバインディング

サービスバインディングについて

サービスバインディングを使用すると、1つのワーカーが別のワーカーを呼び出すことができ、公開URLを介さずに通信できます。サービスバインディングにより、ワーカーAはワーカーBのメソッドを呼び出したり、ワーカーAからワーカーBにリクエストを転送したりできます。

サービスバインディングは、マイクロサービスやサービス指向アーキテクチャが提供する関心の分離を実現し、設定の煩わしさやパフォーマンスのオーバーヘッド、RPCプロトコルを学ぶ必要がありません。

  • サービスバインディングは高速です。 サービスバインディングを使用すると、オーバーヘッドや追加のレイテンシはゼロです。デフォルトでは、両方のワーカーは同じCloudflareサーバーの同じスレッドで実行されます。また、スマートプレースメントを有効にすると、各ワーカーは全体的なパフォーマンスのための最適な場所で実行されます。
  • サービスバインディングはHTTPだけではありません。 ワーカーAは、ワーカーBによって直接呼び出されるメソッドを公開できます。サービス間の通信は、JavaScriptのメソッドとクラスを書くことだけで済みます。
  • サービスバインディングはコストを増加させません。 機能を複数のワーカーに分割しても、追加のコストは発生しません。サービスバインディングの料金について詳しく学びましょう。

サービスバインディングはゼロコストの抽象化です

サービスバインディングは一般的に以下の目的で使用されます:

  • 複数のワーカーに共有内部サービスを提供します。 たとえば、認証サービスを独自のワーカーとしてデプロイし、任意の数の別々のワーカーがサービスバインディングを介して通信できます。
  • サービスを公開インターネットから隔離します。 公開インターネットから到達できないワーカーをデプロイし、別のワーカーが宣言した明示的なサービスバインディングを介してのみ到達できるようにします。
  • チームが独立してコードをデプロイできるようにします。 チームAは独自のリリーススケジュールでワーカーをデプロイでき、チームBは別々にワーカーをデプロイできます。

設定

サービスバインディングを追加するには、呼び出し元のwrangler.tomlを変更します。これは、リクエストを開始できるようにしたいワーカーです。

たとえば、ワーカーAがワーカーBを呼び出せるようにするには、ワーカーAのwrangler.tomlに以下を追加します:

services = [
{ binding = "<BINDING_NAME>", service = "<WORKER_NAME>" }
]
  • binding: envオブジェクトで公開したいキーの名前。
  • service: 通信したいターゲットワーカーの名前。このワーカーはあなたのCloudflareアカウントに存在する必要があります。

インターフェース

ワーカーAがワーカーBにサービスバインディングを宣言すると、ワーカーBを2つの異なる方法で呼び出すことができます:

  1. RPCを使用すると、定義した関数呼び出しを介してワーカー間で通信できます。たとえば、await env.BINDING_NAME.myMethod(arg1)。これはほとんどのユースケースに推奨されており、ワーカーが他のワーカーに提供する内部APIを作成できます。
  2. HTTPを使用すると、他のワーカーからfetch()ハンドラーを呼び出して、Requestオブジェクトを送信し、Responseオブジェクトを受け取ることができます。たとえば、env.BINDING_NAME.fetch(request)

例 — RPCを使用して最初のサービスバインディングを構築する

まず、通信したいワーカーを作成します。これを「ワーカーB」と呼びましょう。ワーカーBは、公開メソッドadd(a, b)を公開します:

name = "worker_b"
main = "./src/workerB.js"
import { WorkerEntrypoint } from "cloudflare:workers";
export class WorkerB extends WorkerEntrypoint {
async add(a, b) { return a + b; }
}

次に、ワーカーBを呼び出すワーカーを作成します。これを「ワーカーA」と呼びましょう。ワーカーAはワーカーBへのバインディングを宣言します。これにより、ワーカーBの公開メソッドを呼び出す権限が与えられます。

name = "worker_a"
main = "./src/workerA.js"
services = [
{ binding = "WORKER_B", service = "worker_b" }
]
export default {
async fetch(request, env) {
const result = await env.WORKER_B.add(1, 2);
return new Response(result);
}
}

ローカル開発でワーカーAとワーカーBの両方を実行するには、ターミナルでWranglerの2つのインスタンスを実行する必要があります。各ワーカーについて、新しいターミナルを開き、npx wrangler@latest devを実行します。

各ワーカーは別々にデプロイされます。

ライフサイクル

サービスバインディングAPIは非同期です — 呼び出すメソッドはawaitする必要があります。ワーカーAがサービスバインディングを介してワーカーBを呼び出し、ワーカーAがワーカーBの完了を待たない場合、ワーカーBは早期に終了します。

サービスバインディングを介してワーカーを呼び出すライフサイクルの詳細については、RPCライフサイクルのドキュメントを参照してください。

ローカル開発

サービスバインディングのローカル開発がサポートされています。各ワーカーについて、新しいターミナルを開き、関連するディレクトリでwrangler devを使用するか、SCRIPTオプションを使用して関連するワーカーのエントリポイントを指定します。

デプロイ

サービスバインディングを使用するワーカーは別々にデプロイされます。

最初に始めてデプロイする際、これはターゲットワーカー(上記の例ではワーカーB)がワーカーAの前に最初にデプロイされる必要があることを意味します。そうしないと、ワーカーAをデプロイしようとすると、ワーカーAがまだ存在しないワーカーBへのバインディングを宣言しているため、デプロイが失敗します。

既存のワーカーに変更を加える場合、ほとんどの場合、次のようにするべきです:

  • 既存のワーカーAと互換性のある方法で、最初にワーカーBに変更をデプロイします。たとえば、ワーカーBに新しいメソッドを追加します。
  • 次に、ワーカーAに変更をデプロイします。たとえば、ワーカーAからワーカーBの新しいメソッドを呼び出します。
  • 最後に、未使用のコードを削除します。たとえば、ワーカーBで以前に使用されていたメソッドを削除します。

スマートプレースメント

スマートプレースメントは、レイテンシを最小限に抑える最適な場所にワーカーを自動的に配置します。

スマートプレースメントをサービスバインディングと組み合わせて、ワーカーを2つのサービスに分割できます:

スマートプレースメントとサービスバインディング

詳細については、スマートプレースメントに関するドキュメントを参照してください。

制限

サービスバインディングには以下の制限があります:

  • サービスバインディングを介してワーカーへの各リクエストは、サブリクエスト制限にカウントされます。
  • 単一のリクエストは最大32のワーカー呼び出しを持ち、サービスバインディングへの各呼び出しはこの制限にカウントされます。以降の呼び出しは例外をスローします。
  • サービスバインディングを呼び出すことは、同時オープン接続制限にはカウントされません。