- Published on
開発者のためのネットワーク基礎完全攻略:TCP/IP、HTTP、DNS、TLSからgRPC、WebSocketまで
- Authors

- Name
- Youngju Kim
- @fjvbn20031
- 1. なぜ開発者にネットワーク知識が必須なのか
- 2. TCP vs UDP 深掘り
- 3. IP、サブネット、ルーティング
- 4. DNS 完全攻略
- 5. HTTPの進化:1.0から1.1、2、3まで
- 6. HTTPSとTLS 1.3
- 7. REST vs GraphQL vs gRPC vs WebSocket
- 8. CDNとロードバランシング
- 9. 実践デバッグツール
- 10. 面接予想質問15選
- 11. クイズ
- 12. 参考資料
1. なぜ開発者にネットワーク知識が必須なのか
面接で頻出の定番テーマ
開発者の面接で「ブラウザにURLを入力すると何が起こるか?」という質問はほぼ定番です。この質問一つにDNS、TCP、TLS、HTTP、ルーティング、ロードバランシング、レンダリングまですべて含まれます。ネットワークを知らなければ、この質問に対する深い回答は不可能です。
デバッグとパフォーマンス最適化の核心
APIが遅いのに原因がわからない場合は、ネットワークレベルで見る必要があります。DNS解決に500msかかっているのか、TCP接続確立に時間がかかっているのか、TLSハンドシェイクがボトルネックなのか、それともサーバーレスポンス自体が遅いのか。ネットワークを理解すれば、curl -w一つでどこがボトルネックかすぐに把握できます。
アーキテクチャ設計の基盤
マイクロサービス間通信にRESTを使うかgRPCを使うか、WebSocketが必要かSSEで十分か、CDNをどこに配置するか — これらすべての判断の基盤がネットワーク知識です。
OSI 7層 vs TCP/IP 4層の比較
実務ではOSI 7層よりTCP/IP 4層をよく使います。以下の比較表を参考にしてください。
| TCP/IP 4層 | OSI 7層 | プロトコル例 | 役割 |
|---|---|---|---|
| アプリケーション層 | アプリケーション(7)、プレゼンテーション(6)、セッション(5) | HTTP, FTP, SMTP, DNS, gRPC | ユーザーデータ処理 |
| トランスポート層 | トランスポート(4) | TCP, UDP | ポートベースのプロセス間通信 |
| インターネット層 | ネットワーク(3) | IP, ICMP, ARP | IPアドレスベースのルーティング |
| ネットワークアクセス層 | データリンク(2)、物理(1) | Ethernet, Wi-Fi | 物理的データ伝送 |
面接のヒント:「OSI 7層を説明してください」という質問が出たら、TCP/IP 4層とのマッピングも一緒に説明すると差別化できます。
2. TCP vs UDP 深掘り
TCP:信頼性のある接続指向プロトコル
TCP(Transmission Control Protocol)はデータの順序保証、損失回復、フロー制御を提供するプロトコルです。
3ウェイハンドシェイク(接続確立)
クライアント サーバー
|--- SYN (seq=x) -------->|
|<-- SYN-ACK (seq=y, ack=x+1) ---|
|--- ACK (ack=y+1) ------>|
| 接続確立完了 |
- SYN:クライアントがサーバーに接続要求(シーケンス番号xを送信)
- SYN-ACK:サーバーが要求を受け入れ、自身のシーケンス番号yとともに応答
- ACK:クライアントが確認応答を送り、接続確立完了
4ウェイターミネーション(接続終了)
クライアント サーバー
|--- FIN ----------------->|
|<-- ACK ------------------|
|<-- FIN ------------------|
|--- ACK ----------------->|
| TIME_WAIT (2MSL) |
接続終了に4段階が必要な理由は、双方向ストリームをそれぞれ独立して終了するためです。TIME_WAIT状態は、遅延パケットが新しい接続に影響を与えないように保護する役割を果たします。
フロー制御 — スライディングウィンドウ
受信者のバッファがオーバーフローしないように、**ウィンドウサイズ(Window Size)**を通じて一度に送信できるデータ量を調整します。
送信ウィンドウ:
[送信済み&ACK済み] [送信済み,未ACK] [送信可能] [送信不可]
|<--- Window Size --->|
受信者はACKに自身の受信ウィンドウ(rwnd)値を含めて送信者に通知します。
輻輳制御(Congestion Control)
ネットワークの輻輳を検知し、送信速度を調整するメカニズムです。
- スロースタート:cwnd(輻輳ウィンドウ)を1 MSSから開始し、指数的に増加
- 輻輳回避(AIMD):ssthresh到達後に線形的に増加、パケット損失時に半減
- 高速再送:3つの重複ACK受信時にタイムアウト前に再送
- 高速回復:高速再送後、スロースタートではなく輻輳回避に移行
cwnd
^
| /\
| / \ /\
| / \ / \ /
| / \ / \ /
| / X \/
| / ssthresh
| /
| / スロースタート
|/__________________ time
Nagleアルゴリズムと TCP_NODELAY
Nagleアルゴリズムは小さなパケットをまとめて一度に送信することでネットワーク効率を高めます。しかし、リアルタイムアプリケーション(ゲーム、トレーディング)では遅延が問題になります。
// Nagleアルゴリズムの無効化
int flag = 1;
setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, &flag, sizeof(int));
UDP:コネクションレスプロトコル
UDP(User Datagram Protocol)は接続設定なしにデータグラムを送信します。信頼性はありませんが、オーバーヘッドが少なく高速です。
UDPの使用事例:
- DNSクエリ:単一のリクエスト-レスポンス、高速応答が重要
- オンラインゲーム:多少のパケット損失より低遅延が重要
- リアルタイムストリーミング:音声/映像での再送は無意味
- QUIC(HTTP/3):UDP上で信頼性を自ら実装
TCP vs UDP 比較表
| 特性 | TCP | UDP |
|---|---|---|
| 接続方式 | 接続指向(3ウェイハンドシェイク) | コネクションレス |
| 信頼性 | 保証(再送、順序保証) | 非保証 |
| 順序保証 | あり | なし |
| フロー/輻輳制御 | あり | なし |
| ヘッダーサイズ | 20バイト | 8バイト |
| 速度 | 比較的遅い | 高速 |
| 使用事例 | HTTP, FTP, SMTP, SSH | DNS, ゲーム, ストリーミング, QUIC |
3. IP、サブネット、ルーティング
IPv4 vs IPv6 比較
| 特性 | IPv4 | IPv6 |
|---|---|---|
| アドレス長 | 32ビット(4オクテット) | 128ビット(8グループ) |
| アドレス例 | 192.168.1.1 | 2001:0db8:85a3::8a2e:0370:7334 |
| アドレス数 | 約43億個 | 事実上無限 |
| NAT必要性 | 必須 | 不要 |
| IPsec | 任意 | 標準搭載 |
| ヘッダー | 可変長 | 固定40バイト |
CIDR表記法とサブネットマスク
CIDR(Classless Inter-Domain Routing)はIPアドレスの後ろにスラッシュとプレフィックス長を付けてネットワークを表現します。
192.168.1.0/24
├── ネットワーク部分: 192.168.1 (24ビット)
└── ホスト部分: 0~255 (8ビット, 256個のアドレス中使用可能254個)
10.0.0.0/16
├── ネットワーク部分: 10.0 (16ビット)
└── ホスト部分: 0.0~255.255 (16ビット, 65,536個のアドレス)
よく使うCIDR:
| CIDR | サブネットマスク | 使用可能ホスト | 用途 |
|---|---|---|---|
| /32 | 255.255.255.255 | 1 | 単一ホスト |
| /24 | 255.255.255.0 | 254 | 一般的なサブネット |
| /16 | 255.255.0.0 | 65,534 | 大規模ネットワーク |
| /8 | 255.0.0.0 | 16,777,214 | クラスA |
NAT(Network Address Translation)
プライベートIPアドレスをパブリックIPアドレスに変換する技術です。
プライベートネットワーク NATルーター インターネット
[192.168.1.10] ---+
[192.168.1.11] ---+--- [NAT] --- [203.0.113.1] --- [サーバー]
[192.168.1.12] ---+
プライベートIP帯域(RFC 1918):
10.0.0.0/8(10.0.0.0 ~ 10.255.255.255)172.16.0.0/12(172.16.0.0 ~ 172.31.255.255)192.168.0.0/16(192.168.0.0 ~ 192.168.255.255)
Docker/K8sネットワーキングとの関連
Dockerネットワーキング:
bridge:デフォルトネットワーク、コンテナ間通信host:ホストネットワークを直接使用overlay:マルチホスト間のコンテナ通信(Docker Swarm)none:ネットワーク無効化
Kubernetesネットワーキング原則:
- すべてのPodは固有のIPを持つ
- すべてのPodはNATなしに他のPodと通信できる
- すべてのNodeのエージェントはすべてのPodと通信できる
K8sクラスタ
+-------------------------------------+
| Node 1 Node 2 |
| +---------+ +---------+ |
| | Pod A | | Pod C | |
| | 10.1.1.2|<-------->| 10.1.2.3| |
| +---------+ +---------+ |
| | Pod B | | Pod D | |
| | 10.1.1.3| | 10.1.2.4| |
| +---------+ +---------+ |
| CNI Plugin (Calico/Flannel) |
+-------------------------------------+
KubernetesではCNI(Container Network Interface)プラグイン(Calico、Flannel、Ciliumなど)がPod間ネットワーキングを担当します。ServiceリソースはL4ロードバランサーの役割を果たし、IngressはL7ルーティングを提供します。
4. DNS 完全攻略
DNSクエリプロセス
DNS(Domain Name System)はドメイン名(例:www.example.com)をIPアドレスに変換する分散データベースシステムです。
ユーザー → ローカルDNSキャッシュ → 再帰リゾルバ → ルートサーバー → TLDサーバー → 権威サーバー
| | |
"." ルート ".com" TLD "example.com"
→ IP: 93.184.216.34
再帰クエリ(Recursive Query):
- クライアントが再帰リゾルバに最終回答を要求
- リゾルバがルート → TLD → 権威サーバーを順番にクエリしてIPを返却
反復クエリ(Iterative Query):
- 各サーバーが次にクエリすべきサーバーを教える方式
- リゾルバが各サーバーに順次クエリ
DNSレコード種類
| レコード | 用途 | 例 |
|---|---|---|
| A | ドメイン → IPv4アドレス | example.com → 93.184.216.34 |
| AAAA | ドメイン → IPv6アドレス | example.com → 2606:2800:220:1:... |
| CNAME | ドメイン → 別ドメイン(エイリアス) | www.example.com → example.com |
| MX | メールサーバー指定 | example.com → mail.example.com (priority 10) |
| TXT | テキスト情報(SPF, DKIMなど) | v=spf1 include:_spf.google.com ~all |
| NS | ネームサーバー指定 | example.com → ns1.example.com |
| SOA | ドメイン権限開始点 | シリアル、リフレッシュ、有効期限等の管理情報 |
| SRV | サービスロケーション情報 | ポート、重みを含むサービスディスカバリ |
| PTR | IP → ドメイン(逆引き) | 34.216.184.93 → example.com |
TTLとキャッシュ戦略
TTL(Time To Live)はDNSレコードがキャッシュに保持される時間(秒)です。
| TTL値 | 適切な状況 |
|---|---|
| 60秒(1分) | インフラマイグレーション直前、高速切り替えが必要 |
| 300秒(5分) | 一般的なWebサービス |
| 3600秒(1時間) | 変更が稀なサービス |
| 86400秒(1日) | ほぼ変更されないレコード |
実践のヒント:DNSマイグレーション前にTTLをまず下げ(例:60秒)、十分な時間が経過してからIPを変更すると、切り替え時のダウンタイムを最小化できます。
DNS over HTTPS (DoH) / DNS over TLS (DoT)
従来のDNSは平文(UDP 53番ポート)で送信されるため、盗聴や改ざんに脆弱です。
| 特性 | 従来のDNS | DoH | DoT |
|---|---|---|---|
| プロトコル | UDP/53 | HTTPS/443 | TLS/853 |
| 暗号化 | なし | TLS | TLS |
| プライバシー | 低い | 高い | 高い |
| ファイアウォール回避 | 簡単にブロック | HTTPSと区別困難 | 専用ポートでブロック可能 |
dig/nslookup 実践コマンド
# Aレコード照会
dig example.com A
# 特定DNSサーバーで照会
dig @8.8.8.8 example.com
# 全クエリプロセスの追跡
dig +trace example.com
# 簡潔な結果のみ出力
dig +short example.com
# MXレコード照会
dig example.com MX
# 逆引きDNS照会
dig -x 8.8.8.8
# nslookupの使用
nslookup example.com
nslookup -type=MX example.com 8.8.8.8
# DNSキャッシュクリア(macOS)
sudo dscacheutil -flushcache
sudo killall -HUP mDNSResponder
5. HTTPの進化:1.0から1.1、2、3まで
HTTP/1.0:リクエストごとに新規接続
初期のHTTPは毎リクエストごとにTCP接続を新たに確立していました。HTMLページ1つに画像が10個あれば、TCP接続を11回確立する必要がありました。
[TCP接続] → [リクエスト] → [レスポンス] → [TCP終了]
[TCP接続] → [リクエスト] → [レスポンス] → [TCP終了]
... 繰り返し
HTTP/1.1:Keep-Aliveとパイプライニング
主な改善点:
- 持続的接続(Keep-Alive):1つのTCP接続で複数のリクエスト/レスポンスを処理
- パイプライニング:レスポンスを待たずに複数リクエストを連続送信(ただしHOLブロッキング問題)
- Hostヘッダー:1つのIPで複数ドメインをホスティング可能(バーチャルホスティング)
- チャンク転送エンコーディング:レスポンスサイズが不明な状態でのストリーミング転送
[TCP接続] → [Req1] → [Res1] → [Req2] → [Res2] → ... → [TCP終了]
HOL(Head-of-Line)ブロッキング問題:最初のレスポンスが遅いと、後続のすべてのリクエストが待機しなければなりません。
HTTP/2:マルチプレキシング革命
単一TCP接続
+----------------------------------+
| Stream 1: GET /index.html |
| Stream 3: GET /style.css | ← 同時処理
| Stream 5: GET /script.js |
| Stream 7: GET /image.png |
+----------------------------------+
コア機能:
-
マルチプレキシング:1つのTCP接続で複数のストリームを同時処理。HTTP/1.1のHOLブロッキングを解決します。
-
ヘッダー圧縮(HPACK):繰り返しヘッダーを静的/動的テーブルで圧縮し、ヘッダーオーバーヘッドを大幅に削減します。
-
サーバープッシュ:サーバーがクライアントのリクエストなしにリソースを事前送信します。
-
バイナリフレーミング:テキストベースではなくバイナリフレームで送信し、パース効率を向上させます。
-
ストリーム優先度:ストリーム間の優先度を設定して、重要なリソースを先に送信します。
HTTP/3:QUIC(UDPベース)
HTTP/3はTCPの代わりにUDPベースのQUICプロトコルを使用します。
HTTP/2スタック HTTP/3スタック
+----------+ +----------+
| HTTP/2 | | HTTP/3 |
+----------+ +----------+
| TLS 1.2+ | | QUIC | ← TLS 1.3内蔵
+----------+ +----------+
| TCP | | UDP |
+----------+ +----------+
| IP | | IP |
+----------+ +----------+
HTTP/3の核心的メリット:
- 0-RTT接続:以前接続したサーバーに対して最初のパケットからデータ送信可能
- HOLブロッキングの完全除去:各ストリームが独立管理されるため、1つのストリーム損失が他のストリームに影響しない
- 接続マイグレーション:ネットワークが変更されても(Wi-Fiからセルラー)接続が維持される
HTTPバージョン比較表
| 特性 | HTTP/1.0 | HTTP/1.1 | HTTP/2 | HTTP/3 |
|---|---|---|---|---|
| トランスポート | TCP | TCP | TCP | QUIC (UDP) |
| 接続方式 | リクエストごと接続 | Keep-Alive | マルチプレキシング | マルチプレキシング |
| HOLブロッキング | TCP + HTTP | TCP + HTTP | TCPレベルのみ | なし |
| ヘッダー圧縮 | なし | なし | HPACK | QPACK |
| サーバープッシュ | なし | なし | サポート | サポート |
| 暗号化 | 任意 | 任意 | 事実上必須 | 必須(TLS 1.3) |
| 接続確立 | 1-RTT (TCP) | 1-RTT (TCP) | 1-RTT (TCP+TLS) | 0-RTT可能 |
いつ何を使うか?
- HTTP/1.1:レガシーシステム、シンプルなAPI
- HTTP/2:ほとんどのWebサイトとAPI(現在のデフォルト)
- HTTP/3:モバイル環境、グローバルサービス、低遅延が重要な場合
6. HTTPSとTLS 1.3
対称暗号 vs 非対称暗号
| 区分 | 対称暗号 | 非対称暗号 |
|---|---|---|
| 鍵 | 同一の鍵で暗号化/復号化 | 公開鍵で暗号化、秘密鍵で復号化 |
| 速度 | 高速 | 低速 |
| アルゴリズム | AES, ChaCha20 | RSA, ECDSA, Ed25519 |
| 用途 | データ暗号化 | 鍵交換、デジタル署名 |
TLSは非対称暗号でセッション鍵を交換した後、対称暗号で実際のデータを暗号化します。
TLS 1.2 vs TLS 1.3 ハンドシェイク
TLS 1.2(2-RTT):
クライアント サーバー
|--- ClientHello ----------------->| RTT 1
|<-- ServerHello, Certificate -----|
|<-- ServerKeyExchange, Done ------|
|--- ClientKeyExchange, Finished ->| RTT 2
|<-- Finished ---------------------|
|===== 暗号化通信開始 =============|
TLS 1.3(1-RTT、0-RTT可能):
クライアント サーバー
|--- ClientHello + KeyShare ------>| RTT 1
|<-- ServerHello + KeyShare -------|
|<-- EncryptedExtensions, Cert ----|
|<-- Finished ---------------------|
|--- Finished -------------------->|
|===== 暗号化通信開始 =============|
TLS 1.3の核心的改善:
| 特性 | TLS 1.2 | TLS 1.3 |
|---|---|---|
| ハンドシェイクRTT | 2-RTT | 1-RTT(0-RTT可能) |
| 鍵交換 | RSAまたはECDHE | ECDHEのみ(前方秘匿性必須) |
| 暗号スイート | 多数のオプション(一部脆弱) | 5つのみ(すべてAEAD) |
| 0-RTT | 非対応 | 対応(再訪問時) |
証明書とCA
証明書チェーン:
+--------------------+
| ルートCA証明書 | ← ブラウザ/OSに内蔵
+--------------------+
| 中間CA | ← ルートCAが署名
+--------------------+
| サーバー証明書 | ← 中間CAが署名
+--------------------+
- Let's Encrypt:無料のDV(ドメイン検証)証明書、90日有効、自動更新(certbot)
- OV/EV証明書:組織検証/拡張検証でより高い信頼レベル
OCSPステープリング
従来のOCSPではブラウザが直接CAに証明書の有効性を確認していましたが、これは遅くプライバシーの問題もありました。OCSPステープリングでは、サーバーがCAから事前に取得したレスポンスをクライアントに渡します。
# Nginx OCSPステープリング設定
server {
ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /path/to/chain.pem;
resolver 8.8.8.8 8.8.4.4 valid=300s;
}
mTLS(相互TLS認証)
通常のTLSではクライアントのみがサーバーを認証します。mTLSではサーバーもクライアントの証明書を確認します。
通常のTLS:
クライアント → サーバー証明書検証(片方向)
mTLS:
クライアント → サーバー証明書検証
サーバー → クライアント証明書検証(双方向)
mTLSの使用事例:
- Kubernetesサービスメッシュ(Istio、Linkerd)でのサービス間通信
- ゼロトラストアーキテクチャでのサービス認証
- APIゲートウェイでのクライアント認証
7. REST vs GraphQL vs gRPC vs WebSocket
REST(Representational State Transfer)
RESTはHTTPメソッド(GET, POST, PUT, DELETE)とリソースURIに基づくアーキテクチャスタイルです。
Richardson成熟度モデル:
| レベル | 説明 | 例 |
|---|---|---|
| Level 0 | 単一URI、単一メソッド | POST /api(RPCスタイル) |
| Level 1 | リソースごとのURI | /users, /orders |
| Level 2 | HTTPメソッドの活用 | GET /users, POST /users |
| Level 3 | HATEOAS(ハイパーメディア) | レスポンスに関連リンクを含む |
HATEOASの例:
{
"id": 1,
"name": "John",
"links": [
{ "rel": "self", "href": "/users/1" },
{ "rel": "orders", "href": "/users/1/orders" },
{ "rel": "update", "href": "/users/1", "method": "PUT" }
]
}
GraphQL
GraphQLはクライアントが必要なデータだけを正確にリクエストできるクエリ言語です。
# クライアントが必要なフィールドのみリクエスト
query {
user(id: 1) {
name
email
orders(last: 5) {
id
total
items {
name
price
}
}
}
}
メリット:
- オーバーフェッチング/アンダーフェッチングの解決
- 単一エンドポイント
- 強力な型システム
デメリット:
- N+1問題(DataLoaderで解決)
- キャッシングが難しい(URLベースのキャッシュ不可)
- 複雑なクエリによるサーバー負荷
gRPC
gRPCはGoogleが開発したHTTP/2ベースの高性能RPCフレームワークです。Protocol Buffersを使用してバイナリシリアライゼーションを行います。
// user.proto
syntax = "proto3";
service UserService {
rpc GetUser (GetUserRequest) returns (User);
rpc ListUsers (ListUsersRequest) returns (stream User);
rpc CreateUsers (stream CreateUserRequest) returns (CreateUsersResponse);
rpc Chat (stream ChatMessage) returns (stream ChatMessage);
}
message GetUserRequest {
int32 id = 1;
}
message User {
int32 id = 1;
string name = 2;
string email = 3;
}
gRPCの4つの通信パターン:
| パターン | 説明 | 使用事例 |
|---|---|---|
| Unary | 1リクエスト → 1レスポンス | 一般的なAPI呼び出し |
| Server Streaming | 1リクエスト → Nレスポンス | 大量データ取得 |
| Client Streaming | Nリクエスト → 1レスポンス | ファイルアップロード |
| Bidirectional Streaming | Nリクエスト ↔ Nレスポンス | チャット、リアルタイムゲーム |
WebSocket
WebSocketはHTTPアップグレードを通じて全二重双方向通信を提供します。
HTTPアップグレード:
GET /chat HTTP/1.1
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
→ 以降、双方向フレームベース通信
使用事例:
- リアルタイムチャット
- 株式/暗号資産リアルタイム相場
- オンラインゲーム
- コラボレーションツール(Google Docsなど)
SSE(Server-Sent Events)
SSEはサーバーからクライアントへの単方向リアルタイムストリーミングです。WebSocketよりシンプルで、HTTP上で動作します。
// サーバー(Node.js)
res.writeHead(200, {
'Content-Type': 'text/event-stream',
'Cache-Control': 'no-cache',
Connection: 'keep-alive',
})
setInterval(() => {
res.write('data: ' + JSON.stringify(data) + '\n\n')
}, 1000)
// クライアント
const eventSource = new EventSource('/events')
eventSource.onmessage = (event) => {
console.log(JSON.parse(event.data))
}
通信方式比較表
| 特性 | REST | GraphQL | gRPC | WebSocket | SSE |
|---|---|---|---|---|---|
| プロトコル | HTTP/1.1+ | HTTP/1.1+ | HTTP/2 | TCP(HTTPアップグレード) | HTTP/1.1+ |
| データ形式 | JSON/XML | JSON | Protobuf(バイナリ) | 自由形式 | テキスト |
| 方向 | リクエスト-レスポンス | リクエスト-レスポンス | 双方向ストリーミング | 双方向 | サーバー→クライアント |
| パフォーマンス | 普通 | 普通 | 高い | 高い | 普通 |
| ブラウザ対応 | 完全 | 完全 | 限定的(gRPC-Web) | 完全 | 完全 |
| 使用時期 | 公開API、CRUD | 複雑なデータ関係 | 内部マイクロサービス | 双方向リアルタイム | 単方向通知 |
8. CDNとロードバランシング
CDNの動作原理
CDN(Content Delivery Network)は世界中に分散されたエッジサーバーにコンテンツをキャッシュし、ユーザーに最も近いサーバーからコンテンツを提供します。
ユーザー(東京) → エッジサーバー(東京) → [キャッシュヒット] → 即座に応答
[キャッシュミス] → オリジンサーバー(米国) → キャッシュ保存 → 応答
コア技術:
- Anycast:同一IPを複数のエッジサーバーが共有し、BGPルーティングで最も近いサーバーにルーティング
- エッジキャッシング:Cache-Controlヘッダーに基づいてコンテンツをキャッシュ
- Cache-Controlヘッダー:
public, max-age=31536000, immutable(1年キャッシュ、不変コンテンツ)
Cache-Controlの主要ディレクティブ:
| ディレクティブ | 説明 |
|---|---|
public | CDNおよび中間プロキシでキャッシュ可能 |
private | ブラウザのみでキャッシュ |
no-cache | キャッシュするが毎回サーバーに有効性検証 |
no-store | いかなるキャッシュも保存しない |
max-age=N | N秒間キャッシュ有効 |
s-maxage=N | CDN/プロキシでN秒間キャッシュ有効 |
immutable | キャッシュ期間内は再検証しない |
CDN比較
| 特性 | Cloudflare | AWS CloudFront | Fastly | Akamai |
|---|---|---|---|---|
| PoP数 | 310+ | 600+ | 100+ | 4,000+ |
| 無料プラン | あり | なし | なし | なし |
| DDoS保護 | 標準搭載 | AWS Shield | 標準 | 標準 |
| エッジコンピューティング | Workers | Lambda@Edge | Compute@Edge | EdgeWorkers |
| リアルタイムパージ | 即時 | 数秒 | 150ms | 5秒 |
| 強み | コスパ、セキュリティ | AWSエコシステム | リアルタイムパージ | エンタープライズ |
ロードバランサー:L4 vs L7
| 特性 | L4(トランスポート) | L7(アプリケーション) |
|---|---|---|
| 動作レイヤー | TCP/UDP | HTTP/HTTPS |
| ルーティング基準 | IP、ポート | URL、ヘッダー、クッキー |
| SSL終端 | 不可(パススルー) | 可能 |
| パフォーマンス | より高速 | より柔軟 |
| WebSocket | サポート | サポート |
| 例 | AWS NLB, Nginx (stream) | AWS ALB, Nginx (http) |
ロードバランシングアルゴリズム
| アルゴリズム | 説明 | 適切な場合 |
|---|---|---|
| ラウンドロビン | 順番に分配 | サーバー性能が同一の場合 |
| 加重ラウンドロビン | 重みに応じて分配 | サーバー性能が異なる場合 |
| 最少接続 | 接続数が最も少ないサーバーへ | リクエスト処理時間が多様な場合 |
| IPハッシュ | クライアントIPベースの固定サーバー | セッション維持が必要な場合 |
| コンシステントハッシング | ハッシュリングベースの分配 | サーバー追加/削除時の再分配最小化 |
コンシステントハッシングの利点:
ハッシュリング:
0 --- Server A --- Server B --- Server C --- 2^32
^ ^ ^
Key1, Key4 Key2, Key5 Key3, Key6
Server D追加時:
0 --- Server A -- Server D -- Server B --- Server C --- 2^32
^ ^ ^ ^
Key1, Key4 Key2 Key5 Key3, Key6
→ Server DとServer Bの間のキーのみ再分配(全体ではない)
主要ロードバランサー製品
# Nginx L7ロードバランサー設定例
upstream backend {
least_conn;
server backend1.example.com:8080 weight=3;
server backend2.example.com:8080 weight=2;
server backend3.example.com:8080 weight=1;
server backend4.example.com:8080 backup;
}
server {
listen 443 ssl;
location / {
proxy_pass http://backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
9. 実践デバッグツール
curl — HTTPリクエストの万能ツール
# 基本GETリクエスト
curl https://api.example.com/users
# 詳細情報出力(TLSハンドシェイク含む)
curl -v https://api.example.com/users
# POSTリクエスト(JSON)
curl -X POST https://api.example.com/users \
-H "Content-Type: application/json" \
-d '{"name": "John", "email": "john@example.com"}'
# レスポンス時間分析(必須!)
curl -w "\n
DNS参照: %{time_namelookup}s\n
TCP接続: %{time_connect}s\n
TLSハンドシェイク: %{time_appconnect}s\n
最初のバイト: %{time_starttransfer}s\n
合計時間: %{time_total}s\n" \
-o /dev/null -s https://api.example.com/users
# HTTP/2でリクエスト
curl --http2 https://api.example.com/users
# ヘッダーのみ出力
curl -I https://api.example.com/users
tcpdump — パケットキャプチャ
# 特定ポートのTCPパケットキャプチャ
sudo tcpdump -i eth0 port 80 -n
# 特定ホストとの通信キャプチャ
sudo tcpdump host 192.168.1.100
# パケットをファイルに保存(Wiresharkで分析)
sudo tcpdump -i eth0 -w capture.pcap port 443
# SYNパケットのみキャプチャ(接続開始追跡)
sudo tcpdump 'tcp[tcpflags] & (tcp-syn) != 0'
# HTTPリクエストのみキャプチャ
sudo tcpdump -A 'tcp port 80 and (((ip[2:2] - ((ip[0]&0xf)<<2)) - ((tcp[12]&0xf0)>>2)) != 0)'
netstat / ss / lsof — 接続状態確認
# 開いているポート確認(ssはnetstatより高速)
ss -tulnp
# 特定ポート使用プロセス確認
ss -tulnp | grep :8080
lsof -i :8080
# TIME_WAIT状態の接続数確認
ss -s
ss -tan state time-wait | wc -l
# ESTABLISHED接続一覧
ss -tan state established
traceroute / mtr — 経路追跡
# 基本経路追跡
traceroute example.com
# TCPベースのtraceroute(ICMPがブロックされている場合)
traceroute -T -p 443 example.com
# mtr(traceroute + ping統合、リアルタイム監視)
mtr example.com
# 特定回数のみ実行
mtr -c 10 --report example.com
Chrome DevTools Networkタブの活用
主な分析ポイント:
- ウォーターフォールチャート:各リクエストのDNS、TCP、TLS、TTFB(Time To First Byte)時間を確認
- Size vs Transferred:圧縮効果を確認(gzip, br)
- Initiator:どのリソースが該当リクエストをトリガーしたか
- Timingタブ:Queued、Stalled、DNS、Initial Connection、SSL、TTFB、Content Downloadの詳細分解
- スロットリング:Slow 3G、Fast 3Gなどで遅いネットワークをシミュレーション
10. 面接予想質問15選
基本概念
Q1.「ブラウザにURLを入力すると何が起こるか説明してください。」
- URLパーシング(プロトコル、ドメイン、パス)
- DNS参照(ブラウザキャッシュ → OSキャッシュ → リゾルバ → ルート → TLD → 権威サーバー)
- TCP 3ウェイハンドシェイク
- TLSハンドシェイク(HTTPSの場合)
- HTTPリクエスト送信
- サーバー処理およびHTTPレスポンス
- ブラウザレンダリング(HTMLパーシング、DOM構築、CSSOM、レイアウト、ペイント)
Q2.「TCPとUDPの違いを説明し、それぞれいつ使うか教えてください。」
TCPは信頼性のある接続指向プロトコルで、データの順序保証と再送を提供します。Web、メール、ファイル転送に使用します。UDPはコネクションレスで高速ですが信頼性がありません。DNS、リアルタイムストリーミング、ゲームに使用します。
Q3.「HTTP/2とHTTP/3の主な違いは?」
HTTP/2はTCP上でマルチプレキシングをサポートしますが、TCPレベルのHOLブロッキングが残っています。HTTP/3はUDPベースのQUICを使用してHOLブロッキングを完全に除去し、0-RTT接続と接続マイグレーションをサポートします。
応用質問
Q4.「TCP 3ウェイハンドシェイクをSYN Flood攻撃と関連づけて説明してください。」
SYN Floodは大量のSYNパケットを送信してサーバーのハーフオープン接続テーブルを埋め尽くすDoS攻撃です。防御方法としてSYN Cookies、SYN Proxy、レートリミッティングがあります。
Q5.「CORSとは何で、なぜ必要ですか?」
Cross-Origin Resource Sharingはブラウザの同一オリジンポリシー(Same-Origin Policy)を安全に緩和するメカニズムです。サーバーがAccess-Control-Allow-Originヘッダーで許可するオリジンを明示します。
Q6.「DNSのTTL値が低いとどのようなメリット・デメリットがありますか?」
メリット:DNS変更時の高速伝播、障害復旧時の迅速な切り替え。デメリット:DNSサーバー負荷増加、クエリ頻度増加による遅延。
Q7.「TLS 1.3がTLS 1.2より速い理由は?」
TLS 1.3はハンドシェイクを1-RTTに短縮し(1.2は2-RTT)、0-RTT再開をサポートします。また、脆弱な暗号スイートを削除し、鍵交換を簡素化しました。
Q8.「REST APIにおける冪等性(Idempotency)とは?」
同一のリクエストを複数回実行しても結果が同じことです。GET、PUT、DELETEは冪等的で、POSTはそうではありません。決済APIでは重複リクエストを防止するためにIdempotency Keyを使用します。
設計/実務質問
Q9.「WebSocketとSSEを比較し、それぞれいつ使うか教えてください。」
WebSocketは双方向、SSEはサーバーからクライアントへの単方向です。チャットやゲームはWebSocket、通知やリアルタイムフィードはSSEが適しています。
Q10.「CDNを使用するとどのようなメリットがありますか?」
遅延時間の短縮(地理的近接性)、オリジンサーバー負荷軽減、DDoS防御、グローバル可用性向上、帯域幅コスト削減。
Q11.「L4 vs L7ロードバランサーの違いは?」
L4はTCP/UDPレベルでIPとポートに基づいてルーティングし、高速ですが制限的です。L7はHTTPヘッダー、URL、クッキーに基づいてルーティングし、より柔軟ですがオーバーヘッドがあります。
Q12.「マイクロサービス間通信にgRPCを使うとどのようなメリットがありますか?」
HTTP/2ベースのマルチプレキシング、Protobufバイナリシリアライゼーションによる高性能、強力な型システム、双方向ストリーミング、多言語対応、Kubernetes環境でのサービスメッシュとの良好な統合。
Q13.「コンシステントハッシングとは何で、なぜ使いますか?」
サーバーの追加/削除時に全体のキーを再分配するのではなく、ハッシュリング上で隣接するキーだけを移動させる技法です。分散キャッシュ(Memcached、Redis Cluster)やロードバランサーで使用します。
Q14.「NATが必要な理由と動作方式を説明してください。」
IPv4アドレスの枯渇によりプライベートIPを使用し、NATを通じてパブリックIPに変換します。送信元/送信先のIPとポートを変換し、プライベートネットワークのセキュリティも高めます。
Q15.「HTTP Keep-AliveとWebSocketの違いは?」
Keep-AliveはTCP接続を維持しますが、依然としてリクエスト-レスポンスモデルです。WebSocketはプロトコルアップグレード後に全二重双方向通信が可能になります。
11. クイズ
これまで学んだ内容を確認しましょう。
Q1. TCP 3ウェイハンドシェイクの3段階を順番に答えてください。
正解:SYN → SYN-ACK → ACK
- クライアントがSYNパケットをサーバーに送信(シーケンス番号を含む)
- サーバーがSYN-ACKパケットで応答(自身のシーケンス番号 + クライアントのシーケンス番号の確認)
- クライアントがACKパケットを送信し、接続確立完了
このプロセスで双方がシーケンス番号を交換し、以降のデータ順序を追跡できるようになります。
Q2. HTTP/2のマルチプレキシングが解決するHTTP/1.1の問題は何ですか?
正解:HOL(Head-of-Line)ブロッキング
HTTP/1.1では1つの接続でリクエストが順番に処理されるため、最初のレスポンスが遅いと後続のすべてのリクエストが待機しなければなりません。HTTP/2は1つのTCP接続で複数のストリームを同時処理(マルチプレキシング)してこの問題を解決します。ただし、TCPレベルのHOLブロッキングは依然として存在し、HTTP/3(QUIC)で完全に解決されます。
Q3. DNSレコードのCNAMEとAレコードの違いは何ですか?
正解:
- Aレコード:ドメインをIPv4アドレスに直接マッピングします。(例:example.com → 93.184.216.34)
- CNAMEレコード:ドメインを別のドメインにマッピングするエイリアスです。(例:www.example.com → example.com)
CNAMEはチェーニングが可能ですが、ルートドメイン(Zone Apex)には使用できません。AWS Route 53のALIASレコードやCloudflareのCNAMEフラットニングでこの制限を回避できます。
Q4. TLS 1.3で0-RTTが可能な原理を簡単に説明してください。
正解:
以前のTLSセッションで交換したPSK(Pre-Shared Key)をベースに、再訪問時にClientHelloと一緒に最初のパケットに暗号化されたデータを含めることができます。サーバーは保存されたPSKで即座に復号化し、ハンドシェイク完了前にデータを処理します。ただし、0-RTTデータはリプレイ攻撃に脆弱なため、冪等なリクエストにのみ使用すべきです。
Q5. コンシステントハッシングでサーバーが追加された時、なぜ全キーの再分配が発生しないのですか?
正解:
コンシステントハッシングはハッシュリング構造を使用します。各サーバーとキーがハッシュリング上の特定の位置にマッピングされ、各キーは時計回りで最も近いサーバーに割り当てられます。サーバーが追加されると、そのサーバーと前のサーバーの間にあるキーだけが新しいサーバーに移動します。全キーのうちK/N個(K:全キー数、N:サーバー数)のみが再分配されるため、影響が最小化されます。仮想ノード(Virtual Node)を使用すると、負荷分散をさらに均等にできます。
12. 参考資料
公式ドキュメントおよびRFC
- RFC 793 - Transmission Control Protocol
- RFC 768 - User Datagram Protocol
- RFC 9000 - QUIC: A UDP-Based Multiplexed and Secure Transport
- RFC 9114 - HTTP/3
- RFC 8446 - TLS 1.3
- RFC 7540 - HTTP/2
- RFC 1035 - Domain Names - Implementation and Specification
書籍
- Computer Networking: A Top-Down Approach (Kurose, Ross) - ネットワーク基礎の教科書
- TCP/IP Illustrated, Volume 1 (W. Richard Stevens) - TCP/IPバイブル
- High Performance Browser Networking (Ilya Grigorik) - 無料オンライン書籍、Web性能最適化
オンライン資料
- MDN Web Docs - HTTP - HTTPガイド
- Cloudflare Learning Center - ネットワーク概念のビジュアル解説
- Julia Evans - Networking Zines - ネットワーキング概念を漫画でわかりやすく解説
- gRPC Official Documentation - gRPC公式ドキュメント
- Beej's Guide to Network Programming - ネットワークプログラミングガイド
- DNS 101 - How DNS Works - DNS動作原理のビジュアライゼーション
- Wireshark User's Guide - Wireshark使用ガイド
ネットワークは開発者の基本素養です。この記事で扱った内容を一度にすべて覚える必要はありません。実務でAPIパフォーマンスの問題をデバッグしたり、システム設計を議論したり、面接を準備する際にこの記事を見返してください。各プロトコルの「なぜ」を理解すれば、新しい技術が登場しても素早く適応できます。