ネットワークレイヤースタックの構造(OSI 7階層 vs TCP/IP 4階層)
バックエンドシステムを設計・構築する上で、ネットワークスタックの理解は不可欠です。以下は、OSI 7階層モデルとTCP/IP 4階層モデルの対応関係、およびバックエンド開発において重要となる技術要素の整理です。
+-----------------------------------+-----------------------------------+
| OSI 7階層モデル | TCP/IP 4階層モデル |
+-----------------------------------+-----------------------------------+
| 第7層: アプリケーション層 | |
| 第6層: プレゼンテーション層 | 第4層: アプリケーション層 |
| 第5層: セッション層 | |
+-----------------------------------+-----------------------------------+
| 第4層: トランスポート層 | 第3層: トランスポート層 |
+-----------------------------------+-----------------------------------+
| 第3層: ネットワーク層 | 第2層: インターネット層 |
+-----------------------------------+-----------------------------------+
| 第2層: データリンク層 | 第1層: ネットワークアクセス層 |
| 第1層: 物理層 | |
+-----------------------------------+-----------------------------------+
第5層~第7層 (OSI) $\rightarrow$ 第4層: アプリケーション層 (TCP/IP)
アプリケーションソフトウェアと直接相互作用し、データを生成してネットワーク経由でデータを交換するための通信プロトコルを定義します。
- HTTP/HTTPS:
- REST API設計: リソースの構造化、適切なHTTPメソッド(GET, POST, PUT, DELETE)の利用、およびステータスラインの定義。
- ステータスコード: 成功($2xx$)、クライアントエラー($4xx$)、サーバーエラー($5xx$)のセマンティクス分類。
- ヘッダー管理:
Cookie、Cache-Control、CORS(Cross-Origin Resource Sharing)などの制御。 - セッションおよびプロキシヘッダー:
Set-Cookie: セッションIDや個別設定をブラウザに送信し、セッション管理を開始するためにサーバーから付与されます。Cookie: ブラウザに保存されたクッキー情報を、その後のリクエストでサーバーに返送します。X-Forwarded-For(XFF) およびX-Forwarded-Proto(XFP): プロキシやロードバランサーを経由する際、オリジナルのクライアントIPおよびプロトコルを特定するために使用されます。- gRPC:
- HTTP/2をベースとしたRemote Procedure Call (RPC) フレームワークであり、マイクロサービスアーキテクチャ(MSA)における高速・低遅延なサービス間通信に用いられます。
- バイナリフレーミング: JSONのようなテキストベースのメッセージではなく、データを「フレーム」と呼ばれるバイナリ形式にシリアライズすることで、ペイロードのオーバーヘッドを削減し、パース処理を高速化します。
- マルチプレキシング: 単一のTCPコネクション内に「ストリーム」と呼ばれる仮想的な双方向チャネルを複数生成し、リクエストとレスポンスを並行して多重送信することで、アプリケーションレイヤーにおけるHead-of-Line (HoL) ブロッキングを解消します。
- HPACK: HTTP/2ヘッダー専用の圧縮アルゴリズムであり、静的・動的テーブルを用いて重複するヘッダーフィールドを排除し、帯域幅の消費を抑えます。
- サーバープッシュ: クライアントからの最初のリクエストを解析し、クライアントが明示的に要求する前に、必要となるリソースをサーバー側から先行してクライアントキャッシュに送信する機能です。
- データシリアライズ: ネットワーク送信のために、JSONやProtocol Buffers (Protobuf) などのフォーマットを用いて構造化データを変換・解析します。
- 認証と認可: JSON Web Token (JWT) やセッションベースのアーキテクチャを用いた、安全なユーザー識別とアクセス制御の実装。
第4層 (OSI) $\rightarrow$ 第3層: トランスポート層 (TCP/IP)
送信元ホストから送信先ホストまでの特定のプロセス(ポート番号で識別)間における、エンドツーエンドの通信信頼性、フロー制御、およびコネクション管理を制御します。
- TCP (Transmission Control Protocol):
- コネクション管理: 3-Way ハンドシェイク(SYN $\rightarrow$ SYN-ACK $\rightarrow$ ACK)による接続確立、および 4-Way ハンドシェイク(FIN $\rightarrow$ ACK $\rightarrow$ FIN $\rightarrow$ ACK)による接続終了。
- 信頼性保証メカニズム: シーケンス番号、確認応答(ACK)、およびパケット損失時の自動再送による、データの順序保証と到達確認。
- アプリケーションの基盤: HTTP/1.1、HTTP/2、およびデータベース接続プール(HikariCPなど)の基盤プロトコルとして機能。
- パフォーマンス機能:
Keep-Alive: 確立済みのTCPコネクションを複数のリクエストで再利用し、ハンドシェイクの繰り返しによるオーバーヘッドを削減します。Pipelining: HTTP/1.1において、前のリクエストのレスポンスを待たずに次のリクエストを送信する機能(ただし、アプリケーション層のHoLブロッキングによる制約を受けます)。- UDP (User Datagram Protocol):
- コネクションレス型で軽量なプロトコルであり、信頼性よりも速度と低オーバーヘッドを優先します。パケットの到達や順序は保証されません。
- DNSクエリ、WebRTC、リアルタイムメディアストリーミング、オンラインゲームなどで広く利用されています。
- ポートの概念: サーバー上で動作する特定のプロセスを識別・ルーティングするための論理アドレス($0$ から $65535$ の範囲。例: HTTPはポート $80$、HTTPSはポート $443$)。
第3層 (OSI) $\rightarrow$ 第2層: インターネット層 (TCP/IP)
複数のネットワークをまたいで送信元から送信先までの経路(ルーティング)を決定し、パケット単位でデータを転送します。
- IP (IPv4 / IPv6): ネットワーク上のホストを一意に識別するための論理アドレス体系。
- ルーターとゲートウェイ: 異なるネットワークセグメント間でトラフィックを中継・転送する物理または仮想機器(クラウド環境における異なるVPCサブネット間のルーティングなど)。
- サブネットマスク設計: ネットワークを論理的に小さなサブネットワークに分割し、IPアドレスの割り当てを最適化するとともに、セキュリティ境界を定義します。
第1層~第2層 (OSI) $\rightarrow$ 第1層: ネットワークアクセス層 (TCP/IP)
物理的な媒体(ケーブル、光ファイバー、無線など)を介した生のビットストリームの伝送、および同一ローカルネットワーク内のノード間データ転送を管理します。
- MACアドレス: ネットワークインターフェースカード(NIC)にハードウェアレベルで割り当てられた一意の物理アドレス。
- ARP (Address Resolution Protocol): 既知のIPアドレスに対応する物理MACアドレスを動的に解決し、ローカルエリアネットワーク(LAN)内での通信を可能にするプロトコル。
- スイッチ: 受信したフレームの宛先MACアドレスを解析し、適切なデバイスが接続されたポートにのみデータを転送するローカルネットワーク機器。
プロトコルの変遷: HTTP/1.1 vs HTTP/2 vs HTTP/3 (QUIC)
HTTPプロトコルの進化は、レイテンシの削減、コネクション利用効率の向上、および下位トランスポートプロトコルの制約の克服に焦点を当ててきました。
| 機能・項目 | HTTP/1.1 | HTTP/2 | HTTP/3 |
|---|---|---|---|
| 下位プロトコル | TCP | TCP | UDP (QUIC) |
| データフォーマット | プレーンテキスト | バイナリフレーム | バイナリフレーム |
| マルチプレキシング | ❌ (順次処理 / パイプライン化) | ⭕ (単一コネクション上の多重ストリーム) | ⭕ (ストリーム単位 of 高度な多重化) |
| HOLB (Head-of-Line Blocking) | アプリケーション層: 先行リクエストの遅延が後続をブロック。 | トランスポート層: 単一パケットの損失が全ストリームをブロック。 | 解消: パケット損失は該当ストリームのみに影響し、他は継続。 |
| ヘッダー圧縮 | ❌ (プレーンテキスト、重複送信) | ⭕ HPACK (静的/動的テーブルとハフマン符号化) | ⭕ QPACK (UDP/QUIC向けに最適化、順序反転によるブロックを防止) |
| 接続ハンドシェイク | 低速: TCP 3-Way ($1$ RTT) + TLS ($1$-$2$ RTT) | 低速: TCP + TLS (データ転送までに複数往復が必要) | 高速: トランスポートと暗号化のハンドシェイクを統合 (1-RTT / 0-RTT) |
DNS (Domain Name System) の解決フローとレコード設計
DNSは、人間が理解しやすいドメイン名を、マシンが理解できるIPアドレスに変換する分散型データベースシステムです。
[Client] ---> (1) Local DNS Cache / Resolver
|
+---> (2) Root DNS Server (.)
|
+---> (3) TLD DNS Server (.com)
|
+---> (4) Authoritative DNS Server (example.com)
1. DNSクエリ解決プロセス
ユーザーがブラウザに https://example.com と入力した際、システムは以下の階層的なルックアッププロセスを経てIPアドレスを解決します。
- ローカルDNSキャッシュの確認: クライアント端末はまず、ISP(インターネットサービスプロバイダ)などが提供するローカルDNSサーバーに問い合わせます。キャッシュに有効なレコードが存在すれば、即座にIPアドレスが返されます。
- ルートDNSサーバー (.) への問い合わせ: ローカルDNSサーバーにキャッシュがない場合、世界のルートDNSサーバーに問い合わせを行います。ルートサーバーはトップレベルドメイン(例:
.com)を解析し、対応するTLDサーバーの情報を返します。 - TLD DNSサーバー (.com) への問い合わせ: ローカルDNSサーバーは、指定された
.comTLDサーバーに問い合わせます。TLDサーバーは、対象ドメインが登録されているレジストラのネームサーバー(権威DNSサーバー)のアドレスを返します。 - 権威DNSサーバーへの問い合わせ: ローカルDNSサーバーは、開発者がドメインレコードを管理している権威DNSサーバーに問い合わせを行い、最終的なIPアドレスまたはレコード値を取得します。
- キャッシュと接続: ローカルDNSサーバーは取得したIPアドレスをクライアントに返し、設定されたTTL(Time To Live)の間、その結果をキャッシュします。ブラウザは解決されたIPアドレスに対して接続を開始します。
2. バックエンド設計に必要な3つの主要DNSレコード
ネームサーバーでドメインを設定する際、ルーティングの目的に応じて適切なレコードタイプを選択する必要があります。
- Aレコード (Address Record):
- 概念: ドメイン名を特定のIPv4アドレスに直接マッピングします。
- 設定例:
example.com$\rightarrow$13.125.1.2(EC2インスタンスなどの静的パブリックIP)。 - 特徴: サーバーのパブリックIPが変更された場合、ネームサーバー上の値を手動で更新する必要があります。
- CNAMEレコード (Canonical Name Record):
- 概念: ドメイン名をIPアドレスではなく、別のドメイン名(エイリアス)にマッピングします。
- 設定例:
api.example.com$\rightarrow$my-load-balancer-123456.amazonaws.com(AWS ALBのドメイン)。 - 特徴: ロードバランサーやCDN(Cloudflareなど)のように、動的にIPアドレスが変化するインフラストラクチャに対して、名前解決の整合性を維持するために使用されます。
- MXレコード (Mail Exchanger Record):
- 概念: 対象ドメイン宛ての電子メールを受信するメールサーバーを指定します。
- 設定例:
example.com宛てのメール $\rightarrow$ Google Workspaceのメールサーバー (aspmx.l.google.com) へルーティング。 - 特徴: 優先度(Priority)を設定することで、プライマリサーバーがダウンした際にセカンダリサーバーへ自動でフォールバックさせる冗長化構成が可能です。
3. 実務におけるDNS運用管理
- TTL (Time To Live) の制御: TTLはDNSレコードがキャッシュされる時間を秒単位で指定するパラメータです。サーバーの移設やIPアドレスの変更を伴うメンテナンスを行う際は、事前にTTLを60秒(1分)などの短い値に下げておくことで、切り替え後の反映遅延によるダウンタイムを最小限に抑えることができます。
- サブドメインルーティング: インフラの役割ごとにサブドメインを分割して管理します。
example.com$\rightarrow$ 静的ウェブサーバー (AまたはCNAME)api.example.com$\rightarrow$ バックエンドAPIゲートウェイ (CNAME)dev-api.example.com$\rightarrow$ 開発環境用ゲートウェイ- TXTレコードの活用: 任意のテキストデータをドメインに関連付けるレコードであり、主に以下の用途で使用されます。
- ドメイン所有権の検証: Google WorkspaceやAWS SESなどの外部サービス利用時に、指定された一意の文字列を登録して所有権を証明します。
- メール送信ドメイン認証: SPF(Sender Policy Framework)やDKIM(DomainKeys Identified Mail)を設定し、なりすましメールやスパム判定を防止します。
プロキシとリバースプロキシの役割分担
プロキシサーバーは、クライアントとサーバーの間で通信を中継する中間サーバーです。通信のどちら側に位置するかによって、フォワードプロキシとリバースプロキシに分類されます。
[Forward Proxy]
[Client 1] --+
[Client 2] --+--> [Forward Proxy] ---> [Internet] ---> [Target Server]
[Reverse Proxy]
[Client] ---> [Internet] ---> [Reverse Proxy (Nginx)] ---> [WAS 1]
---> [WAS 2]
1. フォワードプロキシとリバースプロキシの比較
フォワードプロキシ
- 配置場所: クライアント側のネットワーク内に配置されます。
- 代理対象: クライアントを代理します。宛先サーバーからはプロキシのIPアドレスのみが見え、実際のクライアントのIPアドレスは隠蔽されます。
- 主な用途:
- 社内ネットワークからの外部サイトへのアクセス制限(セキュリティポリシーの適用)。
- クライアントの匿名性確保、または特定の地域制限の回避。
- 頻繁にアクセスされる外部リソースのキャッシュによる帯域幅の節約。
リバースプロキシ
- 配置場所: サーバーインフラの境界(バックエンドサーバーの前方)に配置されます。
- 代理対象: サーバーを代理します。クライアントはリバースプロキシを最終宛先として認識し、内部のサーバー構成を知ることはできません。
- 代表的なソフトウェア: Nginx、Apache HTTP Server、AWS Application Load Balancer (ALB)、Cloudflare。
- 主な用途: バックエンドサーバーの保護、負荷分散、SSL/TLS終端の集約。
2. リバースプロキシが不可欠な理由
アプリケーションサーバー(Spring Boot、Express、Djangoなど)をパブリックインターネットに直接公開することは、セキュリティ上のリスクを伴います。リバースプロキシ(例: Nginx)を前段に配置することで、以下のメリットが得られます。
- 負荷分散 (Load Balancing): 複数のバックエンドWebアプリケーションサーバー(WAS)にトラフィックを分散させます。定期的なヘルスチェックを行い、異常が発生したインスタンスへのルーティングを自動的に遮断します。
- セキュリティとサーバーの隠蔽: 内部ネットワーク IPアドレスやポート構成を外部から隠蔽します。不正なリクエストを境界で遮断し、Webアプリケーションファイアウォール(WAF)と連携してDDoS攻撃などの脅威を緩和します。
- SSL/TLS終端 (SSL Termination): CPU負荷の高い暗号化・復号処理をリバースプロキシで集約して処理します。リバースプロキシとバックエンドWAS間は軽量なHTTPで通信させることで、WASのCPUリソースをビジネスロジックの実行に集中させることができます。
- 静的コンテンツのキャッシュ: 画像、CSS、JavaScriptなどの静的ファイルをリバースプロキシのディスクやメモリから直接クライアントに返却し、WASへの不要なリクエスト転送を削減します。
3. クライアントIPの追跡メカニズム
リバースプロキシを経由すると、バックエンドWASが取得する接続元IPアドレスはリバースプロキシの内部IPアドレスになってしまいます。アクセスログの記録やレートリミット制御のために、オリジナルのクライアントIPを伝播させる必要があります。
リバースプロキシは、リクエストをバックエンドに転送する前に以下のヘッダーを付与します。
X-Forwarded-For (XFF): クライアントおよび経由したプロキシのIPアドレスがカンマ区切りで連結されたリスト。先頭の値がオリジナルのクライアントIPです。X-Real-IP: リバースプロキシに直接接続してきた直前のクライアント(またはプロキシ)のIPアドレス。
Nginxにおける設定例:
server {
listen 80;
server_name api.example.com;
location / {
proxy_pass http://backend_servers;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
L4/L7 ロードバランサーとトラフィック分散アルゴリズム
ロードバランサーは、高可用性と耐障害性を確保するために、複数のサーバーにトラフィックを分散させるコンポーネントです。
[L4 Load Balancer]
[Client] ---> [L4 LB (IP/Port-based)] ---> [Server A (10.0.0.1:80)]
---> [Server B (10.0.0.2:80)]
[L7 Load Balancer]
[Client] ---> [L7 LB (URL/Header-based)] ---> /api/users ---> [User Service]
---> /api/orders ---> [Order Service]
1. L4とL7ロードバランサーの技術的差異
L4ロードバランサー(トランスポート層)
- 動作レイヤー: OSI第4層(トランスポート層)。
- ルーティング基準: IPアドレス、ポート番号、TCP/UDPプロトコルヘッダーの情報のみに基づいてトラフィックを分散します。
- 特徴:
- アプリケーションレイヤーのペイロード(HTTPボディ、クッキー、ヘッダーなど)を解析しないため、処理が極めて高速でリソース消費が少ない。
- SSL/TLSの復号や、URLパスに基づくルーティングは行えません。
- 用途: インフラの最外周に配置し、大量のトラフィックを下位のL7ロードバランサー群に高速に振り分ける用途に適しています。
L7ロードバランサー(アプリケーション層)
- 動作レイヤー: OSI第7層(アプリケーション層)。
- ルーティング基準: HTTP URI、クッキー、HTTPヘッダー、ペイロードの内容を解析してルーティングを決定します。
- 特徴:
- コンテンツベースルーティングが可能(例: URLパスに応じたマイクロサービスへの振り分け)。
- SSL/TLSの終端処理や、クッキー値を用いたセッション維持(Sticky Session)が可能です。
- パケットの復号と解析を行うため、L4ロードバランサーと比較してCPUおよびメモリのリソース消費が大きくなります。
- 用途: AWS ALB、Nginx、HAProxyなど。マイクロサービスアーキテクチャ(MSA)において、
/api/users宛てのリクエストをユーザーサービスに、/api/orders宛てを注文サービスにルーティングする構成などに用いられます。
2. 代表的なトラフィック分散アルゴリズム
- ラウンドロビン (Round Robin):
- 仕組み: 利用可能なサーバーに対して、順番に均等にリクエストを割り当てます。
- 適した環境: 各サーバーのスペックが同一であり、リクエストごとの処理負荷に大きな偏りがない環境。
- 加重ラウンドロビン (Weighted Round Robin):
- 仕組み: 各サーバーに静的な「重み(Weight)」を設定し、スペックの高いサーバーに対して比例して多くのリクエストを割り当てます。
- 適した環境: 新旧のサーバーが混在し、処理能力に差がある環境。
- 最小接続数 (Least Connections):
- 仕組み: 現在アクティブな接続数が最も少ないサーバーに優先してリクエストを割り当てます。
- 適した環境: 接続時間が長い処理(WebSocketなど)や、リクエストごとの処理負荷の変動が大きい環境。
- IPハッシュ / ソースハッシュ (IP Hash):
- 仕組み: クライアントのIPアドレスをハッシュ関数にかけ、その結果に基づいて特定のサーバーに固定的に割り当てます。
- 適した環境: セッション情報をサーバーのローカルメモリに保持しているレガシーなアプリケーションで、同一クライアントからのリクエストを常に同じサーバーに送信したい環境。
3. ヘルスチェックの重要性
ロードバランサーは、バックエンドサーバーの稼働状態を監視し、異常を検知したサーバーを自動的にルーティング対象から除外します。
- L4ヘルスチェック: 対象ポートに対してTCP 3-Wayハンドシェイクを試行し、ポートが開いているか確認します。アプリケーションプロセスがフリーズしてエラー(500 Internal Server Errorなど)を返していても、ポートが開いていれば「正常」と判定される弱点があります。
- L7ヘルスチェック: 実際にHTTPリクエスト(例:
GET /healthz)を送信し、ステータスコード200 OKなどの正常応答が返ってくるかを確認します。データベース接続などの依存関係の健全性も含めて判定するよう、バックエンド側でヘルスチェックエンドポイントを実装することが推奨されます。
4. コンテナのライフサイクルとトラフィック制御
コンテナのローリングアップデートやゼロダウンタイムスケーリング(Zero-downtime scaling)の際、サービスディスカバリとロードバランサーの連携は不可欠です。コンテナが置換される際、古いコンテナへの新規トラフィックを遮断し、既存のコネクションを維持しながら緩やかにトラフィックを移行する「コネクションドレーニング(Connection Draining)」の制御が、L7ロードバランサーやリバースプロキシのレイヤーで実行されます。
ネットワークデバッグとトラブルシューティングのワークフロー
サービス間の通信エラーやAPI接続障害が発生した際、原因を特定するために以下のコマンドラインツールを使用します。
# ネットワーク疎通および診断コマンド一覧
ping [IP/Domain]
nslookup [Domain]
traceroute [IP/Domain]
curl [URL]
1. ping — ネットワーク層 (L3) の疎通確認
- 目的: 対象ホストが起動しており、ネットワーク的に到達可能かを確認します。
- 実行例:
ping -c 4 google.com
- 注意点: クラウド環境(AWSセキュリティグループなど)や企業用ファイアウォールでは、セキュリティ上の理由からICMPプロトコル(
pingが使用するプロトコル)を遮断していることが多く、pingが通らないからといって必ずしもWebサービスがダウンしているとは限りません。
2. nslookup — DNSレコードの検証
- 目的: ドメイン名が正しいIPアドレスに解決されているかを確認します。
- 実行例:
nslookup google.com
3. traceroute — ルーティング経路の追跡
- 目的: 送信元から宛先サーバーに到達するまでに経由するルーターの経路と、各ホップでの遅延を測定します。
- 実行例:
traceroute google.com
- 結果の分析: 特定のホップ以降でタイムアウト(
* * *)が連続して発生する場合、その境界に位置するルーターやファイアウォールでパケットが遮断されている可能性が高いと判断できます。
4. curl — アプリケーション層 (L7) の疎通確認
- 目的: 実際にHTTPリクエストを送信し、サーバーからのレスポンスヘッダーやボディ、TLSハンドシェイクの詳細を確認します。
- 実行例:
curl -v https://example.com
エンドツーエンド・リクエストライフサイクル
ユーザーがブラウザにURLを入力してから、画面にデータが表示されるまでの通信の流れをステップごとに追跡します。
[Browser] --(1. DNS Query)--> [DNS Server]
|
(2. TCP/QUIC Handshake & HTTPS Request)
v
[L7 Load Balancer (ALB)] --(3. SSL Termination & Route)--> [Nginx (Reverse Proxy)]
|
(4. Forward Request)
v
[Database] <--(6. SQL Query / Connection Pool)-- [WAS (Spring Boot / Node.js)]
ステップ 1: ネームサーバーの解決 (DNS Query)
- アドレス入力: ユーザーがブラウザに
https://example.com/v1/usersと入力します。 - IPアドレスの検索: ブラウザはドメインに対応するIPアドレスを特定するため、ローカルDNSキャッシュを確認し、必要に応じて権威DNSサーバー(AWS Route 53など)に問い合わせを行います。
- レコードの返却: 権威DNSサーバーは、
example.comに設定されているCNAMEレコード(ロードバランサーのドメイン)を解決し、対応するIPアドレスをブラウザに返却します。
ステップ 2: 境界ゲートウェイの通過 (L7 Load Balancer & SSL)
- 接続の確立: ブラウザは解決されたロードバランサー(ALB)のIPアドレスに対して、TCP 3-Wayハンドシェイク(またはHTTP/3の場合はUDPベースのQUICハンドシェイク)を実行し、コネクションを確立します。
- SSL終端: ALBはクライアントとの間でTLSハンドシェイクを完了させ、暗号化されたHTTPSリクエストを復号してプレーンなHTTPリクエストに変換します。
- パスベースルーティング: ALBはリクエストのURIパス
/v1/usersを解析し、あらかじめ定義されたルーティングルールに従って、プライベートサブネット内に配置されているNginxリバースプロキシサーバーへリクエストを転送します。
ステップ 3: リバースプロキシによる中継 (Reverse Proxy)
- プロキシ処理: Nginxはリクエストを受信し、バックエンドのアプリケーションサーバー(WAS)へ転送する準備を行います。
- クライアントIPの付与: Nginxは、バックエンドWASが実際のクライアントを識別できるように、
X-Forwarded-ForおよびX-Real-IPヘッダーにクライアントのパブリックIPアドレスを注入します。 - WASへの転送: Nginxは、ローカルまたは同一ネットワーク内のWASがリッスンしているポートに対してリクエストを転送します。
ステップ 4: ビジネスロジックの実行とデータ取得 (WAS & DB)
- リクエストの解析: WAS(Spring BootやNode.jsなど)は、受信したHTTPリクエストをパースし、ヘッダーやクエリパラメータをアプリケーションコードで扱えるオブジェクトにマッピングします。
- コネクションの取得: ビジネスロジックの実行に伴いデータベースアクセスが必要になった場合、WASはあらかじめ確立されているデータベース接続プール(HikariCPなど)からアクティブなTCP接続を1つ取得します。
- クエリの実行: WASは取得した接続を介して、データベースサーバー(MySQLやPostgreSQLなど)に対してSQLクエリ(例:
SELECT * FROM users;)を送信します。 - データの返却: データベースはメモリバッファまたはディスクから該当レコードを抽出し、WASに対して結果を返却します。
ステップ 5: レスポンスの返送 (Response)
- シリアライズ: WASはデータベースから取得したデータをJSON形式のペイロードにシリアライズし、ステータスコード
200 OKを含むHTTPレスポンスオブジェクトを構築します。 - 逆経路での転送: レスポンスは、送信時と逆の経路をたどって返送されます。 $$\text{WAS} \longrightarrow \text{Nginx} \longrightarrow \text{ALB (SSL再暗号化)} \longrightarrow \text{インターネット} \longrightarrow \text{クライアントブラウザ}$$
- レンダリング: ブラウザは受信したJSONデータを解析し、DOMに反映してユーザーの画面上に情報をレンダリングします。これにより、一連のリクエスト・レスポンスサイクルが完了します。
Key Takeaways
- 階層モデルの理解: ネットワークトラブルの発生時、問題が物理層・トランスポート層(ポート未開放、パケットドロップ)にあるのか、アプリケーション層(DNS設定ミス、HTTP 5xxエラー)にあるのかを切り分ける基準となります。
- プロトコルの選択: HTTP/2のマルチプレキシングやHTTP/3のQUICによるハンドシェイク高速化など、プロトコルごとの特性を理解してシステム設計に反映することが重要です。
- ヘッダーの伝播: リバースプロキシやロードバランサーを多段に構成するインフラ設計においては、
X-Forwarded-Forなどのヘッダーを適切に制御し、クライアントの識別性を維持する必要があります。