SSLの導入

まず、サーバにOpenSSLが入っていることを確認します。

Debian

秘密鍵とCSR

まず秘密鍵の作成です。秘密鍵にパスフレーズを設定できますが、設定するとサーバの起動ごとにパスフレーズの入力が必要になるようです(未確認)。
一つ目のコマンドで秘密鍵を生成し、二つ目のコマンドはCSR(署名要求)で、公開鍵に対する署名を証明書の発行会社に要求します。
ここでは、256bit AESの強力な暗号を利用します。

$ openssl genrsa -out private-mlssl-2011.pem 2048 -aes256
$ openssl req -new -key private-mlssl-2011.pem -out csr-mlssl-2011.pem

これによって生成したCSRを証明書の発行会社に送ります。数日で中間証明書と証明書が来ます。それをApacheの設定で読み込ませ、サーバーをリスタートさせます。
CSRのファイルをなくしても秘密鍵からCSRを作成できますが、秘密鍵をなくしてしまうとSSL通信もできないばかりか、CSRも作成できなくなります。
Cf. https://www.verisign.co.jp/ssl/help/csr/capache_new.html

サーバの設定

# vim /etc/apache2/sites-available/default-ssl
# 証明書
SSLCertificateFile    /etc/ssl/certs/missinglink-ssl-cert2011
# 秘密鍵
SSLCertificateKeyFile /etc/ssl/private/private-mlssl-2011.pem
# 中間証明書
SSLCertificateChainFile /etc/apache2/ssl.crt/mlssl-ca.crt

変更点はこれだけでした。この設定をバーチャルホストごとに行います。

CentOS

# yum -y install mod_ssl

で、/etc/httpd/conf.d/ssl.confをDebianのApacheに対して行ったように変更します。

Google ChromeのSame Origin Policyを無効化する

開発などで、JavaScript/XHR(XMLHttpRequest)のセキュリティのために実装されているSame-origin Policyを無効にしたい場合があります。
OSXではターミナルで以下のようにChromeを起動させます。

open -a Google\ Chrome --args --disable-web-security

Windowsではコマンドプロンプトで以下のようにします。

chrome.exe --disable-web-security

ローカルのファイルへXHRをしたい場合は以下の引数も追加します。

-–allow-file-access-from-files

Luaでサーバサイドつくったら速いと思う(1)

Apache 2.4からmod_luaというLua言語のモジュールが組み込まれるようです。Lua言語は型がないLightweight Languageでは最速で、素のRubyやPython、Perlはとうてい敵いません。

これは1から100万までの数に対して素数判定(試し割りアルゴリズム)を行ったものです。Perlの3倍の速度です。

  • http://shootout.alioth.debian.org/
  • http://attractivechaos.github.com/plb/

また、上に示したURLの各種ベンチマークでも、LuaはLLのなかで最速です。

最速を誇っていながらも言語仕様は小さく、そのtar.gzアーカイブは200KBちょっとしかありません。

そんなLuaはC言語と連携しながら組み込み用言語として使われたりしています(マニアックな話ですが、ヤマハ製のルータRTX1200などにも組み込まれています。欲しいなぁ)。

Lua vs Perl (vs PHP)

そこで、CGIとしてLuaとPerlのパフォーマンス比較をしてみました。ただし、単純なコードで、渡されたクエリ文字列を返すだけの簡単なコードです。

Perl 高速化(mod_perl)無し 191.28 req/sec

keiya@s002:~$ ab -c 10 -n 1000 http://192.168.24.170/~keiya/run.pl
This is ApacheBench, Version 2.3 <$Revision: 655654 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking 192.168.24.170 (be patient)
Completed 100 requests
Completed 200 requests
Completed 300 requests
Completed 400 requests
Completed 500 requests
Completed 600 requests
Completed 700 requests
Completed 800 requests
Completed 900 requests
Completed 1000 requests
Finished 1000 requests

Server Software:        Apache/2.2.19
Server Hostname:        192.168.24.170
Server Port:            80

Document Path:          /~keiya/run.pl
Document Length:        1 bytes

