HTTP/3の確認と雑な性能検証


# なぜ書いた
 ゼミ課題でHTTP/3（HTTP over QUIC)に関する課題が出たので、それをまとめていく。
大したことは書いていないので、

ここや
https://asnokaze.hatenablog.com/entry/2018/10/31/020215
ここ
https://asnokaze.hatenablog.com/entry/2018/11/06/025016
それから
https://http3-explained.haxx.se/ja/

などを見ると大体わかるようになると思う。

一応自分でもまとめておく。

##QUICについて

始めに書いたように、HTTP/3はTCPではなくQUICというGoogleが考案したトランスポートプロトコルを使う。
しかし、QUIC自体はUDPのユーザ空間上に実装されている。
トランスポートプロトコルであるQUICがトランスポートプロトコルのUDP上で動くわけである。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/213388/dd3d9fc3-79eb-2ea3-2399-6e49a24268e4.png)
上の画像は、詳解 HTTP/3からコピペしたHTTP/3とHTTP/2のプロトコルスタックである。
このように、OSI参照モデルについては頭の中から外して考える必要がある。

ここから少し機能について触れておく。
ただし、私の理解であるので不適切な表現や間違いがありそうなので、指摘など待ってます。

###素早いハンドシェイク
TCPはトランスポートプロトコルのみであったが、QUICはTLSも内包している。

TCP:TCPコネクションの確立の後にTLSフルハンドシェイク
QUIC：同時にTLSハンドシェイク

TCPのハンドシェイクは
https://blog.lorentzca.me/tcp-3-way-handshake-and-tls-full-handshake/

ただ、いまいち仕組みが分からなくてとても苦しい。

### 0-RTTでの通信の再開
以前にサーバーと接続していたクライアントは特定のパラメータをキャッシュすることができるため、ハンドシェイク完了を待たずに通信ができます。


### ストリームが独立
HTTP/2で提供されていましたが、QUICではトランスポートレイヤにストリームを持ちます。


HTTP/1.1ではリクエスト・レスポンスを同時に複数扱うためにTCPコネクションを複数作っていましたが、TCPの輻輳制御がそれぞれで行われていたためあまり効率がよくありませんでした。
そのため、HTTP/2ではTCPコネクションは一つにし、その中でストリームという仮想的なコネクションを作ることで複数のリクエスト・レスポンスを扱っていました。
しかし、一つのストリームでパケットロスや並び変わりが起きるとすべてのストリームがブロックされ読み直しが起こります。

QUICで提供されるストリームではUDPのユーザ空間で処理できるため、パケットロスや並び変わりが起きたストリームのみがブロックされます。
そのほかのストリームがブロックされません。

##HTTP/3
### HTTP/3用のポートがない
まず、TCPでのコネクションが確立され、サーバーがクライアントの HTTP 要求に応答する際、レスポンスヘッダに ` Alt-Svc: h3=":ポート番号" ` を含めることでQUICを使用できることが通知できます。



