mnagaaのメモ

技術的なことはこのブログで書きます

通信方式 ~vol.3~ (HTTP1.1)

これまでに、WebSocket, Socketなどについて整理してきたので、今回はHTTP(/1.1)について整理する。バージョン2以降は次の記事にします。

mnagaa.hatenablog.com

HTTP

  • HTTP(HyperText Transfer Protocol)は、ウェブ上でデータをやり取りするためのプロトコルです。主にクライアント(例えばウェブブラウザ)とサーバー間で、リクエストとレスポンスのやり取りをする際に使用されます。

基本的な特徴

  • リクエスト-レスポンスモデル:
    • クライアントがサーバーにリクエストを送信し、サーバーがそのリクエストに対するレスポンスを返す。
    • 例えば、ウェブページを閲覧する際にブラウザがサーバーにページのリクエストを送り、サーバーがHTMLやCSSJavaScriptなどのデータを返す仕組み。
sequenceDiagram
    participant Client as クライアント
    participant Server as サーバー
    
    Client->>Server: HTTPリクエスト
    Server-->>Client: HTTPレスポンス
    Client->>Server: 次のHTTPリクエスト
    Server-->>Client: HTTPレスポンス
  • ステートレス(Stateless):

    • HTTPはステートレスなプロトコルである。各リクエストは独立しており、以前のリクエストやレスポンスの情報を個別のサーバー(自体)は保持しない。
    • セッション管理などは、クッキーやトークンなどの別の手段で行われる。←memcacheや永続化用のDBなどはサーバーとは分離される
  • HTTPメソッド: HTTPリクエストにはいくつかのメソッドがあり、目的に応じて選択される。

    • GET: サーバーからリソースを取得する。
    • POST: サーバーにデータを送信し、処理を依頼する。
    • PUT: サーバー上の既存のリソースを更新する。
    • DELETE: サーバー上のリソースを削除する。
    • PATCH: リソースの一部を更新する。
    • HEAD: GETと同様のリクエストを行いますが、ボディ部分は返されません。
  • HTTPステータスコード: サーバーからのレスポンスはステータスコードで示される。代表的なステータスコードとしては以下のようなコードがある。

    • 200 OK: リクエストが成功した。
    • 404 Not Found: リクエストされたリソースが見つからない。
    • 500 Internal Server Error: サーバーでエラーが発生した。
    • 301 Moved Permanently: リソースが恒久的に別の場所に移動した。
  • HTTPヘッダー: リクエストやレスポンスには、メタデータを含むヘッダーが付加される。ヘッダーを使って、データの形式やキャッシュの設定、認証情報などを指定する。

    • 例: Content-Type, Authorization, Cache-Control など。
  • HTTPS: HTTPにSSL/TLSを組み合わせたものがHTTPS(HTTP Secure)です。これにより、通信内容が暗号化され、セキュアなやり取りが可能になる。

ステートレスについて深ぼる

まずは、HTTPはステートレスなプロトコルであるが、サーバーにデータを保存せずに、ステートフルなアプリケーションを実現するときの方法を説明する。

1. クッキー

クッキーは、サーバーがクライアントにセッションIDなどを保存させ、次のリクエストの際に、そのデータを自動的に送信する仕組み。サーバーは特定のクライアントに対してセッションを維持し、ログイン状態などを追跡できる。

  • クライアント側が保持: クッキーは、サーバーからクライアント(ブラウザなど)に送信され、クライアントのデバイスに保存される。クライアントはそのクッキーを次回以降のリクエストに含めてサーバーに送信する。
  • 保存場所: クライアントのブラウザ内に保存される。
  • 使用目的: セッションID、ユーザーの認証情報、トラッキング情報、ユーザーの設定(例: 言語やテーマの選択)などを保存して、次回アクセス時に再利用される。
  • 有効期限: クッキーには有効期限が設定でき、一時的なもの(セッションクッキー)や長期間保存されるもの(永続的なクッキー)がある。

2. セッション

セッションは、サーバー側でクライアントごとの状態を保持する仕組み。セッションIDがクライアントに発行され、サーバー側にそのセッションIDに紐づく情報が保存される。 クライアントはクッキーやリクエストヘッダーでセッションIDを送信して、それに基づいてサーバーが状態を管理する。

一般的に、セッション管理は短期間でログイン情報やショッピングカートの内容などが保存される。

  • サーバー側が保持: セッションは、クライアントの状態(例えば、ログイン状態やショッピングカートの情報など)をサーバー側に保存する。クライアントがサーバーにリクエストを送るとき、セッションIDを使ってサーバーは対応するセッションデータにアクセスする。
  • 保存場所: サーバーのメモリやデータベース(時にはRedisやMemcachedなど)に保存される。
  • 使用目的: ユーザーごとの状態管理(例: ログイン情報、セッションの一貫性維持、トランザクションデータの管理など)に利用される。
  • 有効期限: セッションは通常、短期間有効で、ユーザーがアクションを行わない場合は一定時間後に無効化される(タイムアウト)。

3. WebSocket

HTTPではなくて、WebSocketを使用することで双方向通信が可能になり、サーバーとクライアント間でリアルタイムに情報を保持することができる。 WebSocketはコネクションが確立されている間は継続的にデータをやり取りできるため、ステートフルな通信を実現できる。

ステートフルって?

サーバーが以前のリクエストの情報やセッションデータを保存することを広義で「ステートフル」と呼ぶ。