Concurrency Level:      10
Time taken for tests:   5.228 seconds
Complete requests:      1000
Failed requests:        0
Write errors:           0
Total transferred:      167340 bytes
HTML transferred:       1000 bytes
Requests per second:    191.28 [#/sec] (mean)
Time per request:       52.279 [ms] (mean)
Time per request:       5.228 [ms] (mean, across all concurrent requests)
Transfer rate:          31.26 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.1      0       1
Processing:    22   52   9.4     51      96
Waiting:       22   52   9.4     51      95
Total:         23   52   9.4     51      96

Percentage of the requests served within a certain time (ms)
  50%     51
  66%     54
  75%     56
  80%     58
  90%     64
  95%     69
  98%     78
  99%     82
 100%     96 (longest request)

Lua 高速化無し 396.88 req/sec

keiya@s002:~$ ab -c 10 -n 1000 http://192.168.24.170/~keiya/run.lua
This is ApacheBench, Version 2.3 <$Revision: 655654 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking 192.168.24.170 (be patient)
Completed 100 requests
Completed 200 requests
Completed 300 requests
Completed 400 requests
Completed 500 requests
Completed 600 requests
Completed 700 requests
Completed 800 requests
Completed 900 requests
Completed 1000 requests
Finished 1000 requests

Server Software:        Apache/2.2.19
Server Hostname:        192.168.24.170
Server Port:            80

Document Path:          /~keiya/run.lua
Document Length:        5 bytes

Concurrency Level:      10
Time taken for tests:   2.520 seconds
Complete requests:      1000
Failed requests:        0
Write errors:           0
Total transferred:      172233 bytes
HTML transferred:       5000 bytes
Requests per second:    396.88 [#/sec] (mean)
Time per request:       25.196 [ms] (mean)
Time per request:       2.520 [ms] (mean, across all concurrent requests)
Transfer rate:          66.75 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.1      0       1
Processing:     8   25  14.3     22     118
Waiting:        7   25  14.0     21     117
Total:          8   25  14.3     22     118

Percentage of the requests served within a certain time (ms)
  50%     22
  66%     25
  75%     27
  80%     29
  90%     39
  95%     49
  98%     75
  99%     95
 100%    118 (longest request)

この結果が示す時間の大部分は、それぞれの言語のインタプリタ起動にかかる時間が占めていると思われます。この結果と各種ベンチマーク結果を総合すると、Luaインタプリタの起動にかかる時間も、実行速度も速いといえそうです。

php 標準モジュール (php5_module) 2297.63 req/sec

ここでPHPのベンチマークです。

keiya@s002:~$ ab -c 10 -n 1000 http://192.168.24.170/~keiya/run.php?test=hoge
This is ApacheBench, Version 2.3
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking 192.168.24.170 (be patient)
Completed 100 requests
Completed 200 requests
Completed 300 requests
Completed 400 requests
Completed 500 requests
Completed 600 requests
Completed 700 requests
Completed 800 requests
Completed 900 requests
Completed 1000 requests
Finished 1000 requests

Server Software:        Apache/2.2.19
Server Hostname:        192.168.24.170
Server Port:            80

Document Path:          /~keiya/run.php?test=hoge
Document Length:        5 bytes

Concurrency Level:      10
Time taken for tests:   0.435 seconds
Complete requests:      1000
Failed requests:        0
Write errors:           0
Total transferred:      214000 bytes
HTML transferred:       5000 bytes
Requests per second:    2297.63 [#/sec] (mean)
Time per request:       4.352 [ms] (mean)
Time per request:       0.435 [ms] (mean, across all concurrent requests)
Transfer rate:          480.17 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.1      0       1
Processing:     1    4   4.5      3      51
Waiting:        1    4   4.4      3      51
Total:          1    4   4.5      3      51

Percentage of the requests served within a certain time (ms)
  50%      3
  66%      4
  75%      5
  80%      5
  90%      8
  95%     12
  98%     20
  99%     26
 100%     51 (longest request)

お話にならないほど高速です。これは、Apacheの中にPHPのモジュールが組み込まれているからです。

僕はPerlerですし、負けていられないので同じ条件で計測します。Apacheにmod_perlを組み込み、バイトコードのキャッシュにより高速化を図ります。

Perl mod_perl2 3136.54 req/sec

keiya@s002:~$ ab -c 10 -n 1000 http://192.168.24.170/perl/run.pl?test=hoge
This is ApacheBench, Version 2.3
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking 192.168.24.170 (be patient)
Completed 100 requests
Completed 200 requests
Completed 300 requests
Completed 400 requests
Completed 500 requests
Completed 600 requests
Completed 700 requests
Completed 800 requests
Completed 900 requests
Completed 1000 requests
Finished 1000 requests

Server Software:        Apache/2.2.19
Server Hostname:        192.168.24.170
Server Port:            80

Document Path:          /perl/run.pl?test=hoge
Document Length:        9 bytes

Concurrency Level:      10
Time taken for tests:   0.319 seconds
Complete requests:      1000
Failed requests:        0
Write errors:           0
Total transferred:      216000 bytes
HTML transferred:       9000 bytes
Requests per second:    3136.54 [#/sec] (mean)
Time per request:       3.188 [ms] (mean)
Time per request:       0.319 [ms] (mean, across all concurrent requests)
Transfer rate:          661.61 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.1      0       0
Processing:     1    3   1.1      3       8
Waiting:        1    3   1.1      2       8
Total:          2    3   1.1      3       8

Percentage of the requests served within a certain time (ms)
  50%      3
  66%      3
  75%      3
  80%      4
  90%      5
  95%      6
  98%      7
  99%      7
 100%      8 (longest request)

かなり高速で勝者です。とはいってもPHPは所詮標準モジュールですので、PHPアクセラレータなどを入れるとこのPerlといい勝負ができると思います。

ところで、Luaの組み込みの結果に関してはApache 2.4待ちとなります。とはいってもApache 2.3 betaがあるので、それで試してみようかなと考えています。次回にでも・・・

もしLuaモジュールの実装がちゃんとしていれば、上に書いた言語のベンチマークから考えて、PerlやPHPやその他のLLをぶっちぎって最速になるんじゃないかと考えられます。

LuaRocksというPerlでいうCPAN、PHPでいうPEARのようなライブラリアーカイブも存在します。

LuaJITというやたら速い実装もあり、JavaScriptのV8といい勝負をしています。

まぁ、世の中node.jsヤベーとかいろいろいわれていますが、ApacheにLuaモジュールが組み込まれたらそれはそれで速度的にヤベーと思います。Apacheもevent mpmでイベントドリブンのプロセス・モデルがありますし。

速度を求めるならJava Servlet使え、とかいわれそうですが:p