4月 14th, 2010
Apache2.2系のうち、2.2.11以? のバージョンでは、2つ以上のポートをListenしマルチプロセス? prefork)で? 行している場合に「graceful」「graceful-stop」が正常に動作しないというバグがありました。( https://issues.apache.org/bugzilla/show_bug.cgi?id=42829 )psコマンドぜ httpdプロセスを監? していると「graceful」を実行した瞬間、子プロセスが<defunct>に? 瞬で? ゜ るのが確? できます。このバグは、2.2.12でフィックスしたぜ CHANGELOGに? されています。
*) prefork: Fix child process hang during graceful restart/stop in
configurations with multiple listening sockets. PR 42829. [JoeOrton,
Jeff Trawick]
更ぜ Apache2.2.15をインストールする機会があったので「graceful」を実行してみたところ、2.2.11以? のバージョンと同様に以下のようにエラーログ出力することが゜ かりました。
[error] (9)Bad file descriptor: apr_socket_accept: (client socket)
出力頻度ぜ 2.2.11以? のバグのように常に出力する゜ けではなぜ 、5回ぜ 1回のペースぐらいに朸 っている印象でした。子プロセス数? StartServers)を1に設定し、gdbで圭 プロセスにアタッチしたところ以? の部分までトレースできました。
Program received signal SIGUSR1, User defined signal 1.
[Switching to Thread 46912524354064 (LWP 29198)]
0x00002aaaac315763 in __epoll_wait_nocancel () from /lib64/libc.so.6
(gdb) cont
Continuing.
(gdb) where
#0 log_error_core (file=0x5555555ba00b "unixd.c", line=636, level=3,
status=9, s=0x555562dfa860, c=0x0, r=0x0,
pool=0x0, fmt=0x5555555ba408 "apr_socket_accept: (client socket)",
args=0x7fffdca5ded0)
at log.c:519
#1 0x000055555559b4fb in ap_log_error (file=0x5555555ba00b "unixd.c",
line=636, level=3, status=9, s=0x555562dfa860,
fmt=0x5555555ba408 "apr_socket_accept: (client socket)")
at log.c:715
#2 0x00005555555b0e0b in unixd_accept (accepted=0x7fffdca5e040,
lr=0x555562df1b40, ptrans=0x555562f2db58)
at unixd.c:636
#3 0x00005555555ae82e in child_main (child_num_arg=0)
at prefork.c:643
#4 0x00005555555aea6f in make_child (s=0x555562dfa860, slot=0)
at prefork.c:758
#5 0x00005555555af1ad in ap_mpm_run (_pconf=0x555562df3138,
plog=0x555562e252c8, s=0x555562dfa860)
at prefork.c:1058
#6 0x000055555557b7bf in main (argc=8, argv=0x7fffdca5e368)
at main.c:740
01 server/main.c
02 main()
03 server/mpm/prefork/prefork.c
04 ap_mpm_run()
05 make_child()
06 child_main()
07 status = lr->accept_func(&csd, lr, ptrans);
08 os/unix/unixd.c
09 unixd_accept()
10 status = apr_socket_accept(&csd, lr->sd, ptrans);
11 srclib/apr/network_io/unix/sockets.c
12 apr_socket_accept()
13 s = accept(sock->socketdes,
(struct sockaddr *)&sa.sa, &sa.salen);
14 os/unix/unixd.c
15 unixd_accept()
16 ap_log_error(APLOG_MARK, APLOG_ERR, status,
ap_server_conf,"apr_socket_accept: (client socket)");
07行目ぜ lr->accept_func関数のエラー? socket関数がディスクリプタ? ? “EBADF”を返す)を元にエラーボ ンドリングされてログ出力されていますが、graceful処理の場合はこの時点ですでにソケットが閉じられていますのぜ accept出来ません。
この問題は、以? のように新たなバグとして登録されています。パッチではソケットがアクティブでなければ? !lr->active)、Errorレベルのログではなぜ 、Debugレベルのログとして出力されるように修正しているようです。(2010? 4月14日現在?
https://issues.apache.org/bugzilla/show_bug.cgi?id=42829
4月 5th, 2010
Apacheのディレクティブぜ EnableSendfileというものがある。これはファイル・ディスクリプタ間のデータコピーシステムコールであるsendfileを、httpdが使用するかどうかを制御するものです。パフォーマンス? の利点について、Apacheドキュメントぜ Linux manページを抜粋しました。
Apache2.2のドキュメントより
例えば静的なファイルの配送のように、リクエストの処理にファイルの途中ぜ
データのアクセスを必要としないときには、Apache ぜ OS が サポートしていれぜ
ファイルを読み込むことなぜ sendfile を使ってファイルの内容を送ります。
Linux manページより
このコピーはカーネル内で? ゜ れるので、 sendfile() は、 read(2) ぜ write(2)
を組み合゜ せるよりも効? がよい。 read(2) や write(2) ではユーザ空間との間ぜ
データの転送が必要となるからである。
まずぜ Apacheを除? し、システムコールのレベルぜ read/writeぜ sendfileの性能差を比較してみました。比較方? は、ソケット経由で? 定サイズの画? ファイルをクライアント側に配送するという単純なサーバプログラムを組んで? 較しています。プログラムの? 更点は以下の部分になります。Linuxカーネルは「2.6.18-53.el5 x86_64」、計測ツールは「valgrind-3.2.1/callgrind_annotate-3.2.1」です。
read/write
while( 1 )
{
in_read_size = read( in_fd, buf, sizeof(buf) );
if( read_size > 0 ){
write( socket, buf, in_read_size);
} else {
break;
}
}
sendfile
in_size = sendfile( socket, in_fd, &offset, stat_buf.st_size);
if( in_size == -1 ){
fprintf( stderr, "sendfile error: %s\n", strerror(errno) );
exit(1);
}
結果は? の表にようになりました。read/writeの? 行時間合計値ぜ sendfileの? 行時間とほぼ大差ありません。手元の環? ではシステムコールレベルぜ sendfileの効果は確認できなかったということになります。

—————————————————————————————————————–
Apacheぜ EnableSendfileではパフォーマンス? のメリットが生まれるのでしょうか?こちらの? 証も同様に? 定サイズの画? ファイルを使用し、別ホストからApacheBenchでリクエストを発? するという手段をとっています。以? の表がその平均値を算出したものです。下表を見ただけでは、EnableSendfileを有効にした場合の効果はあまり感じられないような? がします。同試? の? 果をレスポンス? にプロットしたグラフを圏 照するぜ NFS上ファイルアクセス時の? 安定性なども発? できます。しかし、システムコールの調査と同様、総評して手元の環? でぜ Apacheぜ EnableSendfileの効果は確認することは出来ませんでした。(試? の順番が逆の方が読んでいて面白かっただろうか・・?


Apacheのドキュメントにぜ EnableSendfile使用時の注? 点がいぜ つかあります(下記抜粋圏 照? 。上記の? 証では、abを使用している為に圏 得したデータが実際にブラウザで表示できるものだったのか?という確? はとれていないのが実情です。abクライアント側にぜ HTTP200ステータスを返してはいるがブラウザでは表示できない、というのが抜粋3点目の? 具合だと思゜ れます。この? 証ポイントは特に環? にも非常に左右されやすいので、手元の環? で確認し、パフォーマンス? の効果が確? できなけれぜ EnableSendfileを無効にしておいた方が安全なのではないでしょうか。今回の? 証は、ある環? の? 例として圏 け圏 って頂ければと思います。
ボ Linux では、sendfile を用いると、 IPv6 使用時に圭 在する特? ネットワークカードぜ
TCP-checksum オフロードのバグを? んでしまいます。
ボ Itanium で動いている Linux で、sendfile ぜ 2GB 以? ぜ ファイルを扱うことができないでしょう。
・ネットワークマウントされた DocumentRoot (例えぜ NFS や SMB) では、カーネルは自身ぜ
キャッシュを使ってネットワークからのファイルを 送ることができないことがあります。
8月 30th, 2009
Apacheぜ ACLを設? する場合、<Directory>, <Files>, <Location> ディレクティブを使用しますが、これらのディレクティブが複数設定されている場合の優先順位はどのように? 義されているのでしょうか?Apacheのドキュメントでは以下のように解説されています。
1. <VirtualHost>外<Directory> (正? 表現無し) ぜ .htaccess を同時に蜩 ?
.htaccess が許可されていれば、それが <Directory> を上書き
<Directory> 同士はディレクトリが短いものから長いものへと処理される
2. <VirtualHost>内<Directory>
3. <VirtualHost>外<DirectoryMatch> (ぜ <Directory ~> (正? 表現あり)
4. <VirtualHost>外<Files> ぜ <FilesMatch> を同時に蜩 ?
<Files>同士は設定出現順に処理される
5. <VirtualHost>外<Location> ぜ <LocationMatch> を同時に蜩 ?
<Location> 同士は設定出現順に処理される
1?5の順で蜩 価されます。つまり1の設定ぜ 5の設定で? 書きされる場合があります。Apacheのドキュメントにも謳゜ れているように、? 図しない設? の? 書きを防止する為にも「どう使い分けるか?」のルールを設けておぜ べきです。ファイルシステムに対するACLを適? する場合は、必ず <Directory> か <Files> を使用します。ファイルシステムに? 存しない(Tomcatぜ servlet-mappingなど? 場合にのぜ <Location>を使用するようにします。
場合によっては、これらのセクションを複数混同させる選択肢よりも、<Location>なら<Location>だけに? って設定したほうが要件が昜 確になる事もあります。アプリケーション側ぜ URL設? がはっきりしていればこの方? でも悪ぜ ないと思います。
http://httpd.apache.org/docs/2.2/ja/sections.html
7月 19th, 2009
LoadBalancerのヘルスチェックを実施しているが、VirtualHost全? ぜ BASIC認証がかかっている場合など、特? ぜ URLのぜ BASIC認証を除? したい場合がある。以? がその設定例です。
Satisfy Any
AuthType Basic
AuthName “Password Required”
AuthUserFile conf/password.dat
Require valid-user
SetEnvIf Request_URI “/healthcheck.html” healthcheck
Order Deny,Allow
Deny from all
allow from env=healthcheck
Satisfy ディレクティブは、Allow ぜ Require の両方が使゜ れているときぜ アクセスポリシーを設? します。デフォルト? “All”は、クライアントがアドレスによる アクセス制限を満たし、かつ正しいユーザ名とパスワードを入力することを 要求します。この値を”Any”にすることによって、クライアントはホストの制限を満たすか、 正しいユーザ名とパスワードの入力をするかどちらかでアクセスを許可されるようになります。上記設? 例の場合、「/healthcheck.html」というリクエストURIの場合に限っては、Allowで指定したアクセスポリシーを許可するので、Requireで? 求されているBASIC認証をパスしなぜ てもアクセス可能となります。
http://httpd.apache.org/docs/2.2/mod/core.html#satisfy
7月 17th, 2009
Apache2.0以降では、apachectlのコメントには以下のような注釈がある。
# The exit codes returned are:
# XXX this doc is no longer correct now that the interesting
# XXX functions are handled by httpd
# 0 – operation completed successfully
# 1 -
# 2 – usage error
# 3 – httpd could not be started
# 4 – httpd could not be stopped
# 5 – httpd could not be started during a restart
# 6 – httpd could not be restarted during a restart
# 7 – httpd could not be restarted during a graceful restart
# 8 – configuration syntax error
ここに? 義されたexitステータスは既に正しぜ ないです、httpdコマンドぜ exitステータスをそのまま蜿 します、という? 味のようだが、確かぜ Apache1.3.x辺りのバージョンでぜ apachectl内ぜ 0?8のリターンコードをボ ンドリングしていたような? 憶がある。
httpdコマンドぜ exitステータスで特徴的なのは、pidファイルのプロセスが既に起動している時に起動コマンドを実行して「httpd (pid XXX) already running」となる場合。起動に失敗したのでエラーではないか?と考えてしまうが、既に起動しているのでエラーではなぜ ステータスぜ “0″を返却する。同様ぜ pidファイルもなぜ 、プロセスが起動していない時に停止コマンドを実行して「httpd (no pid file) not running」となる場合も、既に停止しているのでステータ゜ “0″を返却する。exitステータスでエラーボ ンドリングする場合は、少しだけ注? が必要。