2006年04月03日 - mod_perl
mod_perl
しばらく追いかけるのをやめているうちにmod_perlはどんどん安定化し、かなり使えるものとなってしまっているようなので(おそい!)使ってみる。- BOX: AMD Opteron 1.6GHz x 2, 1GB RAM
- OS: FreeBSD 7.0-CURRENT #2: Thu Mar 23 12:41:17 JST 2006
- Apache httpd: 半年ぐらい前のHEADなやつかもしくは2.0.55などのGA、MPMはworker
- perl: perl 5.8.8
$ svn checkout https://svn.apache.org/repos/asf/perl/modperl/trunk/ mod_perl-2.0
$ cd mod_perl-2.0
$ perl Makefile.PL MP_APXS=/home/apache/bin/apxs
Reading Makefile.PL args from @ARGV
MP_APXS = /home/apache/bin/apxs
no conflicting prior mod_perl version found - good.
Configuring Apache/2.3.0-dev mod_perl/2.0.3-dev Perl/v5.8.8
・・・・・
・・・・・
$ make && make test
$ sudo make install
httpd.confに
LoadModule perl_module modules/mod_perl.so
と書いて基本的な設定はおわり。
いきなりモジュールを書くのもアレなので、とりあえずApache httpdに付属のprintenvをModPerl::Registryで動かしてみる。
PerlModule ModPerl::Registry
Alias /perl /home/apache/perl
<Location /perl>
SetHandler perl-script
PerlResponseHandler ModPerl::Registry
Options +ExecCGI
</Location>
と書いてhttpdをrestartして、/home/apache/perlにprintenvを置いてアクセス。をを!動いている(あたりまえ)。
mod_perlなので速いはず、ということで、フツーのCGIとして動くprintenvと比べてみると・・・
いい加減な計測だけど相対的な違いは明らか。かなり速い。安定して動くのならいいなあ。
This is ApacheBench, Version 2.0.41-dev <$Revision: 1.121.2.12 $> apache-2.0
Copyright (c) 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Copyright (c) 1998-2002 The Apache Software Foundation, http://www.apache.org/
Benchmarking foo.imgsrc.co.jp (be patient).....done
Server Software: Apache/2.3.0-dev
Server Hostname: foo.imgsrc.co.jp
Server Port: 80
Document Path: /perl/printenv
Document Length: 1115 bytes
Concurrency Level: 1
Time taken for tests: 0.166764 seconds
Complete requests: 50
Failed requests: 0
Write errors: 0
Total transferred: 65250 bytes
HTML transferred: 55750 bytes
Requests per second: 299.82 [#/sec] (mean)
Time per request: 3.335 [ms] (mean)
Time per request: 3.335 [ms] (mean, across all concurrent requests)
Transfer rate: 377.78 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 0.0 0 0
Processing: 3 3 0.0 3 3
Waiting: 2 2 0.7 2 3
Total: 3 3 0.0 3 3
Percentage of the requests served within a certain time (ms)
50% 3
66% 3
75% 3
80% 3
90% 3
95% 3
98% 3
99% 3
100% 3 (longest request)
This is ApacheBench, Version 2.0.41-dev <$Revision: 1.121.2.12 $> apache-2.0
Copyright (c) 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Copyright (c) 1998-2002 The Apache Software Foundation, http://www.apache.org/
Benchmarking foo.imgsrc.co.jp (be patient).....done
Server Software: Apache/2.3.0-dev
Server Hostname: foo.imgsrc.co.jp
Server Port: 80
Document Path: /cgi-bin/printenv
Document Length: 1044 bytes
Concurrency Level: 1
Time taken for tests: 3.622623 seconds
Complete requests: 50
Failed requests: 0
Write errors: 0
Total transferred: 61700 bytes
HTML transferred: 52200 bytes
Requests per second: 13.80 [#/sec] (mean)
Time per request: 72.452 [ms] (mean)
Time per request: 72.452 [ms] (mean, across all concurrent requests)
Transfer rate: 16.56 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 1.5 0 8
Processing: 69 71 1.3 71 76
Waiting: 68 70 1.4 70 76
Total: 69 71 2.2 71 81
Percentage of the requests served within a certain time (ms)
50% 71
66% 72
75% 72
80% 72
90% 74
95% 76
98% 81
99% 81
100% 81 (longest request)
2006年03月31日 - apr
mod_dbd
apache 2.2の新機能にSQL Database Supportつーのがある。RDBMSとの接続をhttpdがプールしておき、モジュールやCGIプログラムは接続をもらって利用することができるようになる。はず。 ということなので、とりあえずそのへんで遊んでみることに。- OS: FreeBSD 7.0-CURRENT #2: Thu Mar 23 12:41:17 JST 2006
- RDBMS: PostgreSQL 8.1.3 (/home/pgsql81にインストール)
- httpd, apr, apr-utilはHEADなもの
$ configure --help
`configure' configures this package to adapt to many kinds of systems.
Usage: ./configure [OPTION]... [VAR=VALUE]...
・・・・・・・・
・・・・・・・・
--with-pgsql=DIR specify PostgreSQL location
--with-mysql=DIR **** SEE INSTALL.MySQL ****
--with-sqlite3=DIR
--with-sqlite2=DIR
--with-oracle=DIR specify ORACLE_HOME location
とある。ここで使いたいRDBMSを指定するのね。
$ ./configure --prefix=/home/apache-trunk --with-apr=/home/apache-trunk --with-pgsql=/home/pgsql81 \
--target=x86_64--freebsd7.0
・・・・・・・・
configure: checking for pgsql in /home/pgsql81
checking libpq-fe.h usability... yes
checking libpq-fe.h presence... yes
checking for libpq-fe.h... yes
checking for PQsendQueryPrepared in -lpq... yes
setting APRUTIL_LDFLAGS to "-L/home/pgsql81/lib"
setting APRUTIL_INCLUDES to "-I/home/pgsql81/include"
setting APRUTIL_EXPORT_LIBS to "-lpq"
setting APRUTIL_LIBS to "-lpq"
・・・・・・・・
$ make && sudo make install
あとはhttpdをフツーにconfigureすれば
$ ./configure --prefix=/home/apache-trunk --with-apr=/home/apache-trunk \
--with-apr-util=/home/apache-trunk --with-mpm=worker --enable-so --with-port=80 \
--enable-mods-shared="all ssl rewrite info usertrack unique-id" --build=amd64--freebsd7.0
・・・・・・・・
checking for APR-util... yes
adding "-L/home/pgsql81/lib" to LDFLAGS
・・・・・・・・
$
と、PostgreSQLのライブラリがあるディレクトリがLDFLAGSに追加される。makeしてmake installしておわり。
たしかにlibpqがリンクされている:
$ ldd /home/apache-trunk/bin/httpd
/home/apache-trunk/bin/httpd:
libm.so.4 => /lib/libm.so.4 (0x80068f000)
libaprutil-1.so.3 => /home/apache-trunk/lib/libaprutil-1.so.3 (0x8007ab000)
libpq.so.4 => /home/pgsql81/lib/libpq.so.4 (0x8008c6000)
libexpat.so.6 => /usr/local/lib/libexpat.so.6 (0x8009e2000)
libapr-1.so.3 => /home/apache-trunk/lib/libapr-1.so.3 (0x800b04000)
libcrypt.so.3 => /lib/libcrypt.so.3 (0x800c2b000)
libpthread.so.2 => /usr/lib/libpthread.so.2 (0x800d44000)
libc.so.6 => /lib/libc.so.6 (0x800e70000)
$
mod_dbdのマニュアルを読むと、データベースドライバーを指定するディレクティブはDBDriver、接続時に必要なパラメータ(データベース名とかユーザ名、パスワードなど)DBDParamsで指定するようなので、httpd.confに
LoadModule dbd_module modules/mod_dbd.so
<IfModule dbd_module>
DBDriver pgsql
DBDParams dbname=postgres,user=pgsql
</IfModule>
と書いてapacheを動かしてみる。
$ sudo /home/apache-trunk/bin/apachectl start
$
ぜんぜん問題なく動いた。ように見えただけ、実は:
tail /home/apache-trunk/logs/error_log
[Fri Mar 31 17:50:39 2006] [notice] Apache/2.3.0-dev (Unix) mod_ssl/2.3.0-dev OpenSSL/0.9.7e DAV/2 configured
[Fri Mar 31 17:50:39 2006] [crit] (20014)Internal error: DBD: Can't connect to pgsql
[Fri Mar 31 17:50:39 2006] [crit] (20014)Internal error: DBD: failed to initialise
[Fri Mar 31 17:50:39 2006] [crit] (20014)Internal error: DBD: Can't connect to pgsql
[Fri Mar 31 17:50:39 2006] [crit] (20014)Internal error: DBD: failed to initialise
mod_dbdさんがエラー出してる。pgsqlに接続できない、と言っているということは、DBDriverディレクティブはたぶんうまく効いているということ。じゃあDBDParamsが悪いのだろうか? マニュアルには、
DBDParams param1=value1[,param2=value2]
と書いてあるので特に問題はなさそう。うーん・・・ソースを見てみますか。httpd-trunk/modules/database/mod_dbd.cのdbd_construct関数の中の
rv = apr_dbd_open(rec->driver, rec->pool, svr->params, &rec->handle);
switch (rv) {
case APR_EGENERAL:
ap_log_perror(APLOG_MARK, APLOG_CRIT, rv, rec->pool,
"DBD: Can't connect to %s", svr->name);
return rv;
default:
ap_log_perror(APLOG_MARK, APLOG_CRIT, rv, rec->pool,
"DBD: mod_dbd not compatible with apr in open");
return rv;
case APR_SUCCESS:
break;
}
というあたりがそれっぽい。apr_dbd_openはapr-utilの関数なので、srclib/apr-util/dbd/apr_dbd.cを見てみると
APU_DECLARE(apr_status_t) apr_dbd_open(const apr_dbd_driver_t *driver,
apr_pool_t *pool, const char *params,
apr_dbd_t **handle)
{
apr_status_t rv;
*handle = driver->open(pool, params);
if (*handle == NULL) {
return APR_EGENERAL;
}
rv = apr_dbd_check_conn(driver, pool, *handle);
if ((rv != APR_SUCCESS) && (rv != APR_ENOTIMPL)) {
apr_dbd_close(driver, *handle);
return APR_EGENERAL;
}
return APR_SUCCESS;
}
単に引数で与えられたdriverのオープン関数を呼んでるだけ。ということでドライバーであるsrclib/apr-util/dbd/apr_dbd_pgsql.cを見てみる
static apr_dbd_t *dbd_pgsql_open(apr_pool_t *pool, const char *params)
{
apr_dbd_t *sql;
PGconn *conn = PQconnectdb(params);
/* if there's an error in the connect string or something we get
* back a * bogus connection object, and things like PQreset are
* liable to segfault, so just close it out now. it would be nice
* if we could give an indication of why we failed to connect... */
if (PQstatus(conn) != CONNECTION_OK) {
PQfinish(conn);
return NULL;
}
sql = apr_pcalloc (pool, sizeof (*sql));
sql->conn = conn;
return sql;
}
ななな、なんと! paramsをPQconnectdbにそのまま渡しているだけ。PQconnectdbの使い方は、マニュアルによると
The passed string can be empty to use all default parameters, or it can contain one or more parameter
settings separated by whitespace.
つまり、「key=value」なやつをホワイトスペースで区切って並べる。ってことは、httpd.confでDBDParamsの値を「dbname=postgres,user=pgsql」としたのは間違いで
DBDParams "dbname=postgresql user=pgsql"
とすればいいのかな? これでhttpdを動かしてみたところ、
$ tail /home/apache-trunk/logs/error_log
[Fri Mar 31 18:38:58 2006] [notice] Digest: generating secret for digest authentication ...
[Fri Mar 31 18:38:58 2006] [notice] Digest: done
[Fri Mar 31 18:38:58 2006] [notice] Apache/2.3.0-dev (Unix) mod_ssl/2.3.0-dev OpenSSL/0.9.7e DAV/2
$
エラーは出なくなった。実際、
$ scokstat
pgsql postgres 48557 7 stream /tmp/.s.PGSQL.5432
pgsql postgres 48556 7 stream /tmp/.s.PGSQL.5432
www httpd 48555 13 stream -> /tmp/.s.PGSQL.5432
www httpd 48554 13 stream -> /tmp/.s.PGSQL.5432
と、繋がってるもよう。うまくいったなあ。でもmod_dbdのマニュアルは間違いだろう? もしくは、apr_dbd_pgsql.cがサボりすぎか? 他のデータベースドライバーの場合はDBDParamsの値をパースしてそれなりなことをやっているようなので、やっぱりapr_dbd_pgsql.cはサボりすぎだろう。あとでパッチ作って送るかな。