項目 ステートフルなサーバー ステートレスなサーバー
定義 サーバーがクライアントとの状態(セッション、認証情報、トランザクション)を保持し、クライアントごとの状態を管理する方式 各リクエストを独立したものとして扱い、クライアントの状態をサーバーに保持せずに処理する方式
セッションの保存場所 サーバーのメモリやローカルストレージにセッション情報が保存される セッション情報は外部システム(例: Redis, Memcached)やクライアント側に保存され、サーバー自体は状態を保持しない
負荷分散の柔軟性 クライアントは特定のサーバーに接続し続ける必要があるため、負荷分散が難しい サーバーがクライアントの状態を保持しないため、リクエストを任意のサーバーに振り分けやすく、スケーラビリティが向上する
スケーラビリティ セッションがサーバーに依存するため、スケールアウト(サーバーの増加)に制限がある ステートレスな設計のため、サーバーを簡単に追加・削除でき、大規模なスケールアウトが可能
障害時の影響 サーバーがダウンすると、そのサーバーに依存していたクライアントのセッションが失われる可能性がある サーバーに依存しないため、特定のサーバーがダウンしても影響は少なく、外部のセッションストレージによりフェイルオーバーが容易
実装の複雑さ 状態をサーバー側で管理するため、実装は比較的シンプルだが、負荷や障害管理が難しくなる 外部システムとの連携が必要であり、初期実装は複雑になることもあるが、長期的には管理が容易で、特に大規模システムに適している
用途の例 トラディショナルなWebアプリケーション、単一サーバーでのアプリケーション運用 マイクロサービスアーキテクチャクラウドベースのシステム、スケーラブルなAPIサービス
Sticky Session 特定のサーバーにクライアントを固定するSticky Sessionを必要とする場合が多い Sticky Sessionが不要。ロードバランサーを使用してリクエストを均等に振り分けられる
データの保持 状態をサーバーに保持し続けるため、メモリやストレージに依存することがある データの保持は外部ストレージに依存し、各リクエストが必要なデータを持ってくるか、外部データベースで参照する

ロードバランサーについて軽く触れる

ロードバランサーとサーバーのステートフル・ステートレスの設計は非常に密接であるため軽く説明する。

ロードバランサーの役割

ロードバランサーは、複数のサーバー(バックエンドサーバー群)に対して、トラフィックを分散させ、システム全体の負荷を平準化する役割を果たす。これにより、あるサーバーが故障しても他のサーバーでリクエストを処理できるため、システムのダウンタイムを最小限に抑えられる。つまり可用性を向上させることができる。

トラフィック量が増加した際には、追加のサーバーをバックエンドに追加して、ロードバランサーがそれらにリクエストを振り分けることで負荷を分散させることができる。

Sticky Sessionについて

ロードバランサーの機能として、Sticky Sessionというものがある。

  • Sticky Sessionは、クライアントが最初にアクセスしたサーバーに対して、以降のリクエストも一貫して送信されるように制御する。これにより、サーバー側でのセッション情報が維持され、ステートフルな動作が可能になります。
  • ロードバランサーは、クライアントのセッション情報を確認し、同じサーバーにリクエストをルーティングすることで、サーバー内の状態を利用して処理が続行されます。

Sticky Sessionの課題

  • スケーラビリティの制限:特定のサーバーにリクエストが集中するようになるため、負荷が均等に分散されず、スケーラビリティが制限される。サーバーが1台ダウンすると、そのサーバーに保存されていたクライアントのセッション情報が失われる可能性がある。
特徴 Sticky Session(ステートフル) ステートレス
セッション管理 各サーバーがセッションを保持 外部ストレージやトークンでセッション管理
ロードバランシング 同じサーバーにリクエストを送る必要がある リクエストは任意のサーバーに送信可能
スケーラビリティ スケールアウトが困難 容易にスケールアウト可能
サーバー障害時の影響 特定サーバーに依存 影響は少ない
実装の複雑さ シンプルだがサーバー間での負荷が偏る可能性あり 外部ストレージやJWTの実装が必要

HTTP以外の代表的な通信方式

通信方式 特徴 用途
WebSocket 双方向リアルタイム通信が可能。接続後、持続的なデータのやり取りが可能。 チャット、リアルタイム通知、オンラインゲーム
FTP ファイル転送プロトコルTCPを使用してファイルをサーバー間で転送。 ファイルのアップロード/ダウンロード
SMTP メール送信の標準プロトコル メール送信(GmailOutlookなど)
IMAP/POP3 IMAPはサーバー上のメール管理、POP3はメールをダウンロードしてローカル管理。 メールの受信と管理
UDP 軽量で高速だが、信頼性が低い。順序やエラー制御なし。 ストリーミング、オンラインゲーム、VoIP
gRPC HTTP/2ベースの高速通信。プロトコルバッファを使った効率的なデータシリアライズ マイクロサービス間の通信、分散システム
MQTT 軽量なメッセージングプロトコル。低帯域で信頼性のある通信が可能。 IoTデバイス間のデータ送受信
SSH 暗号化されたセキュアな通信。リモートアクセスやファイル転送に使用。 サーバー管理、リモートアクセス、SFTPによる転送
QUIC UDPベースのプロトコル。高速で信頼性のある接続を提供。 HTTP/3、リアルタイム通信、ストリーミング
SNMP ネットワークデバイスの監視・管理プロトコル ネットワーク管理、デバイス監視

最後に

次のブログでは、HTTP/2とHTTP/3について説明しよう