##実験
今回、[Caddy](https://caddyserver.com/)という、サーバソフトを使ってquicを体験したいと思う。
残念ながら、IETFで策定されているQUICではなく今後消えゆくGoogleのQUICで実装されています。
gquicとiquicの差は申し訳ないのですが調べてもいまいちわからなかったです。(QUICがHTTP前提であるかの違い・・・？)
また、運用するわけではないのでチューニングなどは一切行っていない。
実験の比較は、HTTP/1.1、HTTP/2、HTTP over QUICで行う。
サーバに置いたコンテンツは右の無料テンプレートを使用 https://colorlib.com/wp/template/transcend/
 
###caddyでquicを使う

今回は例示として、example.comとexample.jpを使用していいる。
[example.com](https://example.com)はRFCで決まっている。
example.jpはJPRSで決まっているらしい。

caddyは設定を`Caddyfile`というfileで管理する。
また、caddyはcaddyを起動したときのカレントディレクトリがwebの公開ディレクトリになるので注意。
便利なことにドメインを書くと自動でLet's Encryptから証明書を取ってきてくれる。
caddyのインストールは公式に従うとこうなる

```
wget https://caddyserver.com/download/linux/amd64?license=personal -O caddy_v0.11.2_linux_amd64_personal.tar.gz

tar -xzf caddy*.tar.gz caddy

mv ./caddy /usr/local/bin
```
これで`caddy`コマンドが使えるようになる。

今回使用するドメインをexample.comとする。
その時のCaddyfileは

```
https://example.com {
        tls hege@example.jp
}
```

httpsで通信するときはWellknownポートを使うので管理者権限が必要であることを忘れずに。
http/2で起動する場合

```
sudo caddy -http2
```
quicを使う場合

```
sudo caddy -quic
```

HTTP/1.1がしたい場合、Caddyfileのないディレクトリで`sudo caddy -port 80`するといい



### 実験1
十分な速度の通信回線で、HTTP/1.1、HTTP/2、HTTP over QUICを使用して同じサイトに接続して違いが出るか

この場での十分な速度の通信回線とは[独立行政法人国民生活センターが発行する「国民生活」2017年11月号の17ページ(PDFです)](http://www.kokusen.go.jp/wko/pdf/wko-201711_05.pdf)にて４K画質動画を視聴することができるとされている24Mbps以上の通信回線のことをさします。


- サーバにサイトを用意
- 用意したサイトに自宅のPCからシークレットモードのChromeで開発者モードを開いた状態で接続
- サイトの読み込み時間やリクエストの数などを記録
- 各プロトコル五回ずつ繰り返し


トポロジー図としては
![image.png](https://qiita-image-store.s3.amazonaws.com/0/213388/32df6ff7-b1b8-9483-4c36-e89d70889d13.png)

####結果
HTTP/1.1
![image.png](https://qiita-image-store.s3.amazonaws.com/0/213388/4fa9bb98-0b32-aa31-d08d-0c8a07811e04.png)
HTTP/2
![image.png](https://qiita-image-store.s3.amazonaws.com/0/213388/abf006f4-dddd-0aa5-c3e4-06b6a192671b.png)
HTTP over QUIC
![image.png](https://qiita-image-store.s3.amazonaws.com/0/213388/71b9d13d-ea45-37c9-2be3-85f8b17eedff.png)


####まとめ
そんなに差があるわけではないっぽい




###実験2
上限200kbpsの通信速度制限のかかった携帯回線でHTTP/1.1,HTTP/2,HTTP over QUICを使用して同じサイトに接続すると違いが出るか

- サーバにサイトを用意
- 用意したサイトにスマホからUSBテザリングされたPCからシークレットモードのChromeで開発者モードを開いた状態で接続
- サイトの読み込み時間やリクエストの数などを記録
- 各プロトコル五回ずつ繰り返し


トポロジー図としては
![image.png](https://qiita-image-store.s3.amazonaws.com/0/213388/e83d65ca-38c6-bb4a-e7e2-7e62bb99e87e.png)


####結果
HTTP/1.1
![image.png](https://qiita-image-store.s3.amazonaws.com/0/213388/dc1d2dac-9ff0-5ddb-8400-71134674676d.png)

HTTP/2
![image.png](https://qiita-image-store.s3.amazonaws.com/0/213388/5663efcd-1877-034d-c7f2-4dd569b4724b.png)

HTTP over QUIC
![image.png](https://qiita-image-store.s3.amazonaws.com/0/213388/8482268b-c87b-16ac-e3e2-c8731fa26ed8.png)


####まとめ
若干 QUICがはやい・・・？
ただ、リクエスト数や転送容量がHTTP/2と比べると減っているのでストリームのブロックが減っているんだと思う。


###最後に
プロトコルとか全然わからんって感じでずっと課題をやっていた。

![Untitled Diagram(2).jpg](https://qiita-image-store.s3.amazonaws.com/0/213388/b7a0a9c2-35c7-c812-2b8b-2ed7b970e580.jpeg)
こんな感じのトポロジー図だと、HTTP/2とQUICの差が全くでなかったそうです。
ところが、パケットのサイズをいじったら差が出たそうで、現実だとやっぱりパケットサイズ変わるんだなって思いました。