いい加減CentOS 7にしないと思っているこのブログサーバーですが、本日またちょっと改善しました。TCP Fast Open(TFO)に対応させたのと、一部表示に不具合のあったWebp対応を無効化しました。
サーバーは速いに越したことはないです。
TCP Fast Open
何を今更、という感じが無くも無いですが、フラフラとネット見てたら、なんか見つけたんですよね。
マイクロソフト、より高速な「TCP Fast Open」など採用へ、Windows 10の大型アップデートとWindows Server 2016で - Publickey
どうやらこのTFO、理屈からしてもかなり速くなりそうで、かつ、影響も少なそう、ということで、軽く検証しつつ、サーバーに適応してみました。ちなみに、RFCはこちら。
TFOを有効化するには、以下の条件が必要です。
- OS(TCPスタック)が対応していること
- アプリ(サーバー・クライアント)が対応していること
- 途中の通信路でパケット書き換えが行われないこと
OSの対応については、Linuxであれば3.6以降の対応ということで、CentOS 7や、kernel-rtで3.10系を導入しているCentOS 6辺りで対応可能です。クライアント側は良く分かりませんが、Windows 10のEdgeやChromeとかは対応しているとか。基本、他のNWオプション(keepalive等)と同じように、アプリ側でsetsockoptで明示的に対応するか、OS側で強制的に対応するか、ということになります。
途中の経路にNATやFW、Transparent Proxy等が入っている場合、TFOで使っているSYN Cookieが上手く通らず、シーケンスが成立しない(通常のハンドシェイクになる)ことがあるようです。取り急ぎ私が使っている環境では、うまく通っているように見えます。
という訳で、適応。
このサーバーはCentOS 6+kernel-rt(3.10)なので、さくっとkernel optionですべて強制的に有効にしてみました。nginxをリコンパイルして、sockopt指定を有効化する方法もありますが(本当はこっちが良いと思うのですが)取り急ぎ、ということで。
適応前の状態を確認します。クライアントはこちらも、CentOS 7でTFOが有効化できる環境から確認します。
$ httping //blog.ayurina.net/ -c 10 round-trip min/avg/max = 74.4/118.1/164.5 ms round-trip min/avg/max = 82.3/116.2/169.2 ms
2回やってこれくらい。有効化してみます。
# echo 0x403 > /proc/sys/net/ipv4/tcp_fastopen # cat /proc/sys/net/ipv4/tcp_fastopen 1027
この、/proc/sys/net/ipv4/tcp_fastopenが有るか否かが、要するにkernelがTFOに対応しているか否かの判断材料になります。
フラグの意味については、kernel Document(/Documentation/networking/ip-sysctl.txt)にありますが、0x403は、
クライアントサイド・サーバーサイドとも強制的に(sockoptによらず)syn_cookieを有効化する設定になります。
nginxを再起動することで、サーバー設定を有効化します(bindしなおす必要がある)。
$ docker restart nginx.home
dockerになっているのはサーバー環境によるところですので、気にしない。これで有効化されたはずです。
再度、httpingを使って確認してみます。
$ httping //blog.ayurina.net/ -c 10 -F round-trip min/avg/max = 71.0/119.0/160.6 ms round-trip min/avg/max = 64.5/103.6/138.9 ms
まぁ、気持ち速くなった(苦笑)。実際、ローカルな環境等、ジッターの少ない環境で試験すると、もっと分かりやすい差が見えます。TFO凄い。
実際、TFOが有効化されているかどうかは、tcpdumpでパケットを見ても分かりますし(HTTPであれば、SYNパケットにリクエストメソッドが入っています)、httpingでも表示が変わります。
$ httping //blog.ayurina.net/ -c 5 -F PING blog.ayurina.net:80 (/): connected to 157.7.129.251:80 (368 bytes), seq=0 time= 63.05 ms F connected to 157.7.129.251:80 (368 bytes), seq=1 time=166.00 ms F connected to 157.7.129.251:80 (368 bytes), seq=2 time= 63.72 ms F connected to 157.7.129.251:80 (368 bytes), seq=3 time= 99.86 ms F connected to 157.7.129.251:80 (368 bytes), seq=4 time=107.53 ms F --- //blog.ayurina.net/ ping statistics --- 5 connects, 5 ok, 0.00% failed, time 5504ms round-trip min/avg/max = 63.1/100.0/166.0 ms
「F」が目印です。ちなみにTFOの仕様上、そのサーバーと通信する最初の1発目はそもそもCookieが無いのでTFOが成立しません。
体感的には・・・ちょっと速くなった気がします。気のせいかもしれません。そもそもhttpのkeep aliveも有効な環境で、TCPのセットアップシーケンスがどれくらい効くか、と冷静に考えると微妙なんですが、ブラウザ等の環境がこれから対応してくることを考えると、対応しておいて悪くはないかな、という感じです。HTTPのみならず、その他のTCPもすべて有効化される(有効化しようとする)ので、もしかしたら差が出てくることもあるかな、と期待しています。
ちなみに、netstat -sでFastOpenの件数が見えたりするんですが、CentOS 6+kernel-rtのような環境だと、そもそもnetstatのほうが対応していなくて見えなかったりして残念。どこかスペシャルデバイスに統計ありそうな気もします。CentOS 7環境なら、問題なく確認できます。
Webp
iOSのChromeでブログ見てたら、なんだかサムネイルが一部表示されていないことに気づきました。URLを見てみると、pagespeedがwebp形式にコンバートしたものが表示されていません。バグなのか何なのか分かりませんが、なんでChromeで表示できないの、って感じ。Safariでは表示できるのに・・・・
というわけで、pagespeedモジュールのデフォルトで有効化されているwebpフィルタを無効化して正しく表示されるようにしました。
ModPagespeedDisableFilters convert_jpeg_to_webp,convert_to_webp_lossless
ngx_pagespeedだと「pagespeed」接頭辞が必要ですので念のため。無事サムネイルも表示されるようになりました(※2016/9/4追記:当初「convert_jpeg_to_webp」だけ指定していましたが、「convert_to_webp_lossless」も必要なようです)。
しかしなぜChromeでダメなんだろう・・・Webp自体が、Google発祥なんですがねぇ。
サーバーが速いことは良いことだ
やっぱりWebサーバーはスピード命ですね。速いことは良いことだ。でもいい加減、CentOS 7にしないといかんよなぁ、と思いつつ・・・思い切ってCoreOSでも良いか。
そんな中、現在このサーバーを構成しているdockerコンテナたちをdocker-compose管理に移行することを計画中です。今は、Dockerfileがgithub管理になったところです。
サーバーインフラは楽しいです。
コメント