HTTP/3とQUICについてざっくり解説

この記事は、[Ateam Finergy Inc. Advent Calendar 2021](https://qiita.com/advent-calendar/2021/ateam-finergy) 19日目の記事です :christmas_tree: 

本日は、[ナビナビ証券](https://navinavi-shoken.com/) の開発に携わっている @kazenomachi が担当します。

## はじめに

これまでインターネットでは**TCP**（Transmission Control Protocol）という通信プロトコルが標準的に用いられてきましたが、
今年の5月、IETF（Internet Engineering Task Force）によって新たに**QUIC**というプロトコルが[RFC9000](https://datatracker.ietf.org/doc/html/rfc9000)として承認されました。

QUICがこれからのインターネットにどのような影響を及ぼすのでしょうか？

本記事では、**QUIC**と**HTTP/3**について、できるだけ簡単に、掻い摘んで解説してみようと思います。

## これまでのインターネット

WebブラウザとWebサーバーとの間の通信では、**HTTP**というプロトコルが用いられています。

HTTPは、最初にHTTP/1.1が1997年に[RFC 2068](https://datatracker.ietf.org/doc/html/rfc2068)として標準化されました。

**HTTP/1.1**は、テキスト形式でデータのやりとりを行います。
ひとつのリクエストが完了するまで、次のリクエストを送信することができないという仕組みのため、Webコンテンツが発展し大規模になるにつれて、非効率な通信方法であることが問題となってきました。
（これを`Head-of-Line-Blocking問題`といいます）

その後、時代に合わせて改良が進み、HTTP/2が2015年に[RFC 7540](https://datatracker.ietf.org/doc/html/rfc7540)として標準化されました。

**HTTP/2**では、テキスト形式ではなくバイナリ形式でデータのやりとりを行うようになりました。
従来のHTTP/1.1を踏襲しつつ、HPACKというヘッダ圧縮技術やストリーム技術が導入され、データの転送量を減らすことが可能となりました。

HTTP/1.1で問題となっていたHead-of-Line-Blocking問題に対しては、ストリームの多重化を行うことで、**1つのコネクション上で複数のリクエストを送る**ことが可能となりました。
しかし、複数のリクエストを単一のTCPコネクションで処理するため、もしもパケットロスが生じた場合、そのパケットの再送を待つ間、コネクションが停止することとなります。
パケットロス率が上昇すると、それだけパフォーマンスが低下することとなります。

HTTP/2ではHTTP（アプリケーション層）におけるHead-of-Line-Blocking問題は解消しましたが、TCP（トランスポート層）におけるHead-of-Line-Blocking問題は残っているという状態でした。
この問題を解消するために、新たに**QUIC**というプロトコルが開発されました。

## QUIC

QUICとは、2013年にGoogleが発表し、2021年5月にIETFで[RFC9000](https://datatracker.ietf.org/doc/html/rfc9000)として承認された**トランスポート層のプロトコル**で、UDPをベースに開発されました。

HTTP/2までで使われていた**TCPではなく、UDPがベース**となっています。
UDPは、パケットを受信する順序に決まりがないため、パケットロスが発生しても問題なく他のパケット処理を行うことができ、TCPで発生していたHead-of-Line-Blocking問題は発生しません。
しかし、TCPと違い、3wayハンドシェイクによる応答の確認やパケットロス時の再送処理等を行わない通信方法のため、信頼性が低いことが問題となります。
（TCPは確実に届くけど時間がかかる宅配便で、UDPは玄関の前に置き配していくけどたまに誤配や紛失があるようなものだとイメージすると理解しやすいかと思います）

この信頼性の低さを補うための機能が独自に実装されたものが、QUICとなります。

QUICでは、**暗号化通信を必須とし、TLSハンドシェイク**を行います。
また、TLS1.3を使用することで、TLS1.2よりも通信が1往復少なく、より効率化されています。
パケットロス時の処理や輻輳制御も独自に実装され、**効率よく信頼性の高い通信**を行うことができるのが特徴です。

## HTTP/3

ここまで長くなりましたが、QUICを使用してWeb通信を行うための**アプリケーション層のプロトコル**が、HTTP/3になります！

QUICを使用することにより、Head-of-Line-Blocking問題を解消し、より高速なWeb通信を実現するのがHTTP/3です。

QUICは今年5月にIETFで標準化されましたが、HTTP/3についてはまだDraftの段階で、[QUIC Working Group](https://quicwg.org/)で議論が進められています。
ですが、Google等ではすでにHTTP/3が段階的に採用されています。

Chromeの最新バージョンの開発者ツールでネットワークタブを開くと、プロトコルの項目に「h3」と記載されるものがHTTP/3を使った通信となっています。
YouTube等を開いて確認してみると、意外と身近なところでHTTP/3が使われていることを実感できると思います。
![スクリーンショット 2021-12-16 12.08.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202164/af9610e3-1baa-2dbc-3cf8-8568a45f8613.png)

HTTP/3の普及は徐々に広がっており、W3Techsの調査によると2021/12/16現在ではおよそ**23.9%**のWebサイトがHTTP/3に対応しているようです。
> ![スクリーンショット 2021-12-16 12.17.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202164/c4a0792d-2739-365d-24a6-6e17c2bb118b.png)
> 引用： [HTTP/2 vs\. HTTP/3 usage statistics, December 2021](https://w3techs.com/technologies/comparison/ce-http2,ce-http3)


[Cloudflare](https://cloudflare-quic.com/)や[Fastly](https://www.fastly.com/jp/quic-http-3)等のCDNでも、HTTP/3に対応しています。
Cloudflareでは、「ネットワーク」の設定画面で有効にするだけでクライアントからエッジまでの接続を簡単にHTTP/3化することができます。
![スクリーンショット 2021-12-16 11.33.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202164/c4db16c9-07e8-980d-4757-b94db36a0217.png)

CloudflareのQUICの実装については、OSSとして公開されています。（Rustで実装されています！）
curlやNginxで動かしてみることができるので、ぜひ試してみてください。

https://github.com/cloudflare/quiche


## まとめ

QUICとHTTP/3について、長くなりましたができるだけ掻い摘んで解説してみました。
通信の効率化において様々な工夫がされており、Webの高速化が期待できます。
HTTP/3についてはまだDraftですが、標準化されればより一層普及が進んでいくと思うので、取り残されないように今後も最新情報を追っていきたいと思います。

最後までお読みいただき、ありがとうございました :santa: :christmas_tree: :stars:


## 参考文献など

- [QUIC Working Group](https://quicwg.org/)
- [日本語 \- HTTP/3 explained](https://http3-explained.haxx.se/ja)
- [HTTP の進化 \- HTTP \| MDN](https://developer.mozilla.org/ja/docs/Web/HTTP/Basics_of_HTTP/Evolution_of_HTTP)
- [HTTP/2 vs\. HTTP/3 usage statistics, December 2021](https://w3techs.com/technologies/comparison/ce-http2,ce-http3)
- [QUIC \| Cloudflare](https://cloudflare-quic.com/)