HTTPプロトコルの進化:1.0から2.0まで
HTTP(HyperText Transfer Protocol)は、インターネット上で最も広く使用されるネットワークプロトコルであり、すべてのWWWファイルはこの基準に従う必要があります。その元々の設計目標は、HTMLページの公開と受信の方法を提供することであり、WWWサーバからローカルブラウザにハイパーテキストを転送するために使用され、デフォルトではポート80を使用します。HTTPクライアントが要求を発行すると、サーバの指定されたポート(デフォルトではポート80)にTCP接続を確立します。
注目すべきは、HTTPプロトコルはTCPプロトコルと衝突しないことです。HTTPは7層プロトコルのアプリケーション層にあり、一方、TCPはトランスポート層の論理的な問題を解決する役割を担っています。HTTPがUDPではなくTCPを選択するのは、ウェブページを開く際に大量のデータを送信する必要があり、TCPプロトコルが送信制御を提供して、データの順序立てた組織とエラー訂正を実現できるからです。また、HTTPプロトコルのボトルネックと最適化技術もTCPプロトコルの特性に基づいています。例えば、TCP接続を確立する際の3-way handshakeにより、1.5RTT(往復時間)の遅延が発生します。各要求のハンドシェイク遅延を避けるために、アプリケーション層では異なる戦略のHTTP持続接続スキームを採用します。そして、TCPが接続の初期段階でスロースタートの特性を持つため、接続再利用のパフォーマンスは通常、新しい接続よりも優れています。
HTTP接続は「要求-応答」モードを採用しています。要求を行う際には、まず接続を確立する必要があるだけでなく、サーバはクライアントがサーバに要求を送信した後にのみデータを返答することができます。インターネットの発展に伴い、HTTPプロトコルも継続的にアップグレードされ、HTTP/1.0、HTTP/1.1、HTTP/2.0などのバージョンが次々と登場し、各バージョンはパフォーマンスと機能面で最適化と改善が行われています。
HTTP/1.0
HTTP/1.0は、通信においてバージョン番号を指定する最初のHTTPプロトコルのバージョンであり、現在でもプロキシサーバなどのシナリオで広く使用されています。このバージョンでは、ブラウザとサーバが短期間の接続のみを維持することが定められています。ブラウザは各要求ごとにサーバとのTCP接続を確立する必要があり、サーバは要求処理を完了した後すぐにTCP接続を切断します。これは、各クライアントを追跡したり、過去の要求を記録したりしません。
このメカニズムにより、いくつかのパフォーマンスの欠点が生じます。大量の画像を含むウェブページを例にとると、ウェブページファイル自体には画像データは含まれず、画像のURLアドレスのみが指定されています。ブラウザがこのウェブページにアクセスすると、まずウェブページファイルの要求を送信します。HTMLコンテンツを解析する際に、画像タグを見つけた場合、src属性に指定されたURLに基づいてサーバに再度要求を送信して画像データをダウンロードします。これは、多数の画像を含むウェブページにアクセスするためには、複数の要求と応答が必要であり、各回、個別の接続を確立して単一の文書または画像を送信することを意味します。画像ファイルが小さくても、頻繁に接続を確立および切断するプロセスは時間がかかり、クライアントとサーバの両方のパフォーマンスに深刻な影響を与えます。同様に、ウェブページにJavaScriptファイルやCSSファイルなどのコンテンツが含まれる場合も、同様の問題が発生します。
同時に、帯域幅とレイテンシもネットワーク要求に影響を与える重要な要素です。現在のネットワークインフラにおける帯域幅の大幅な改善に伴い、応答速度のレイテンシ問題がより顕著になっています。HTTP/1.0の最も批判される2つの問題は、接続再利用ができないことと、先頭ブロッキングです。
この2つの問題を理解するには、クライアントがドメイン名に基づいてサーバに接続を確立することを明確にすべきです。一般的に、PCのブラウザは単一のドメイン名のサーバに同時に6-8の接続を確立し、一方、モバイルブラウザは4-6に制御します。接続の数は多いほど良いわけではありません。なぜなら、多すぎるとリソースのオーバーヘッドと全体的なレイテンシが増加するからです。接続再利用ができないことにより、各要求において3-way handshakeとスロースタートが必要になります。3-way handshakeは、高レイテンシのシナリオにおいて大きな影響を与え、スロースタートは大きなファイルの要求に対してより大きな影響を与えます。先頭ブロッキングにより、帯域幅を完全に活用することができず、後続の正常な要求がブロックされます。
先頭ブロッキングにより、正常な要求が異常な要求の影響を受けることになり、この損失はネットワーク環境によって影響を受け、ランダムで監視しにくいものです。先頭ブロッキングによるレイテンシを解決するために、プロトコルの設計者はパイプライン機構を導入しましたが、この機構はHTTP/1.1にのみ適用され、厳格な使用条件があり、多くのブラウザベンダーがサポートしていません。
HTTP/1.0では、要求ヘッダは比較的シンプルです。例えば、ウェブページリソースを取得する際:
GET /index.html HTTP/1.0
User - Agent: Mozilla/5.0
HTTP/1.1
HTTP/1.0の欠点を克服するために、HTTP/1.1は持続接続をサポートしています(デフォルトモードはパイプライン付きの持続接続です)。複数のHTTP要求と応答を単一のTCP接続上で送信することができ、接続の確立と切断にかかるコストとレイテンシを低減します。大量の画像を含むウェブページを例にとると、複数の要求と応答を1つの接続で送信することができますが、各個別のウェブページファイルの要求と応答には依然として独自の接続を使用する必要があります。また、HTTP/1.1では、クライアントが前の要求の結果が返されるのを待たずに次の要求を送信でき、サーバは要求を受け取った順序で応答結果を返す必要があり、これによりクライアントが各要求の応答コンテンツを区別できるようになり、全体のダウンロードプロセスにかかる時間が大幅に短縮されます。
HTTP/1.1では、connection
ヘッダが要求と応答ヘッダに表示されることがあり、これはクライアントとサーバが持続接続をどのように処理するかを示すために使用されます。デフォルトでは、クライアントとサーバは相手が持続接続をサポートしていると想定しています。クライアントがHTTP/1.1プロトコルを使用しているが、持続接続を使用したくない場合、ヘッダにconnection
の値をclose
と指定する必要があります。サーバが持続接続をサポートしたくない場合、応答においてもconnection
の値を明確にclose
と設定する必要があります。要求または応答のヘッダにclose
の値が含まれている場合、現在のTCP接続が要求処理が完了した後に切断され、クライアントからの後続の新しい要求は新しいTCP接続を作成する必要があります。例えば:
# 要求ヘッダ
GET /index.html HTTP/1.1
User - Agent: Mozilla/5.0
Connection: close
# 応答ヘッダ
HTTP/1.1 200 OK
Content - Type: text/html
Connection: close
また、HTTP/1.1は、より多くの要求ヘッダと応答ヘッダを追加することで、HTTP/1.0の機能を改善および拡張しました:
- Hostヘッダのサポート:HTTP/1.0はHost要求ヘッダフィールドをサポートしておらず、ブラウザはホストヘッダ名を通じてサーバ上の特定のWEBサイトにアクセスすることができず、同じIPアドレスとポート番号に複数の仮想WEBサイトを設定することが制限されていました。HTTP/1.1がHost要求ヘッダフィールドを追加した後、ブラウザはホストヘッダ名を通じてアクセスするサイトを明確に指定できるようになり、同じIPアドレスとポート番号に異なるホスト名を持つ複数の仮想WEBサイトの作成が可能になりました。例えば:
GET /index.html HTTP/1.1
Host: example.com
-
持続接続の制御:HTTP/1.1の持続接続は、新しい要求ヘッダを通じて実装されます。
Connection
要求ヘッダの値がKeep - Alive
の場合、クライアントはサーバに対して、この要求の結果を返した後も接続を維持するよう通知します。値がclose
の場合、結果を返した後に接続を切断するようサーバに通知します。 -
キャッシュと中断したダウンロードの再開:HTTP/1.0は、ファイルの中断したダウンロードの再開をサポートしておらず、各ファイルの転送は0バイト位置から始まります。HTTP/1.1は新しい
RANGE:bytes
フィールドを追加し、RANGE:bytes=XXXX
はサーバに対して、ファイルのXXXXバイト位置から転送を開始するよう要求することを意味し、中断したダウンロードの再開が可能になります。例えば:
GET /largefile.zip HTTP/1.1
Range: bytes=1000 -
また、HTTP/1.1はキャッシュ処理、帯域幅最適化、エラー通知管理などの面でも改善されています:
-
キャッシュ処理:HTTP/1.0は主に
If - Modified - Since
とExpires
をキャッシュ判定基準として使用していましたが、HTTP/1.1はより多くのキャッシュ制御戦略を導入しており、例えばEntity tag
、If - Unmodified - Since
、If - Match
、If - None - Match
などです。 -
帯域幅最適化:HTTP/1.0には帯域幅の浪費という現象があり、中断したダウンロードの再開をサポートしていませんでした。HTTP/1.1は要求ヘッダに
range
ヘッダフィールドを導入し、リソースの一部のみを要求できるようにし、返り値のコードは206(Partial Content)となり、帯域幅の利用率が向上しました。 - エラー通知:HTTP/1.1は24の新しいエラーステータスステータス応答コードを追加しており、例えば409(Conflict)は要求されたリソースが現在の状態と競合していることを示し、410(Gone)はサーバ上のリソースが永続的に削除されたことを示します。
SPDY:HTTP/2.0の前身
SPDYは標準的なプロトコルではありません。その開発チームはそれをインターネットの草案に昇格させようと推進しましたが、最終的には単独で公式の標準になることはありませんでした。ただし、SPDYの開発チームのメンバーはHTTP/2.0の策定の全プロセスに参加しました。HTTP/2.0の主要な機能は主にSPDY技術に由来しており、SPDYの成果が採用されてHTTP/2.0に進化したと考えることができます。2015年9月、GoogleはSPDYに対するサポートを撤廃し、代わりにHTTP/2.0を採用することを発表し、Chrome 51でそれが実施されました。
SPDYはHTTPを置き換えるものではなく、HTTPの要求と応答がネットワーク上で送信される方法を改変するものです。SPDYのトランスポート層を追加するだけで、既存のサーバサイドのアプリケーションは何も改変する必要はありません。SPDYを使用して送信する際、HTTPの要求は処理、マーキング、簡素化、圧縮されます。
SPDYには以下の新機能があります:
- 多重化:複数の要求ストリームが単一のTCP接続を共有し、HOL(Head of Line)ブロッキングの問題を解決し、レイテンシを低減し、帯域幅の利用率を向上させます。
- 要求の優先順位:各要求に優先順位を設定でき、重要な要求が最初に応答されるようにします。例えば、ブラウザがホームページをロードする際、HTMLコンテンツを優先的に表示し、その後に静的なリソースやスクリプトファイルをロードすることができます。
- ヘッダ圧縮:HTTP/1.xのヘッダにはしばしば重複した冗長な情報が含まれています。SPDYは適切な圧縮アルゴリズムを選択して、パケットのサイズと数を削減します。
- HTTPSに基づく暗号化されたプロトコルの送信:送信されるデータの信頼性を向上させます。
-
サーバプッシュ:SPDYを使用するウェブページの場合、クライアントが
sytle.css
を要求すると、サーバはsytle.js
をクライアントにプッシュします。クライアントがその後sytle.js
を取得する際、キャッシュから直接取得することができ、別の要求を行う必要がありません。
HTTP/2.0
HTTP/2.0とSPDYの違い
- トランスポートプロトコル:HTTP/2.0は平文のHTTP送信をサポートしていますが、SPDYはHTTPSの使用を義務付けています。HTTP/2.0は非HTTPSもサポートしていますが、ChromeやFirefoxなどの主流のブラウザはTLSに基づいて展開されたHTTP/2.0プロトコルのみをサポートしています。したがって、HTTP/2.0にアップグレードするには通常、まずHTTPSをアップグレードする必要があります。
- メッセージヘッダの圧縮アルゴリズム:HTTP/2.0はHPACKアルゴリズムを使用してメッセージヘッダを圧縮しますが、SPDYはDEFLATEアルゴリズムを使用しています。
HTTP/2.0がHTTP/1.xと比較して持つ新機能
- 多重化:HTTP/2.0は、単一のHTTP/2接続を通じて複数の要求-応答メッセージを同時に開始することを可能にします。HTTP/1.1プロトコルでは、ブラウザクライアントは同じドメイン名の下での要求の数に制限があり、制限を超える要求はブロックされます。これは、一部のウェブサイトが複数の静的リソースCDNドメイン名を使用する理由の1つです。HTTP/2.0の多重化により、メッセージは単一の接続上で並列に交換できるようになり、HTTPプロトコル通信の基本単位をフレームに縮小し、これらのフレームは論理ストリーム内のメッセージに対応し、複数のTCP接続に依存することなく複数のストリームの並列化を実現します。例えば、複数のリソースを同時に要求する際:
:method: GET
:scheme: https
:authority: example.com
:path: /image1.jpg
:method: GET
:scheme: https
:authority: example.com
:path: /image2.jpg
HTTP/1.1における持続接続の再利用と比較すると、HTTP/1.*では、各要求-応答に対して接続が確立され、使用後に切断され、各要求は接続を確立する必要があります。HTTP/1.1のパイプラインモードでは、いくつかの要求がキューに入れられて直列の単一スレッド処理が行われ、後続の要求は前の要求が返されるのを待ってから実行できます。要求の1つがタイムアウトすると、後続の要求がブロックされます。一方、HTTP/2.0では、複数の要求を1つの接続上で並列に実行でき、大きなレイテンシを持つ要求は他の接続の正常な実行に影響を与えません。
HTTP/2.0の多重化により、TCP接続がより効果的に利用され、HTTPのパフォーマンスが向上します。TCP接続は「自己調整」し、初期段階で接続速度を制限し、データが正常に送信されるにつれて徐々に速度を上げます。つまり、TCPのスロースタートです。HTTP/2.0はすべてのデータストリームが同じ接続を共有できるようにしているため、HTTP接続の非効率性を低減し、混雑とパケットロスの回復時間を短縮し、接続のスループットを増やします。
- 要求の優先順位:多重化により、重要な要求がブロックされる可能性があります。HTTP/2.0は各要求に優先順位を設定できるようにしており、31ビットの優先順位値を使用し、0が最も高い優先順位を、2(31) - 1が最も低い優先順位を表します。サーバは優先順位に基づいてリソース割り当てを制御し、高い優先順位の要求フレームをクライアントに対して優先的に処理して返すことができます。
- バイナリフレーミング:HTTP/1.1はテキスト解析に基づいており、テキスト形式の多様性により、解析時に複数のシナリオを考慮する必要があり、ロバスト性が低いです。HTTP/2.0はバイナリ形式の解析を採用し、アプリケーション層(HTTP/2.0)とトランスポート層(TCPまたはUDP)の間にバイナリフレーミング層を追加しました。この層は、すべての送信情報をより小さなメッセージとフレーム(frame)に分割し、バイナリ形式で符号化します。HTTP/1.xのヘッダ情報はHEADERフレームにカプセル化され、RequestBodyはDATAフレームにカプセル化されます。HTTP/2.0でのすべての通信は1つの接続上で完了し、この接続は任意の数の双方向データストリームを担うことができます。
- ヘッダ圧縮:HTTP/1.1はHTTPヘッダの圧縮をサポートしておらず、SPDYとHTTP/2.0はこの目的のために登場しました。SPDYはDEFLATEアルゴリズムを使用し、HTTP/2.0はHPACKアルゴリズムを使用しています。HTTP/2.0は辞書を保持し、HTTPヘッダを増分的に更新することで、ヘッダ送信によって生成されるトラフィックを削減します。通信の両当事者はそれぞれヘッダフィールドのテーブルをキャッシュし、重複したヘッダの送信を避け、送信サイズを削減します。
- サーバプッシュ:HTTP/2.0では、サーバはクライアントからの単一の要求に対して複数の応答を送信できます。サーバプッシュにより、HTTP/1.x時代の埋め込みリソースを使用する最適化方法はもはや必要ありません。ホームページから要求が発行された場合、サーバはホームページのコンテンツ、ロゴ、およびクライアントが必要とするスタイルシートなどのリソースを応答として送信することができ、これらのリソースはキャッシュされ、同じオリジン下の異なるページ間でのキャッシュリソースの共有が実現されます。
HTTPプロトコルバージョンの比較表
機能 | HTTP/1.0 | HTTP/1.1 | HTTP/2.0 |
---|---|---|---|
接続方法 | 短い接続、各要求ごとに新しい接続を確立 | 持続接続、Connection: keep - alive がデフォルトで有効 |
多重化、単一接続上で複数の要求 |
先頭ブロッキング | 存在、パフォーマンスに影響 | パイプライン機構により部分的に軽減されるが、ブラウザのサポートが限定的 | 多重化により解決 |
要求ヘッダのサポート | Hostヘッダをサポートせず、仮想ホストの実装が困難 | Hostヘッダをサポートし、複数の仮想ホストを設定可能 | より豊富な機能をサポート |
キャッシュ制御 |
If - Modified - Since 、Expires
|
Entity tag 、If - Unmodified - Since などを追加 |
さらに最適化 |
中断したダウンロードの再開 | サポートしない |
RANGE:bytes を通じてサポート |
サポート |
ヘッダ圧縮 | サポートしない | サポートしない | HPACKアルゴリズムにより圧縮 |
要求の優先順位 | サポートしない | サポートしない | サポート |
サーバプッシュ | サポートしない | サポートしない | サポート |
参照リンク
Leapcell: サーバレスウェブホスティングの最高峰
最後に、サービスをデプロイするのに最適なプラットフォームをお勧めします:Leapcell
🚀 好きな言語で構築
JavaScript、Python、Go、またはRustで簡単に開発できます。
🌍 無料で無制限のプロジェクトをデプロイ
使用した分だけ支払います — 要求がなければ、請求はありません。
⚡ 使った分だけ支払い、隠された費用はありません
アイドル料はなく、シームレスなスケーラビリティが実現されます。
🔹 Twitterでフォローしてください:@LeapcellHQ