ゲートウェイとリバースプロキシ
🎯 核心問題
高並行のインターネットアーキテクチャにおいて、トラフィックを安全かつ効率的に正しいサービスへ届けるにはどうすればよいか? リバースプロキシは「トラフィックをどう分配するか」を解決し、APIゲートウェイは「リクエストをどう処理するか」を解決する。本記事では実際のケース(受付、警備システム、インテリジェントルーティング)を通じて、ゲートウェイの設計思想とエンジニアリング実践を深く理解する。
1. なぜ「ゲートウェイ」が必要なのか?
1.1 実際のケースから始める:あるECサイトのアーキテクチャ進化
あるECプラットフォームが急成長する中で、深刻なアーキテクチャ問題に直面した:
シナリオの再現:
フェーズ1:サービスを直接公開
クライアント → ユーザーサービス、注文サービス、決済サービスを直接呼び出し...
↓
問題1:サービスIPが露出し、セキュリティリスクがある
問題2:認証、レート制限を統一的に実施できない
問題3:新しいサービスを追加するたびにクライアント設定を変更する必要がある⚠️ 直接公開の致命的な問題
- セキュリティリスク: すべてのサービスIPが露出し、攻撃を受けやすい
- 機能の重複: 各サービスがそれぞれ認証、レート制限、ログを実装する必要がある
- 拡張が困難: 新しいサービスを追加するたびに全クライアントを変更する必要がある
- プロトコルの混乱: HTTPを使うものもあればgRPCを使うものもあり、クライアントがそれぞれに対応する必要がある
改善後のアーキテクチャ(ゲートウェイ導入):
クライアント → APIゲートウェイ(Nginx/Kong) → 内部サービス
↓
統一認証、レート制限、ルーティング
↓
クライアントはゲートウェイのアドレスだけを知っていればよい✨ 改善後の効果
- セキュリティ: 実際のサービスIPは隠蔽され、ゲートウェイのみが外部に公開される
- 機能の集約: 認証、レート制限、ログをゲートウェイで統一的に処理
- 拡張が容易: 新しいサービスを追加する際はゲートウェイのルーティング設定のみで済む
- プロトコルの統一: 対外向けはHTTP、内部ではgRPCが使用可能
1.2 ゲートウェイを日常に例えると
受付
大きな会社を訪れる場面を想像してほしい:
- 受付がない場合: 来訪者が直接各部署を探し回り、どこに行けばいいかわからず、会社は混乱する
- 受付がある場合: 来訪者はまず受付に行き、受付が用件を聞いてから該当部署へ案内する
APIゲートウェイはシステムの「受付」である:
- リバースプロキシ: 受付。来訪者を正しい部署へ案内する
- APIゲートウェイ: スマート受付。来訪者の身分確認(認証)や訪問人数の制限(レート制限)もできる
- 客户端无感知,只需要访问域名
- 隐藏真实服务器架构,统一对外接口
- 提供负载均衡、安全防护、SSL卸载等功能
- 典型代表:Nginx、HAProxy、AWS ELB
- 网站需要承载高并发流量(负载均衡)
- 统一HTTPS证书管理(SSL卸载)
- 防护DDoS攻击和SQL注入
- 灰度发布、A/B测试、蓝绿部署
"反向代理 = 代理服务器" —— 客户端不知道真实服务器,只知道域名
2. リバースプロキシとは?
2.1 フォワードプロキシ vs リバースプロキシ
🤔 用語解説
フォワードプロキシ(Forward Proxy):
- クライアント側に配置
- クライアントの代わりに外部リソースへアクセス
- 典型的な用途:VPN、ファイアウォール回避ツール
- 例:社内ネットワークで、プロキシ経由で外部ネットワークにアクセスする
リバースプロキシ(Reverse Proxy):
- サーバー側に配置
- クライアントのリクエストを受信し、内部サービスに転送
- クライアントはプロキシの存在のみを知り、実際のサーバーは知らない
- 例:Nginx、HAProxy
比較表:
| 観点 | フォワードプロキシ | リバースプロキシ |
|---|---|---|
| 配置位置 | クライアント側 | サーバー側 |
| サービス対象 | クライアント | サーバー |
| 典型的な用途 | VPN、ファイアウォール回避 | ロードバランシング、ゲートウェイ |
| 透過性 | サーバーはプロキシIPを見る | クライアントはプロキシIPを見る |
| 目的 | 実際のクライアントを隠す、アクセス高速化 | 実際のサーバーを隠す、ロードバランシング |
2.2 リバースプロキシの核心的価値
価値その1:ロードバランシング
トラフィックを複数のバックエンドサーバーに分散し、単一障害点の過負荷を防ぐ。
クライアント
↓
Nginx(リバースプロキシ)
↓
┌─────────┬─────────┬─────────┐
│ サーバー1 │ サーバー2 │ サーバー3 │
└─────────┴─────────┴─────────┘価値その2:セキュリティ防御
実際のサーバーIPを隠蔽し、直接攻撃を防ぐ。プロキシ層で統一的にセキュリティ防御を行う。
クライアント → NginxのIPだけが見える
実際のサーバー → 内部ネットワークのみ、外部から直接アクセス不可価値その3:SSL終端
プロキシ層でHTTPSの暗号化/復号を処理し、バックエンドサービスはHTTPを使用することで、バックエンドの計算オーバーヘッドを削減する。
HTTPSクライアント → Nginx(暗号化/復号) → HTTPバックエンドサービス
↑
SSL終端点3. Nginx:なぜ100万同時接続を支えられるのか?
3.1 Master-Workerプロセスモデル
Nginxはマルチスレッドではなく、マルチプロセスアーキテクチャを採用している:
Masterプロセス(管理者):
- 設定ファイルの読み取りと検証を担当
- Workerプロセスの管理(起動、停止、再読み込み)
- 具体的なリクエストは処理しない
Workerプロセス(作業者):
- 実際のHTTPリクエストを処理
- 各Workerは独立したプロセスで、相互に分離されている
- 数は通常CPUコア数に設定し、コンテキストスイッチのオーバーヘッドを回避
💡 利点
- 分離性が高い: 1つのWorkerがクラッシュしても他のWorkerに影響しない
- マルチコアを最大限活用: 各Workerが独立して動作
- マルチスレッドの複雑さを回避: ロックや競合などの問題に対処する必要がない
3.2 イベント駆動 + 非同期ノンブロッキング
これがNginxの高性能の核心的な秘密である:
従来のApache(マルチプロセス/スレッドモデル):
- 1接続 = 1プロセス/スレッド
- 同時接続数はシステムのプロセス/スレッド数に制限される
- 大量接続時、プロセス切り替えのオーバーヘッドが膨大
Nginx(イベント駆動モデル):
- epoll(Linux)/kqueue(macOS)などの効率的なI/Oマルチプレクシング機構を使用
- 1つのWorkerプロセスで数万の接続を同時に処理可能
- 接続にデータがない間はCPUを消費せず、新しいデータがあればイベント通知で復帰
日常に例えると
- Apache: レストランで各客に1人のウェイター(プロセス)を配置。客が増えると大量のウェイターが必要
- Nginx: 1人のスーパーウェイターが全客を同時にサービス。必要な客のところに行き、ずっと特定の客のそばに立っているわけではない
太多了上下文切换开销大,太少了无法利用多核性能。
4. APIゲートウェイとは?
4.1 なぜAPIゲートウェイが必要なのか?
ゲートウェイのないシステムを想像してほしい:
- クライアントは複数サービスのアドレスを知っている必要がある(ユーザーサービス、注文サービス、決済サービス...)
- 各サービスがそれぞれ認証、レート制限、ログを実装しなければならない
- プロトコルが統一されておらず、HTTPを使うものもあればgRPCを使うものもある
- サービスをアップグレードする際、クライアントも追随して変更する必要がある
⚠️ ゲートウェイがない場合の問題
- クライアントが複雑: 複数のサービスアドレスを設定する必要がある
- 機能の重複: 各サービスが認証、レート制限を実装する必要がある
- プロトコルの混乱: クライアントが複数のプロトコルに対応する必要がある
- アップグレードが困難: サービスをアップグレードすると、クライアントも変更が必要
APIゲートウェイ導入後:
- クライアントはゲートウェイのアドレスだけを知っていればよく、ゲートウェイが正しいサービスへのルーティングを担当
- 認証、レート制限、ログなどの横断的関心事をゲートウェイで統一的に処理
- ゲートウェイがプロトコル変換を行い、対外向けにHTTPを統一して公開
- バックエンドサービスのアップグレードはゲートウェイ設定の変更のみで、クライアントは意識不要
| 功能需求 | 没有网关 (直接访问) | 有 API 网关 |
|---|---|---|
| 身份认证 | 每个服务都要写一遍登录校验 | ✅ 统一在网关层校验 JWT |
| 限流保护 | 每个服务自己实现限流 | ✅ 网关统一限流,保护后端 |
| 协议转换 | HTTP、gRPC、WebSocket各自处理 | ✅ 网关统一对外暴露 HTTP |
| 灰度发布 | 需要改负载均衡器配置 | ✅ 网关层按 Header 路由 |
4.2 APIゲートウェイのコア機能
| 機能 | 説明 | 典型的なシナリオ |
|---|---|---|
| ルーティング転送 | URL、Headerなどのルールに基づき、リクエストを異なるサービスに転送 | /api/users → ユーザーサービス、/api/orders → 注文サービス |
| ロードバランシング | 同一サービスに複数インスタンスがある場合、トラフィックを分散 | ユーザーサービスに3台のインスタンスがあり、ラウンドロビンでリクエストを分散 |
| 認証・認可 | JWT、OAuth Tokenを統一的に検証 | 未ログインユーザーは/api/adminにアクセス不可 |
| レート制限・サーキットブレーカー | トラフィック上限を制御し、サービスが押しつぶされるのを防ぐ | 毎秒最大1000リクエスト、超過時は429を返す |
| プロトコル変換 | 対外HTTP、内部はgRPCに変換可能 | クライアントはHTTP、ゲートウェイがgRPCに変換して内部サービスを呼び出し |
| カナリアリリース | Headerまたは割合に基づき、一部トラフィックを新バージョンに誘導 | 5%のユーザーが新バージョンを体験、95%は旧バージョンを使用 |
| ログ・監視 | リクエストログを統一的に記録し、分析とトラブルシューティングを容易に | 各リクエストの処理時間、ステータスコード、レスポンスサイズを記録 |
5. ゲートウェイ実践:完全なゲートウェイアーキテクチャを構築するには?
5.1 完全なアーキテクチャ図
┌───────────────────────────────────────────────────────────────────────┐
│ クライアント(ブラウザ/アプリ) │
└───────────────────────────┬─────────────────────────────────────────┘
│ HTTPS
▼
┌───────────────────────────────────────────────────────────────────────┐
│ 外層:CDN + WAF │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ CDN(コンテンツデリバリーネットワーク) │ │
│ │ - 静的リソースのキャッシュ(画像、CSS、JS) │ │
│ │ - 近接アクセス、レイテンシ低減 │ │
│ └───────────────────────────────────────────────────────────────┘ │
│ ┌───────────────────────────────────────────────────────────────┐ │
│ │ WAF(Webアプリケーションファイアウォール) │ │
│ │ - SQLインジェクション、XSS攻撃の防御 │ │
│ │ - 悪意のあるBot、クローラーのブロック │ │
│ │ - CC攻撃の防御 │ │
│ └───────────────────────────────────────────────────────────────┘ │
└───────────────────────────────────────────────────────────────────────┘
│
▼
┌───────────────────────────────────────────────────────────────────────┐
│ 中層:APIゲートウェイ(Nginx/Kong) │
│ ┌───────────────────────────────────────────────────────────────┐ │
│ │ 第1層:SSL終端 + セキュリティ防御 │ │
│ │ - HTTPS / TLS 1.3 │ │
│ │ - HSTS、セキュリティレスポンスヘッダー │ │
│ └───────────────────────────────────────────────────────────────┘ │
│ ┌───────────────────────────────────────────────────────────────┐ │
│ │ 第2層:認証と認可 │ │
│ │ - JWT Token検証 │ │
│ │ - OAuth 2.0 / SSO連携 │ │
│ │ - API Key管理 │ │
│ │ - 権限チェック(RBAC) │ │
│ └───────────────────────────────────────────────────────────────┘ │
│ ┌───────────────────────────────────────────────────────────────┐ │
│ │ 第3層:トラフィック制御 │ │
│ │ - レート制限- トークンバケット/リーキーバケットアルゴリズム │ │
│ │ - サーキットブレーカー- 障害の拡散を防止 │ │
│ │ - フォールバック- サービス不可時の代替案 │ │
│ │ - カナリアリリース- 割合に応じたトラフィック分配 │ │
│ └───────────────────────────────────────────────────────────────┘ │
│ ┌───────────────────────────────────────────────────────────────┐ │
│ │ 第4層:ルーティングとロードバランシング │ │
│ │ - パスルーティング- Path-based Routing) │ │
│ │ - ドメインルーティング- Host-based Routing) │ │
│ │ - Headerルーティング- Header-based Routing) │ │
│ │ - ロードバランシングアルゴリズム- ラウンドロビン/加重/最小接続/IPハッシュ) │ │
│ │ - サービスディスカバリ- Service Discovery)連携 │ │
│ └───────────────────────────────────────────────────────────────┘ │
│ ┌───────────────────────────────────────────────────────────────┐ │
│ │ 第5層:プロトコル変換とデータ処理 │ │
│ │ - SSL終端- HTTPS ↔ HTTP) │ │
│ │ - プロトコル変換- HTTP ↔ gRPC / WebSocket) │ │
│ │ - リクエスト/レスポンス変換- JSON ↔ XML) │ │
│ │ - データ圧縮- Gzip / Brotli) │ │
│ │ - キャッシュ- Cache)- 静的リソースとAPIレスポンス │ │
│ └───────────────────────────────────────────────────────────────┘ │
└───────────────────────────────────────────────────────────────────────┘
│
▼
┌───────────────────────────────────────────────────────────────────────┐
│ 内層:マイクロサービス群 │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ ユーザー │ │ 注文 │ │ 商品 │ │ 決済 │ │
│ │ サービス │ │ サービス │ │ サービス │ │ サービス │ │
│ │ User Svc │ │ Order Svc │ │ Product Svc │ │ Payment Svc │ │
│ │ │ │ │ │ │ │ │ │
│ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ │
│ │ │ │ │ │
│ └────────────────┴────────────────┴────────────────┘ │
│ │ │
│ サービスディスカバリと設定センター/ etcd) │
│ - サービス登録と検出 │
│ - ヘルスチェック │
│ - KV設定ストレージ │
└───────────────────────────────────────────────────────────────────────┘5.2 ルーティングとロードバランシング
ゲートウェイの核心的な責務の一つは、リクエストを正しい場所に届けることである。これには2つの重要な能力が関わる:ルーティング(どのサーバーに行くか)とロードバランシング(トラフィックをどう分配するか)。
ルーティングルール:URLからサービスへ
ECシステムを想像してみよう。異なるURLが異なるサービスに対応する:
/api/users/*→ ユーザーサービス/api/orders/*→ 注文サービス/api/products/*→ 商品サービス/api/pay/*→ 決済サービス
Nginx設定例:
server {
listen 80;
server_name api.example.com;
# ユーザーサービス
location /api/users/ {
proxy_pass http://user-service;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
# 注文サービス
location /api/orders/ {
proxy_pass http://order-service;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
# 商品サービス
location /api/products/ {
proxy_pass http://product-service;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
# 決済サービス(より高いセキュリティレベルが必要)
location /api/pay/ {
# IPアクセス制限
allow 10.0.0.0/8;
deny all;
proxy_pass http://payment-service;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}ロードバランシング:4つの戦略比較
同じサービスに複数のインスタンスがある場合、どのように選択するか?
| 戦略 | 原理 | 適したシナリオ | 利点 | 欠点 |
|---|---|---|---|---|
| ラウンドロビン | 順番に各サーバーに割り当て | サーバー性能が近い場合 | シンプルで公平 | サーバーの現在の負荷を考慮しない |
| 加重ラウンドロビン | 重みに比例して割り当て、重みが高いほど多く割り当て | サーバー性能が不均一な場合 | 高性能サーバーを最大限活用 | 適切な重み設定が必要 |
| 最小接続 | 現在の接続数が最も少ないサーバーに割り当て | 長時間接続シナリオ、動画ストリーミング | 負荷変動に動的に対応 | 接続数のリアルタイム統計が必要 |
| IPハッシュ | クライアントIPに基づいてハッシュを計算し、同一IPは常に同一サーバーに割り当て | セッション維持が必要な場合 | セッションの一貫性を保証 | 特定IPのトラフィックが大きい場合、単一点への負荷集中が発生 |
Nginx設定例:
# 加重ラウンドロビン
upstream backend_weighted {
server 10.0.1.10:8080 weight=3; # 性能が良い、より多くのトラフィックを担当
server 10.0.1.11:8080 weight=2;
server 10.0.1.12:8080 weight=1; # 性能が低い、より少ないトラフィックを担当
}
# 最小接続
upstream backend_least_conn {
least_conn;
server 10.0.1.10:8080;
server 10.0.1.11:8080;
server 10.0.1.12:8080;
}
# IPハッシュ(セッション維持)
upstream backend_ip_hash {
ip_hash;
server 10.0.1.10:8080;
server 10.0.1.11:8080;
server 10.0.1.12:8080;
}6. ゲートウェイセキュリティ:システムの門をどう守るか?
6.1 認証と認可
従来の方式(各サービスが個別に認証):
- ユーザーサービス、注文サービス、決済サービス...それぞれがJWTを検証する必要がある
- コードの重複、メンテナンスが困難
- secretが各サービスに分散し、漏洩リスクが高い
ゲートウェイ統һ認証:
- クライアントはTokenを持ってゲートウェイにアクセス
- ゲートウェイがTokenの正当性を検証(署名、有効期限)
- 検証通過後、ユーザー情報(user_idなど)をリクエストヘッダーに追加し、バックエンドサービスに転送
- バックエンドサービスは検証不要で、Headerから直接ユーザー情報を取得
💡 核心思想
認証はゲートウェイで、認可はサービスで:
- 認証: あなたは誰か?(Tokenを検証し、ユーザー身元を取得)
- 認可: あなたは何ができるか?(ユーザーロールに基づいて権限を判断)
会社の受付のように:受付があなたの身元を認証し(身分証明書)、具体的な権限は各部署が判断する。
| 对比维度 | Session + Cookie | JWT | OAuth2.0 |
|---|---|---|---|
| 存储位置 | 服务端存储 Session,客户端存 Cookie | 客户端存储 Token,服务端无状态 | 授权服务器存储,客户端存 Access Token |
| 扩展性 | ❌ 需要共享 Session,扩展复杂 | ✅ 无状态,易于水平扩展 | ✅ 分布式架构,支持大规模系统 |
| 安全性 | ⚠️ Cookie 可能被窃取,需要 CSRF 防护 | ⚠️ Token 泄露风险,需 HTTPS + 短期有效 | ✅ 行业最佳实践,支持多种安全机制 |
| 实现复杂度 | 🟢 简单,开箱即用 | 🟡 中等,需要 Token 管理 | 🔴 复杂,需要授权服务器 |
| 适用场景 | 传统 Web 应用、后台管理系统 | SPA、移动端 API、微服务 | 第三方登录、开放平台、SSO |
6.2 HTTPSとSSL終端
なぜHTTPSが必要なのか?
- セキュリティ: 転送中のデータの盗聴を防止
- コンプライアンス: モダンブラウザはHTTPサイトに「安全でない」警告を表示
- SEO: 検索エンジンはHTTPSサイトを優先的に収録
SSL終端ソリューション:
- ゲートウェイ層のみでHTTPSと証明書を設定
- ゲートウェイがTLSハンドシェイクと暗号化/復号を担当
- ゲートウェイとバックエンドサービス間はHTTP平文で転送(内部ネットワークは信頼できる)
- バックエンドサービスはビジネスロジックに専念し、TLS処理は不要
💡 SSL終端の利点
- 管理の簡素化: 証明書はゲートウェイのみに設定、バックエンドは設定不要
- オーバーヘッド削減: バックエンドサービスはTLSハンドシェイクを処理する必要がない
- 統一的な更新: 証明書の更新はゲートウェイでの操作のみで完了
openssl genrsa -out private.key 2048openssl req -new -key private.key -out csr.pem# 添加 DNS TXT 记录 或 上传验证文件到 /.well-known/# 下载 certificate.crt 和 chain.crtnginx -t && systemctl reload nginx7. レート制限とサーキットブレーカー:「トラフィックの洪水」からシステムをどう守るか?
7.1 レート制限アルゴリズムの比較
| アルゴリズム | 核心思想 | バーストトラフィック | 適したシナリオ | 実装の複雑さ |
|---|---|---|---|---|
| トークンバケット | バケツにトークンが入っており、トークンがある場合のみ通過可能 | 一定程度のバーストを許容 | APIレート制限、帯域制御 | 中程度 |
| リーキーバケット | リクエストがバケツに入り、一定速度で流出処理 | 強制的に平滑化、バーストはキャッシュまたは拒否される | 厳密な一定速度処理が必要なシナリオ | 中程度 |
| スライディングウィンドウ | 時間ウィンドウ内のリクエスト数を統計 | ウィンドウ単位で厳密にカウント、超過は一律拒否 | 正確な統計(例:「1分間に最大100回」) | やや高い |
7.2 Nginxレート制限設定の実践
# レート制限領域の定義(httpブロックに配置)
# 1. IPベースのレート制限(リーキーバケットアルゴリズム)
# zone=mylimit:10m - 領域名とメモリサイズ(10MBで約16万IPを保存可能)
# rate=10r/s - 毎秒10リクエストを許可
limit_req_zone $binary_remote_addr zone=mylimit:10m rate=10r/s;
# 2. IPベースの接続数制限(単一IPの過剰な接続確立を防止)
limit_conn_zone $binary_remote_addr zone=addr:10m;
# 3. サービスエンドポイントベースのレート制限(IPを区別せず、バックエンド全体を保護)
limit_req_zone $server_name zone=server_limit:10m rate=100r/s;
server {
listen 80;
server_name api.example.com;
# ユーザーサービス - 通常のレート制限
location /api/users/ {
# レート制限を適用
# burst=20 - バケット容量、20リクエストのバーストを許容
# nodelay - バーストリクエストを遅延処理しない(即時処理または拒否)
limit_req zone=mylimit burst=20 nodelay;
# 単一IPの接続数を制限
limit_conn addr 10;
proxy_pass http://user-service;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
# 注文サービス - より厳格なレート制限
location /api/orders/ {
# より厳格なレート制限:毎秒5リクエスト
limit_req_zone $binary_remote_addr zone=order_limit:10m rate=5r/s;
limit_req zone=order_limit burst=10 nodelay;
proxy_pass http://order-service;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
# レート制限後の処理
# リクエストがレート制限された場合、429 Too Many Requestsを返す
error_page 429 /429.html;
location = /429.html {
internal;
return 429 '{"error": "Too Many Requests", "message": "Rate limit exceeded. Please try again later."}';
add_header Content-Type application/json;
}
}💡 レート制限戦略の提案
- 一般API: 毎秒10リクエスト、バースト20を許容
- 重要API(決済、注文): 毎秒5リクエスト、バースト10を許容
- 全体保護: 全リクエストの合計が毎秒100を超えない
| 维度 | 令牌桶 (Token Bucket) | 漏桶 (Leaky Bucket) | 滑动窗口 (Sliding Window) |
|---|---|---|---|
| 核心思想 | 桶里装令牌,有令牌才能通过 | 请求进桶,匀速流出处理 | 统计时间窗口内的请求数 |
| 突发流量 | ✅ 允许一定程度的突发(桶里有令牌) | ❌ 强制平滑,突发会被缓存或拒绝 | ❌ 严格按窗口计数,超出一律拒绝 |
| 适用场景 | API 限流、带宽控制(允许突发) | 需要严格匀速处理的场景(如消息队列) | 精确统计(如"1分钟内最多100次") |
| 实现复杂度 | 中等 | 中等 | 较高(需要记录每个时间窗口的请求) |
| Nginx 配置 | limit_req_zone (漏桶) | limit_req_zone (漏桶) | 需第三方模块或 Lua |
# 定义限流区域
# $binary_remote_addr: 按 IP 限流
# zone=mylimit:10m: 区域名称和大小
# rate=10r/s: 每秒最多10个请求
limit_req_zone $binary_remote_addr zone=mylimit:10m rate=10r/s;
server {
listen 80;
server_name api.example.com;
location / {
# 应用限流
# burst=20: 桶容量,允许突发20个请求
# nodelay: 不延迟处理突发请求
limit_req zone=mylimit burst=20 nodelay;
proxy_pass http://backend;
}
}- limit_req_zone: 在 http 块中定义限流区域
- $binary_remote_addr: 使用二进制 IP 地址作为限流键(省内存)
- zone=mylimit:10m: 区域名称 mylimit,分配 10MB 内存
- rate=10r/s: 每秒允许 10 个请求(漏桶算法)
- burst=20: 桶的容量为 20,允许一定程度的突发流量
- nodelay: 不延迟处理突发请求(立即处理或拒绝)
7.3 サーキットブレーカー:障害の拡散を防ぐ
サーキットブレーカーの動作原理:
- クローズ状態: 正常にリクエストを転送し、同時にエラー率を統計
- オープン状態: エラー率が閾値を超えると、サーキットブレーカーがオープンし、直接エラーを返し、リクエストを転送しない
- ハーフオープン状態: 一定時間経過後、少量のリクエストの通過を許可して试探。成功すればサーキットブレーカーをクローズする
💡 核心思想
サーキットブレーカーは電気回路のヒューズのようなもの:電流が大きすぎると、ヒューズが自動的に切れ、回路全体が焼損するのを防ぐ。
同様に、バックエンドサービスに大量のエラーが発生した場合、サーキットブレーカーが「トリップ」し、高速に失敗することで、障害がシステム全体に拡散するのを防ぐ。
8. まとめ:ゲートウェイ設計の核心的思考
8.1 核心原則の振り返り
| 原則 | 意味 | 実践のポイント |
|---|---|---|
| ルーティング | リクエストを正しい場所に届ける | パスルーティング、ドメインルーティング、Headerルーティング |
| ロードバランシング | トラフィックを複数サーバーに分散 | ラウンドロビン、加重、最小接続、IPハッシュ |
| セキュリティ | システムの門を守る | 認証認可、HTTPS、WAF |
| レート制限 | トラフィックに押しつぶされるのを防ぐ | トークンバケット、リーキーバケット、スライディングウィンドウ |
| サーキットブレーカー | 障害の拡散を防ぐ | 高速失敗、フォールバック案 |
| 可観測性 | 監視とトラブルシューティング | ログ、メトリクス、分散トレーシング |
8.2 技術選定の提案
💡 選定デシジョンツリー
ゲートウェイの選択:
│
├─ リバースプロキシ、ロードバランシングのみ必要?
│ ├─ はい → Nginx(第一選択)
│ └─ いいえ → 続行
│
├─ 豊富なプラグインエコシステムが必要?
│ ├─ はい → Kong(Nginxベース)
│ └─ いいえ → 続行
│
├─ Spring Cloud フルスタック?
│ ├─ はい → Spring Cloud Gateway
│ └─ いいえ → Nginx9. 用語クイックリファレンス
| 用語 | 英語 | 説明 |
|---|---|---|
| リバースプロキシ | Reverse Proxy | サーバー側に配置され、クライアントのリクエストを受信して内部サービスに転送するプロキシサービス。クライアントはリバースプロキシの存在のみを知り、実際のサーバーアドレスは知らない。 |
| フォワードプロキシ | Forward Proxy | クライアント側に配置され、クライアントの代わりに外部リソースにアクセスするプロキシサービス。サーバー側はプロキシのIPを見ており、実際のクライアントは知らない。典型的な用途:VPN、ファイアウォール回避ツール。 |
| APIゲートウェイ | API Gateway | クライアントとバックエンドサービスの中間に位置し、ルーティング、認証、レート制限、ログなどの機能を提供する、マイクロサービスアーキテクチャの「統一された門」。 |
| ロードバランシング | Load Balancing | リクエストトラフィックを複数のサーバーに分散し、単一サーバーの過負荷を防ぎ、システムの可用性と性能を向上させる。 |
| SSL終端 | SSL Termination | ゲートウェイ層でHTTPSの暗号化/復号を処理し、バックエンドサービスはHTTPを使用することで、バックエンドの計算オーバーヘッドを削減し、証明書管理を簡素化する。 |
| レート制限 | Rate Limiting | 単位時間あたりのリクエスト数を制限し、システムがバーストトラフィックに押しつぶされるのを防ぐ。よく使われるアルゴリズム:トークンバケット、リーキーバケット、スライディングウィンドウ。 |
| サーキットブレーカー | Circuit Breaking | 依存サービスに障害が発生した場合、自動的に呼び出しを遮断し、障害の拡散を防ぎ、フォールバック案を提供する。 |
| セッション維持 | Session Persistence | 同一クライアントのリクエストが常に同一のバックエンドサーバーにルーティングされることを保証し、セッション状態の維持が必要なシナリオで使用される。 |
| ヘルスチェック | Health Check | バックエンドサービスの健全性状態を定期的にチェックし、障害ノードを自動的に除外し、トラフィックが健全なサービスインスタンスにのみ送信されることを保証する。 |
| カナリアリリース | Canary Release | 少量のトラフィックを新バージョンに誘導し、安定性を検証した後に段階的に割合を拡大し、リリースリスクを低減する。 |
| WAF | Web Application Firewall | Webアプリケーションファイアウォール。SQLインジェクション、XSS、CC攻撃などのWebセキュリティ脅威を防御する。 |
| CDN | Content Delivery Network | コンテンツデリバリーネットワーク。世界中にエッジノードを配置し、静的リソースへのアクセスを高速化する。 |