ブログサーバー改善。TCP Fast Openを有効化して、Webpを無効化して。

Linux

いい加減CentOS 7にしないと思っているこのブログサーバーですが、本日またちょっと改善しました。TCP Fast Open(TFO)に対応させたのと、一部表示に不具合のあったWebp対応を無効化しました。

サーバーは速いに越したことはないです。

TCP Fast Open

何を今更、という感じが無くも無いですが、フラフラとネット見てたら、なんか見つけたんですよね。

マイクロソフト、より高速な「TCP Fast Open」など採用へ、Windows 10の大型アップデートとWindows Server 2016で - Publickey
どうやらこのTFO、理屈からしてもかなり速くなりそうで、かつ、影響も少なそう、ということで、軽く検証しつつ、サーバーに適応してみました。ちなみに、RFCはこちら。

https://tools.ietf.org/html/rfc7413

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管理になったところです。

サーバーインフラは楽しいです。

コメント

タイトルとURLをコピーしました