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
threadedなMPMなapacheに組み込む場合、当然だろうけどperlもthreadedにしないといけないので、そうでない場合はthreadedなperlを入れる。FreeBSDでportで入れる場合はWITH_THREADSでmake。で、mod_perlのソースを取ってきてビルド。Apache httpdはHEADなやつだとauthまわりでごちゃごちゃしてるのでmakeできないもよう。日々失敗する箇所が変っているのでいじってる最中かも? たまたま半年ぐらい前のHEADなやつがあったのでそれで試してみたらmakeはできた。
$ 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)
posted at 13:56 | permalink | Comments (0) | TrackBack (0)

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なもの
HEADなhttpdのビルドをした時にPostgreSQLとのリンクなんかもできてるのかなと思ったらそうでもないようだ。PostgreSQLは諸事情で8.0.3のクライアントをportでインストールしてあり、/usr/local/lib/libpsq.soとかあるので勝手にそれを使ってくれても良さそうなのだが使ってくれてないみたい。mod_dbdはapr-util/dbd/ 以下にあるものを利用するので、そのあたりからやり直し。apr-utilのconfigureのオプションを見てみると
$ 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はサボりすぎだろう。あとでパッチ作って送るかな。
posted at 13:58 | permalink | Comments (0) | TrackBack (0)