NodeConf EU 2019でのトークの要点まとめです。
はじめに
- NearForm社でリサーチやってます
- 主にOSS活動
- 最近はNodeにQUICを実装してる
HTTP/2 in Node.js
- その前にHTTP/2について
- Nodeにも実装はあって、2017年にコアにはいった
- けど、残念ながら使い勝手はあまりよくない...
- だいたいのNodeは前段にNginxなどを置くせい
- HTTP/2はステートフルなプロトコル
- ヘッダ圧縮のために、コネクションは状態を持つ必要がある
- それを経由するミドルボックスで協調してメンテするのが無理
- Node <-> Nodeとか、ブラウザ直でつなげるなら有用ともいえる
HTTP/2
- HTTP/1.xは、1リクエスト:1TCPコネクション
- なのでHOLBが問題になる
- 1つパケットが落ちると、後続のパケットはその再送を待つ
- HTTP/2では、リクエストを多重化した
- Nリクエスト:1TCPコネクション
- しかし結局TCPなので、HOLBからは逃れられない...
- 物理的に距離が遠かったり、モバイルなど低品質のNWの場合にそれが顕著
QUIC
- そこでQUIC, HTTP/3
- QUICはUDPベース
- unreliableなプロトコル
- それぞれのパケットは独立してる
- なのでTCPでやってたことを、全部実装しなおしてる
- 到達確認(=reliable)
- シーケンス(=ordering)
- 輻輳制御
- 暗号化 w/ TLS1.3
- etc...
- HTTP/3は、そんなQUICセッションを束ねてる
- TCPはIPに紐付いたコネクションなので、NWを変えると切れる
- そういうのも大丈夫
QUIC in Node.js
const { createSocket } = require("quic"); const socket = createSocket(); socket.listen({ port: 443, key, cert, ca }); socket.on("session", session => { session.on("stream", stream => { stream.end("Hello world!"); }); });
- ただいま絶賛実装中
- という具合に、見慣れたNodeのコードで書ける
- `stream`は単なる`Duplex`な`Stream`
- そしてQUICは単なるトランスポートプロトコル
const { createSocket } = require("quic"); const socket = createSocket(); const req = socket.connect({ address, port: 443, key, cert, ca }); req.on("secure", () => { const stream = req.openStream(); stream.end("Hello world!"); stream.on("data", data => {}); });
- という感じでHTTP/3を実装する
- QUIC上のアプリケーションプロトコルとして
- なのでQUICの上に独自のプロトコルを実装することもできる
進捗
- `ngtcp2`の`tatsuhiro-t`さんありがとう
- 実装はここで進行中
- おそらく2019年の11月末にExperimentalなPRをコアに出せそう
- ただし来年いっぱいくらいはAPIを洗練したり検討したりすると思う
- まだ実装しないといけないこともいっぱいあるし
- (クラサバでパケットを送り合うデモ)
- 流れたByte数とかストリームの数などが、JSのAPIから取れる!
- Wiresharkとかでデバッグできるようキーロギングサポートも