レート制限と負荷制御
TL;DRについて
信頼できる回路は、複数のレベル(エッジ→BFF→servis)の制限とクォータの組み合わせ、公正なリソース割り当て(テナント/キー/ルートごと)、SLO適応スロットリング、サイレントタイムアウトの代わりにバックプレッシャーです。トークン/リークバケットを使用して「、スピード」、会計クォータのスライドウィンドウ、重い操作の競争力の制限、劣化の動的なスロットリング、上流の壊れやすいサーキットブレーカー。すべてが観察中であり、プレイブックがあります。
1) iGaming/fintechの限界
SLOと持続可能性:リトレイ雪崩、トーナメント/イベントピーク、支払いスパイクに対する保護。
公平性:1人のテナントまたはパートナーは、予算全体を「吸い取る」ことはありません。
反乱用/ボット:ログイン/登録、スパム、ディレクトリのスクレイピング。
コスト:高価なコール(KYC、レポート、集計)の封じ込め。
コンプライアンス/公正使用:契約における正式な「公正使用」クォータ。
2)タクソノミの制限
3)アルゴリズムと適用する場所
3.1トークンバケット(デフォルト)
パラメータ:'rate' (tokens/sec)、 'burst' (max margin)。
API読み取り、支払/ステータス、BFFに最適です。
空のバケット→429+'Retry-After'で。
3.2漏れやすいバケツ(平均化)
RPSの「解体」が保証されており、労働者を獲得しないようにWebhookに役立ちます。
3.3固定ウィンドウとスライディングウィンドウ
修正-シンプルですが「境界」;スライド-ウィンドウ内の公正な会計(分/時間/日)。
契約クォータのスライドを適用します。
3.4同時制限
同時にアクティブなタスクの制限。輸出/レポート、KYCパッケージ、再処理に最適です。
不足の場合-429/503+キュー/ポーリング。
3.5コスト/複雑性リミッター
GraphQL/search: depth/cardinality/extensionsによる「cost」を考慮します。
「高価な」リクエストのクリッピング/劣化、ヒント付きの応答。
4)キーの寸法記入
テナントごと(マルチリース、エクイティ)、
per-api_key/client_id(パートナー)、
ルートごと(より深刻な重大な変異)、
ユーザーごと/デバイス/IP/ASN/geo
BIN/国(支払方法、発行者およびプロバイダーの保護)、
per-method (GET softer、 POST/PUT stricter)。
構成:メインキー+「リスク乗数」(新しいアカウント、TOR/プロキシ、高いチャージバックリスク)。
5) SLO適応的なスロットリング
SLOが危険な場合に動的スロットリングを有効にします:- トリガー:'p95 latency_'、'5xx_'、'queue len_'、'CPU/IO飽和'。
- アクション:低レート/バースト、アウトリアイジェクションを有効にし、「高価な」ルートをカットし、一時的に劣化します(重いフィールド/集計なし)。
- Return: Nの連続した間隔の信号を正規化するときにステップワイズ(25→50→100%)。
6)アーキテクチャの統合
APIゲートウェイ(エッジ):プライマリ・レート/クォータ、geo/ASN、 HMAC/JWT検証、429/' Retry-After'。
BFF/サービスメッシュ:ルートごと/テナントごとの制限、同時制限、上流へのサーキットブレーカ。
サービス内:重い操作のためのセマフォー、キューのバックプレッシャー、バインドサイズの「ワークプール」。
Webhooks:漏れやすいバケットとリトレイバッファを備えた個別の入力エンドポイント。
7)構成(断片)
Kong/NGINXスタイル(レート+バースト):yaml plugins:
- name: rate-limiting config:
policy: local minute: 600 # 10 rps limit_by: consumer fault_tolerant: true
- name: response-ratelimiting config:
limits:
heavy: { minute: 60 }
Envoy(回路+アウトリエ+レート):
yaml circuit_breakers:
thresholds: { max_connections: 1000, max_requests: 800 }
outlier_detection:
consecutive_5xx: 5 interval: 5s base_ejection_time: 30s http_filters:
- name: envoy. filters. http. local_ratelimit typed_config:
token_bucket: { max_tokens: 100, tokens_per_fill: 100, fill_interval: 1s }
filter_enabled: { default_value: 100% }
filter_enforced: { default_value: 100% }
並行限度(擬似):
pseudo sema = Semaphore(MAX_ACTIVE_EXPORTS_PER_TENANT)
if! sema. tryAcquire(timeout=100ms) then return 429 with retry_after=rand(1..5)s process()
sema. release()
GraphQLコストガード(アイデア):
pseudo cost = sum(weight(field) cardinality(arg))
if cost > tenant. budget then reject(429,"query too expensive")
8)異なったチャネルのための方針
REST(休
GET-柔らかく、POST/PATCH/DELETE-stricter;「idempotent」のステータス/チェックを取り消すことができます。
支払いの場合:ユーザー/テナント/BIN/国ごとに'認証/キャプチャ/払い戻し'の制限。
GraphQL
Depth/Complexity Caps、 persisted/whitelistedクエリ、aliasesの制限。
WebSocket/SSE
頻度制限'subscribe/unsubscribe'、トピック数の上限、イベントのサイズの制御、send-queue→'policy_disconnect'オーバーフロー時。
Webhooks
受信時の漏えいバケット、送信クォータごとのクォータ、デッドレターキュー、決定論的な2xx/429。
9)顧客からのフィードバック
常に見出しで明確な429を返します:- 'Retry-After:
' - 'X-RateLimit-Limit/Return/Reset'
- クォータの場合-403コード「quota_exceeded」とプランのアップグレードへのリンク。
- ドキュメント:OpenAPI/SDL+「Fair Use」ページの制限。
10)監視およびダッシュボード
メトリクス:- ヒット数の制限:'rate。限界。hit 'by keys/routs/tenants。
- latency p50/p95/p99、エラー率、キュー長、オープン回路。
- フェアシェア:消費のトップのテナント、「bully detector」。
- Webhook:受信/レトライ、ドロップレート、中間ラグ。
- 総RPSの429以上1-3%(ボットなし)。
- p95リミッター添加剤≤エッジあたり5〜10ミリ秒です。
- 劣化回復時間≤ 10分。
sql
SELECT ts::date d, tenant, route,
SUM(hits) AS limit_hits,
SUM(total) AS total_calls,
SUM(hits)::decimal/NULLIF(SUM(total),0) AS hit_rate
FROM ratelimit_stats
GROUP BY 1,2,3
ORDER BY d DESC, hit_rate DESC;
11)インシデントプレイブック
リトレイストーム(上流落下):グローバルスロットリングをオンにし、バックオフを上げ、サーキットブレーカーを開け、タイムアウトの代わりに「クイックミス」を返します。
ボット攻撃/スクレイピング:IP/ASN/geoによるハードキャップ、WAF/JSチャレンジを有効にし、ディレクトリ/検索を制限します。
トーナメント/イベントピーク:読み取り制限を事前に引き上げ、「高価なフィールド」を下げ、キャッシュ/非正規化を有効にします。
PSPからのWebhookを追加:一時的な漏洩バケット、クリティカルタイプの優先順位付け、デッドレターの展開、リトレイ。
12)テストおよびUAT
負荷:RPSの梯子、ビーズ×正常の10。
公平性:1「貪欲な」テナントのエミュレーション-グローバル予算のX%以下。
劣化:SLO適応は制限を減らし、p95を廊下に保ちます。
境界の場合:窓の変更(min→chas)、時計の揺れ(時計のスキュー)、Redisのスケーリング/キーのシャーディング。
契約:429とRetry-Afterヘッダーが存在するため、SDKは正しくバックオフされます。
13)限界のための貯蔵
局所限界(小さなクラスタ)のインメモリ。
Redis/Memcached for distributed(原子性のためのLuaスクリプト)。
ハッシュによるシャーディングキー。窓の下のTTL;キャッシュ損失のためのバックアップメトリック。
Idempotency:リミッターは、idempotent repeated call(リクエストキーによる会計)を破るべきではありません。
14)ガバナンス
限界カタログ:所有者は誰ですか、キー/しきい値/配列。
ファストスイッチ(危機モード)のフィーチャーフラグ。
契約クォータへの変更のためのポリシーとRFCプロセスのバージョニング。
最適な閾値の選択に関するA/B実験。
15)アンチパターン
グローバルな1つの制限「すべてのAPIのために」。
固定ウィンドウ→「エッジ」ジャンプのみ。
フィードバックなしで制限('Retry-After'/ヘッダーはありません)。
高速429/503の代わりにサイレントタイムアウト。
テナントごとのフェアシェアの欠如-1人のクライアントが残りを絞め殺します。
GraphQL/Complexityの検索保護はありません。
コンカレントガード→DB/PSP「掃除機」のゼロ。
16)選択のミニチートシート
デフォルトはトークンバケット(rate+burst) per-tenant+routeです。
お金/レポートによるクォータ:スライドウィンドウの日/月。
重い操作:concurrent-limits+queue。
GraphQL/\\\' 83\' 5c: complexity-budgets+persistedクエリ。
WS/webhooks: leaky bucket+backpressure。
ダイナミックスロットリング+サーキットブレーカ+劣化。
概要
ロードコントロールは、正しいアルゴリズム(バケット/窓/競争力)、フェアリミットキー、SLO適応、透明フィードバックなど、マルチレベルの分野です。ゲートウェイ/メッシュ/サービスに限界を縫い、プロファイルポリシーを持つGraphQL/WS/Webhookを武装させ、観察可能性をプレイブックと接続することで、ピークイベントや他の人々の失敗を制御された状況に変えます。