H2Oの勉強がてらブログのアーキテクチャをApache + mod_phpからH2O + php-fpmの構成に変えてみました。ということで今回は移行に関する備忘録。
移行前の構成
- OS: CentOS 6.7
- Apache:
- Version: 2.2.15 (Unix)
- MPM: Prefork
- PHP: 5.6
IPA 独立行政法人 情報処理推進機構:ウェブサーバ「Apache HTTP Server」の脆弱性(CVE-2011-3192)について
H2Oのインストール
rpmのものをインストールします。以下のリポジトリを追加。
$ sudo vim /etc/yum.repos.d/intray-tatsushid-h2o-rpm.repo
#bintray-tatsushid-h2o-rpm - packages by tatsushid from Bintray
[bintray-tatsushid-h2o-rpm]
name=bintray-tatsushid-h2o-rpm
#If your system is CentOS
baseurl=https://dl.bintray.com/tatsushid/h2o-rpm/centos/$releasever/$basearch/
#If your system is Fedora
#baseurl=https://dl.bintray.com/tatsushid/h2o-rpm/fedora/$releasever/$basearch/
gpgcheck=0
repo_gpgcheck=0
enabled=1
で以下インストール
$ sudo yum install h2o
旧構成のApacheのhtaccessの設定
Redirect permanent /blog/aws/671/ http://freedom-man.com/blog/swf_using_apex_2/
Redirect permanent /blog/aws/652/ http://freedom-man.com/blog/swf_using_apex/
...
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /blog/
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{HTTPS} on
RewriteRule . http://%{HTTP_HOST}%{REQUEST_URI} [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{HTTPS} off
RewriteRule . /blog/index.php [L]
</IfModule>
基本的に以下の目的を達成するために記載しています。
- 旧パスでのアクセスは新パス(パーマリンク)にリダイレクトされる
- HTTPSでのアクセスはHTTPにリダイレクトされる。
- HTTPでのアクセスは/blog/index.phpに内部リダイレクトされる
H2Oの設定
ということで、/etc/h2o/h2o.confは以下の通りuser: nobody
file.custom-handler:
extension: .php
fastcgi.connect:
port: /var/run/php-fpm/php-fpm.sock
type: unix
compress: ON
file.index: [ 'index.html', 'index.htm', 'index.txt', 'index.php' ]
hosts:
"freedom-man.com:443":
listen:
port: 443
host: 0.0.0.0
ssl:
certificate-file: "/path/to/server.crt"
key-file: "/path/to/server.key"
paths:
"/":
redirect:
status: 301
url: /blog
"/blog":
mruby.handler-file: /etc/h2o/handler.rb
file.dir: /path/to/wordpress
redirect:
url: /blog/index.php/
internal: YES
status: 307
"freedom-man.com:80":
listen:
port: 80
host: 0.0.0.0
paths:
"/":
redirect:
status: 301
url: "https://freedom-man.com/"
access-log: /var/log/h2o/access.log
error-log: /var/log/h2o/error.log
pid-file: /var/run/h2o/h2o.pid
handler.rb
Proc.new do |env|
headers = {}
if /\.(css|js|png|jpg|jpeg|gif)\z/.match(env["PATH_INFO"])
headers["cache-control"] = "max-age=86400"
end
[399, headers, []]
end
php-fpmのインストール&設定
phpは5.6を利用$ sudo rpm -Uvh https://mirror.webtatic.com/yum/el6/latest.rpm
$ sudo rpm -Uvh http://dl.fedoraproject.org/pub/epel/6/i386/epel-release-6-8.noarch.rpm
$ cd /etc/yum.repos.d
$ sudo curl -O http://rpms.famillecollet.com/enterprise/remi.repo
$ sudo yum install php-fpm -y --enablerepo=remi-php56
/etc/php-fpm.d/www.confではlistenポートをUNIXドメインソケットに変更してます。
; listen = 127.0.0.1:9000
listen = /var/run/php-fpm/php-fpm.sock
listen.owner = nobody
listen.group = nobody
listen.mode = 0660
WordPressの設定
設定>一般から、WordPressアドレスとサイトアドレスのURLをhttpsにします。さらに、SearchRegexのプラグインを入れて、http://{Domain}になっている部分を一括置換します。
ブラウザでの確認
Apacheだとロードはこんな感じ。同時接続数6が効いちゃってます。h2oだとロードはこんな感じ。HTTP/2が効いて同時リクエストをしているのが確認できます。
ベンチマーク
wrkでベンチマークをとってみました。Apacheは以下のような設定です。StartServers 50
MinSpareServers 50
MaxSpareServers 100
ServerLimit 200
MaxClients 100
MaxRequestsPerChild 4000
Apache: php+内部リダイレクトなパーマリンクページ
$ wrk -c 50 -d 1m -t 10 http://freedom-man.com/blog/h2o-http2/
Running 1m test @ http://freedom-man.com/blog/h2o-http2/
10 threads and 50 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 1.64s 355.70ms 1.99s 91.67%
Req/Sec 2.75 4.00 19.00 81.97%
441 requests in 1.00m, 23.05MB read
Socket errors: connect 0, read 20, write 0, timeout 417
Non-2xx or 3xx responses: 20
Requests/sec: 7.34
Transfer/sec: 393.04KB
Apache: 静的ページ
$ wrk -c 50 -d 1m -t 10 http://freedom-man.com/blog/wp-content/plugins/yet-another-related-posts-plugin/style/widget.css\?ver\=4.6.1
Running 1m test @ http://freedom-man.com/blog/wp-content/plugins/yet-another-related-posts-plugin/style/widget.css?ver=4.6.1
10 threads and 50 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 133.90ms 84.46ms 1.53s 88.11%
Req/Sec 29.32 16.66 100.00 59.52%
14504 requests in 1.00m, 13.68MB read
Socket errors: connect 0, read 27, write 0, timeout 56
Non-2xx or 3xx responses: 25
Requests/sec: 241.34
Transfer/sec: 233.01KB
続いてはH2O。
H2O: php+内部リダイレクトなパーマリンクページ
$ wrk -c 50 -d 1m -t 10 /h2o-http2/
Running 1m test @ /h2o-http2/
10 threads and 50 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 695.26ms 437.10ms 2.00s 66.79%
Req/Sec 5.22 5.70 40.00 94.23%
571 requests in 1.00m, 27.08MB read
Socket errors: connect 139, read 25, write 0, timeout 23
Non-2xx or 3xx responses: 76
Requests/sec: 9.50
Transfer/sec: 461.38KB
H2O: 静的ページ
$ wrk -c 50 -d 1m -t 10 /wp-content/plugins/yet-another-related-posts-plugin/style/widget.css\?ver\=4.6.1
Running 1m test @ /wp-content/plugins/yet-another-related-posts-plugin/style/widget.css?ver=4.6.1
10 threads and 50 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 56.41ms 37.84ms 707.37ms 93.00%
Req/Sec 33.99 17.11 110.00 76.98%
17579 requests in 1.00m, 17.35MB read
Socket errors: connect 174, read 0, write 0, timeout 0
Requests/sec: 292.52
Transfer/sec: 295.66KB
平均的に良くなっている感じです。
ちなみにApacheの方でKeepAlive Offにすると激遅で、静的ページすらスループットが出ずという結果でした。3way handshakeのオーバーヘッド恐るべし。
ハマりどころ
H2OでHTTPSでアクセスしているのにChrome Developer ToolでProtocolがHTTP/1.1のまま変わらず…。AVAST!のSSLインタラプトして内容を解析する機能が原因でした。以下のようにチェックを外せばOK。