レート制限

このページでは、Service Infrastructure を使用して、Service Management API に統合されたマネージド サービスのレート制限を実装する方法について説明します。

1 つのマネージド サービスを複数のサービス ユーザーで利用することができます。システム容量を保護し、公正な使用量を保証するために、マネージド サービスは多くの場合、レート制限を使用してサービス ユーザー間で容量を分散させます。 レート制限の管理や適用には Service Management API と Service Control API を使用できます。

レート制限の設定

レート制限機能を使用するには、サービス プロデューサー プロジェクトのサービス構成_quota metrics__quota limits_ を構成します。

現在サポートされているレート制限は、サービス ユーザーあたりの 1 分間のリクエスト数です。この制限において、サービス ユーザーは、API キー、プロジェクト ID、またはプロジェクト番号で識別される Google Cloud プロジェクトです。レート制限では、リクエストという概念が不透明です。サービスは、1 つのリクエストとして 1 つの HTTP リクエストを選択することも、ペイロードの 1 バイトを選択することもできます。レート制限機能は、リクエストが何を意味するかとは無関係です。

割り当て指標

指標は、一定期間に特定の値を測定するための名前付きカウンタです。たとえば、サービスによって受信される HTTP リクエストの数が指標です。割り当て指標は、割り当てとレート制限のために使用される指標です。サービスでアクティビティが発生すると、1 つ以上の割り当て指標がインクリメントされます。事前定義された割り当て制限に指標値が到達すると、サービスは 429 エラーでアクティビティを拒否する必要があります。

割り当て上限

割り当て制限は、割り当て指標に適用される制限を意味します。たとえば、1 分間のサービス ユーザーあたりのリクエスト数は割り当て制限です。現時点でサポートされている唯一の割り当て制限タイプは、ユーザーあたりの 1 分間の値、つまり 1/min/{project} です。

サービスとユーザーのペアの実際のレート制限は、次の 3 つの設定で制御されます。

  • マネージド サービスに対して指定されたデフォルト制限。
  • サービス ユーザーに対するサービス プロデューサー オーバーライド。
  • サービス ユーザーに対するサービス ユーザー オーバーライド。

有効なレート制限は次のとおりです。

  • オーバーライドが存在しない場合のデフォルト制限。
  • サービス プロデューサー オーバーライドは存在するが、サービス ユーザー オーバーライドは存在しない場合のサービス プロデューサー オーバーライド。
  • サービス ユーザー オーバーライドが存在するが、サービス プロデューサー オーバーライドが存在しない場合の、サービス ユーザー オーバーライドとデフォルト制限のうち小さい値。
  • サービス プロデューサー オーバーライドとサービス ユーザー オーバーライドの両方が存在する場合の、サービス ユーザー オーバーライドとサービス プロデューサー オーバーライドのうち小さい値。

レート制限の適用

レート制限を適用するには、マネージド サービスに属している各サーバーが Service Control API の services.allocateQuota メソッドを定期的に呼び出す必要があります。services.allocateQuota メソッドのレスポンスで使用量が上限を超えていることが通知された場合、サーバーは受信リクエストを 429 エラーで拒否する必要があります。詳細については、services.allocateQuota メソッドのリファレンス ドキュメントをご覧ください。

システムのパフォーマンスと信頼性を向上させるには、各サーバーでバッチ処理、キャッシュ保存、予測ロジックを使用することをおすすめします。一般に、1 つのサーバーは、同じ(サービス、ユーザー、指標)タプルに対して 1 秒間に 1 回だけ services.allocateQuota メソッドを呼び出す必要があります。

次の例は、services.allocateQuota メソッドを呼び出してレート制限をチェックする方法を示しています。正しく設定する必要がある重要なリクエスト パラメータは、サービス名、ユーザー ID、指標名、および指標値です。services.allocateQuota メソッドは、(サービス、ユーザー、指標)タプルに対して指定された量だけ使用量を増やそうとします。増加した使用量が制限を超えた場合は、エラーが返されます。次の例は、gcurl コマンドを使用した呼び出しを示しています。この設定方法については、Service Control API スタートガイドをご覧ください。

gcurl -d '{
  "allocateOperation": {
    "operationId": "123e4567-e89b-12d3-a456-426655440000",
    "methodName": "google.example.hello.v1.HelloService.GetHello",
    "consumerId": "project:endpointsapis-consumer",
    "quotaMetrics": [{
      "metricName": "endpointsapis.appspot.com/requests",
      "metricValues": [{
        "int64Value": 1
      }]
    }],
    "quotaMode": "NORMAL"
  }
}' https://servicecontrol.googleapis.com/v1/services/endpointsapis.appspot.com:allocateQuota
{
  "operationId": "123e4567-e89b-12d3-a456-426655440000",
  "quotaMetrics": [
    {
      "metricName": "serviceruntime.googleapis.com/api/consumer/quota_used_count",
      "metricValues": [
        {
          "labels": {
            "/quota_name": "endpointsapis.appspot.com/requests"
          },
          "int64Value": "1"
        }
      ]
    }
  ],
  "serviceConfigId": "2017-09-10r0"
}

エラー処理

HTTP レスポンス コードが 200 で、レスポンスに RESOURCE_EXHAUSTED QuotaError が含まれている場合、サーバーは 429 エラーでリクエストを拒否する必要があります。レスポンスに割り当てエラーが含まれていない場合は、受信リクエストの処理を継続します。他の割り当てエラーの場合、サーバーは 409 エラーでリクエストを拒否する必要があります。セキュリティ リスクがあるため、エラー メッセージにどのエラー情報を含めるかを慎重に検討する必要があります。

他のすべての HTTP レスポンス コードの場合、サーバーにプログラミング上のバグがある可能性が高いと考えられます。問題をデバッグしている間はサーバーで受信リクエストを引き続き処理することをおすすめします。services.allocateQuota メソッドから予期しないエラーが返された場合は、エラーをログに記録して受信リクエストを受け入れます。後でエラーをデバッグすることができます。

フェール オープン

レート制限機能は、マネージド サービスが過負荷にならないように保護し、サービス ユーザー間でサービス容量が公平に分配されるようにします。ほとんどのサービス ユーザーは通常のオペレーション中にレート制限に到達することがないため、レート制限機能が利用不可の場合は、すべての受信リクエストをマネージド サービスで受け入れる必要があります(フェール オープンとも呼ばれます)。 これにより、サービスの可用性がレート制限システムの影響を受けなくなります。

services.allocateQuota メソッドを使用する場合、サービスは再試行なして 500503504 エラーを無視しする必要があります。レート制限機能に依存しすぎないように、Service Control API は限定された量のエラー インジェクションを定期的に発行します。