3. Copyright (C) 2016 DeNA Co.,Ltd. All Rights Reserved.
最近の仕事
H2O
⁃ ディー・エヌ・エーで開発しているウェブサーバ
• 2014年12月: 初回リリース (0.9.0)
• 2014年2月: 1.7.0リリース
⁃ HTTP/2対応 (おそらく世界最速)
⁃ その他、先進的な取り組み
⁃ オープンソース (MIT License)
標準化活動
⁃ Cache Digests for HTTP/2
3HTTPとサーバ技術の最新動向
4. Copyright (C) 2016 DeNA Co.,Ltd. All Rights Reserved.
本日のテーマ: HTTPとサーバ技術の最新動向
目次:
⁃ サーバ技術の評価軸
⁃ HTTP/2
• 誕生の背景と基礎
• レスポンスタイム最適化
⁃ サーバプッシュ
⁃ HTTPS化とサーバ負荷
⁃ Brotli
⁃ ウェブサーバ内でのスクリプト実行
4HTTPとサーバ技術の最新動向
5. Copyright (C) 2016 DeNA Co.,Ltd. All Rights Reserved.
サーバ技術の評価軸
5HTTPとサーバ技術の最新動向
6. Copyright (C) 2016 DeNA Co.,Ltd. All Rights Reserved.
サーバ技術の評価軸
サーバ負荷
転送データ量
応答性
設定・運用コスト
6HTTPとサーバ技術の最新動向
7. Copyright (C) 2016 DeNA Co.,Ltd. All Rights Reserved.
サーバ負荷の削減
例: HandlerSocket
⁃ DeNA樋口が開発
• MySQL Conference Community Awards 2011受賞
⁃ MySQLサーバにKVSプロトコルを追加
⁃ 単純なクエリにSQLを使わないことにより、大量の接
続を高速に処理
⁃ 効果:
• スレーブ台数を削減(LANのデータ転送量も)
• サーバが数千台規模だと、削減コスト>>開発費
7HTTPとサーバ技術の最新動向
8. Copyright (C) 2016 DeNA Co.,Ltd. All Rights Reserved.
転送データ量の削減
主な受益者
⁃ 大規模事業者
⁃ モバイル回線のユーザ
参考:
⁃ Amazon EC2のネットワーク価格: 〜$0.05/GB
• 10Gbps * 1 year = 40PB / year → 2.4億円 / 年
8HTTPとサーバ技術の最新動向
9. Copyright (C) 2016 DeNA Co.,Ltd. All Rights Reserved.
応答性
9HTTPとサーバ技術の最新動向
出典: http://radar.oreilly.com/2009/06/bing-and-google-agree-slow-pag.html
レスポンスタイム短縮 → 売上増加
10. Copyright (C) 2016 DeNA Co.,Ltd. All Rights Reserved.
HTTP/2の基本
10HTTPとサーバ技術の最新動向
11. Copyright (C) 2016 DeNA Co.,Ltd. All Rights Reserved.
誕生の背景
11HTTPとサーバ技術の最新動向
12. Copyright (C) 2016 DeNA Co.,Ltd. All Rights Reserved.
転送データ量は増大中
12HTTPとサーバ技術の最新動向
出典: http://httparchive.org/trends.php?s=All&minlabel=Aug+1+2011&maxlabel=Aug+1+2015#bytesTotal&reqTotal
13. Copyright (C) 2016 DeNA Co.,Ltd. All Rights Reserved.
バンド幅も増大中
エンドユーザのバンド幅は年率50%で増加(ニールセン
の法則)
13HTTPとサーバ技術の最新動向
出典: http://www.nngroup.com/articles/law-of-bandwidth/
14. Copyright (C) 2016 DeNA Co.,Ltd. All Rights Reserved.
未来はバラ色?
14HTTPとサーバ技術の最新動向
15. Copyright (C) 2016 DeNA Co.,Ltd. All Rights Reserved.
ページロード時間はバンド幅に比例しない
15HTTPとサーバ技術の最新動向
出典: More Bandwidth Doesn't Matter - 2011 Mike Belshe (Google)
※実効バンド幅は1.6Mbps程度で頭打ちに
16. Copyright (C) 2016 DeNA Co.,Ltd. All Rights Reserved.
ページロードはレイテンシが小さいほど速い
16HTTPとサーバ技術の最新動向
出典: More Bandwidth Doesn't Matter - 2011 Mike Belshe (Google)
17. Copyright (C) 2016 DeNA Co.,Ltd. All Rights Reserved.
Why?
17HTTPとサーバ技術の最新動向
18. Copyright (C) 2016 DeNA Co.,Ltd. All Rights Reserved.
HTTP/1.1は多重性がない
18HTTPとサーバ技術の最新動向
RTT
request
response
request
response
client server
…
RTT
HTTP/1.1では、1RTTあたり1リクエスト/レスポンスし
か送受信できない
⁃ RTT=ラウンドトリップタイム
• レイテンシの大きさを表す値
緩和策:複数のTCP接続を使う
⁃ 同時6本が一般的
• 1RTTあたり6リクエスト!!!
• それでも遅い
19. Copyright (C) 2016 DeNA Co.,Ltd. All Rights Reserved.
HTTP/1.1パイプラインの問題
19HTTPとサーバ技術の最新動向
RTT
requests
responses
client server
仕様上、レスポンス受信前に次のリクエストを送信可能
問題:
⁃ 切断時に、レスポンス未受信のリクエストを再送信し
ていいかわからない
• サーバが同じリクエストを複数回処理する可能性
⁃ 先行リクエストの処理に時間がかかると後続が詰まる
(head-of-line blocking)
⁃ バグのあるサーバ実装が多い
20. Copyright (C) 2016 DeNA Co.,Ltd. All Rights Reserved.
レイテンシは今後も小さくならない
光の速度はかわらない
⁃ アメリカまで光ファイバーで往復すれば80ミリ秒
携帯回線はレイテンシが大きい
⁃ LTE ~ 50ms
20HTTPとサーバ技術の最新動向
21. Copyright (C) 2016 DeNA Co.,Ltd. All Rights Reserved.
やばい!ウェブが遅くなってきた!
21HTTPとサーバ技術の最新動向
22. Copyright (C) 2016 DeNA Co.,Ltd. All Rights Reserved.
どうしよう?
22HTTPとサーバ技術の最新動向
23. Copyright (C) 2016 DeNA Co.,Ltd. All Rights Reserved.
解決策:レイテンシに負けないプロトコルを作る
23HTTPとサーバ技術の最新動向
24. Copyright (C) 2016 DeNA Co.,Ltd. All Rights Reserved.
HTTP/2!
24HTTPとサーバ技術の最新動向
25. Copyright (C) 2016 DeNA Co.,Ltd. All Rights Reserved.
HTTP/2
RFC 7540 (2015/5)
⁃ GoogleのSPDYプロトコルの実験を参考に規格化
基本的な技術要素
⁃ バイナリプロトコル
⁃ 多重化
⁃ ヘッダ圧縮
25HTTPとサーバ技術の最新動向
36. Copyright (C) 2016 DeNA Co.,Ltd. All Rights Reserved.
ここまでのまとめ
HTTP/2の基本
⁃ 多重化によりレイテンシの影響を低減
⁃ ヘッダ圧縮により通信量を低減
上記2点を体感できるデモ
⁃ https://www.symfony.fi/entry/compare-
resource-loading-between-http-2-and-http-1-1
36HTTPとサーバ技術の最新動向
37. Copyright (C) 2016 DeNA Co.,Ltd. All Rights Reserved.
HTTP/2におけるレスポンスタイム最適化
37HTTPとサーバ技術の最新動向
38. Copyright (C) 2016 DeNA Co.,Ltd. All Rights Reserved.
HTTP/2のレスポンスタイムベンチマーク
コンテンツ系ウェブサイトが表示されるまでの時間測定
初期描画(first-paint)までの時間に大差、H2Oが最短
38HTTPとサーバ技術の最新動向
39. Copyright (C) 2016 DeNA Co.,Ltd. All Rights Reserved.
差が出た理由: 優先度制御
39HTTPとサーバ技術の最新動向
40. Copyright (C) 2016 DeNA Co.,Ltd. All Rights Reserved.
HTTP/2の規定する優先度制御
クライアントがリクエスト毎に優先度を指定する
⁃ 2種類の制御手法の組み合わせ
• 重みづけ (weight)
⁃ 値に比例したバンド幅の配分
• 依存関係 (dependency)
⁃ 依存されているレスポンスを先に送信
⁃ グループ化にも利用
サーバは指定された優先度を「参考にする」
40HTTPとサーバ技術の最新動向
41. Copyright (C) 2016 DeNA Co.,Ltd. All Rights Reserved.
Firefoxの優先度制御
41HTTPとサーバ技術の最新動向
Root
Leader G
Follower G
weight: 1
HTML
weight: 32
Image
weight: 22
Image
weight: 22
Image
weight: 22
CSS
weight: 32
CSS
weight: 32
各CSS, JSを、HTMLや画像より先に転送
⁃ 正確には32倍速く転送
HTMLを画像よりも多少優先
JS
weight: 32
JS
weight: 32
42. Copyright (C) 2016 DeNA Co.,Ltd. All Rights Reserved.
H2Oの優先度制御実装
H2Oは
⁃ Webブラウザの指示に従い、バンド幅を配分
• 割当はHTTP/2の規定どおり
⁃ 優先度制御の粒度が細かい
• 16KB単位でストリームを切り替え
• 約64KB単位でバッファリング
全てのHTTP/2サーバが優先度制御を(正しく)実装して
いるわけではない
42HTTPとサーバ技術の最新動向
50. Copyright (C) 2016 DeNA Co.,Ltd. All Rights Reserved.
サーバプッシュ
50HTTPとサーバ技術の最新動向
51. Copyright (C) 2016 DeNA Co.,Ltd. All Rights Reserved.
サーバプッシュ
HTTP/2はRTTを隠蔽する技術
でも、1RTT(リクエストを投げてからレスポンスを受け
取るまで)は絶対かかるよね?
それ、0RTTでできるよ!
⁃ サーバが、クライアントの発行するリクエストを予測
して、レスポンスをプッシュすればいい
※これ以外の目的でも使える技術ですが、今回はウェブブラ
ウザのレスポンスタイムに絞った議論をします
51HTTPとサーバ技術の最新動向
52. Copyright (C) 2016 DeNA Co.,Ltd. All Rights Reserved.
サーバプッシュ
例: RTT=50ms, アプリサーバの処理時間=200ms
52HTTPとサーバ技術の最新動向
req.
processrequest
push-asset
HTML
push-asset
push-asset
push-asset
req.
processrequest
asset
HTML
asset
asset
asset
req.
450ms(5RTT+processingme)
250ms(1RTT+processingme)
without push with push
53. Copyright (C) 2016 DeNA Co.,Ltd. All Rights Reserved.
サーバプッシュ
CDNによるウェブ高速化にも応用可能
⁃ アプリサーバの応答を待つ間も回線を有効活用可能
⁃ アプリ提供者は、その分、アプリサーバの設置拠点を
減らすことが可能に
53HTTPとサーバ技術の最新動向
req.
push-asset
HTML
push-asset
push-asset
push-asset
client edge server (CDN) app. server
req.
HTML
54. Copyright (C) 2016 DeNA Co.,Ltd. All Rights Reserved.
サーバプッシュ
実用にむけた課題:
⁃ (クライアントに頼らない)優先度制御
⁃ プッシュの起動方法
⁃ ブラウザキャッシュとの兼ね合い
54HTTPとサーバ技術の最新動向
55. Copyright (C) 2016 DeNA Co.,Ltd. All Rights Reserved.
サーバプッシュと優先度制御
RFCどおり実装してあっても、あまり役に立たない
⁃ プッシュされるレスポンスは、プッシュを
起動したレスポンスに依存する形でスケ
ジュールされるから
画像をHTMLより優先してプッシュするわけにもいかな
い
H2Oは、プッシュのmime-typeを見て優先度を決定
⁃ reprioritize-blocking-assetsと同様
⁃ つまり、JSやCSSなら最優先で
• 画像ならHTMLの後で
55HTTPとサーバ技術の最新動向
HTML
weight: ??
CSS (pushed)
weight: 16
56. Copyright (C) 2016 DeNA Co.,Ltd. All Rights Reserved.
サーバプッシュの使い方 (1)
Link: rel=preload ヘッダ
⁃ アプリサーバが返す Link ヘッダを認識してプッシュ
HTTP/1.1 200 OK
Content-Type: text/html
Link: </style.css>; rel=preload # このヘッダ!!!
⁃ H2O, nghttpx (nghttp2), mod_h2 (Apache) が対応
⁃ 問題: アプリサーバが応答を返すまでプッシュ不可能
56HTTPとサーバ技術の最新動向
57. Copyright (C) 2016 DeNA Co.,Ltd. All Rights Reserved.
サーバプッシュの使い方 (2)
H2O では、アプリサーバへリクエストを転送する前にプ
ッシュを開始可能
# 1. mrubyハンドラでプッシュを開始 (Linkヘッダをセット)
mruby.handler: |
Proc.new do |env|
[399, { "Link" => "</style.css>; rel=preload" }, []]
end
# 2. リバースプロキシハンドラがアプリサーバにリクエストを転送
proxy.reverse.url: http://app.example.com:8080/
57HTTPとサーバ技術の最新動向
58. Copyright (C) 2016 DeNA Co.,Ltd. All Rights Reserved.
サーバプッシュ vs. ブラウザキャッシュ
キャッシュ済のファイルはプッシュしたくない
⁃ バンド幅(と場合によっては時間)のムダ
キャッシュの有無を判断する方法は?
⁃ ブラウザキャッシュ内の状況を確認するためにリクエ
スト/レスポンスを送信してはいけない
• そのために1RTTかかるとプッシュのメリットがなくなる
58HTTPとサーバ技術の最新動向
85. Copyright (C) 2016 DeNA Co.,Ltd. All Rights Reserved.
OpenRestryのコルーチン使用例
redis.client:get の呼出時に、コルーチンがイベントルー
プに処理を渡す
⁃ プログラマは非同期であることを意識しなくていい
local redis = require "redis"
local client = redis.connect(REDIS_ADDR, REDIS_PORT)
route = client:get(ngx.var.http_host)
if route ~= nil then
ngx.var.upstream = route
else
ngx.exit(ngx.HTTP_NOT_FOUND)
end
ref: http://blog.cybozu.io/entry/2016/02/16/080000
85HTTPとサーバ技術の最新動向
86. Copyright (C) 2016 DeNA Co.,Ltd. All Rights Reserved.
単純なコルーチン実装の問題
複数のサーバに同時問い合わせができない
並行問い合わせが必要なユースケース:
⁃ HTML内の特殊タグを認識して、ウェブサーバで別の
コンテンツを差し込み (Edge-side Includes)
<esi:include src="http://ad-server.local/..." />
解決策: 非同期処理をタスクとして抽象化
⁃ H2Oのアプローチ
86HTTPとサーバ技術の最新動向
87. Copyright (C) 2016 DeNA Co.,Ltd. All Rights Reserved.
H2Oの非同期タスク
http_requestメソッドはタスクを返す
タスクはイベントループ側で非同期に実行される
join メソッドが呼ばれると、結果取得までコルーチンが
スリープする
例: 広告を差し込んで返すコード
app_req = http_request("http://example.com")
ad_req = http_request("http://example.org")
ad_html = (ad_req.join)[2].join
status, headers, body = main_req.join
body = [body.join.gsub(/<!--insert ad-->/, ad_html)]
[status, headers, [body]]
87HTTPとサーバ技術の最新動向
88. Copyright (C) 2016 DeNA Co.,Ltd. All Rights Reserved.
非同期タスクを用いたESI実装
# HTML内の<ESI>タグを展開しつつ、届いたところからクライアントに送信
class ESIResponse
def initialize(input)
@parts = input.split /(<esi:include +src=".*?" */>)/
@parts.each_with_index do |part, index|
@parts[index] = http_request("http://127.0.0.1:5000/#{$1}")
if /^<esi:include +src=" *(.*?) *"/.match(part)
end
end
def each(&block)
@parts.each do |part
if part.kind_of? String
block.call(part)
else
part.join[2].each(&block)
end
end
end
end
88HTTPとサーバ技術の最新動向