lighttpd で [note] sockets enabled again がでる不具合の対処方法
「高負荷、大量アクセスなサイトで Lighttpd を使う場合の注意点」でも書いたのですが、最新版の lighttpd 1.4.11 でも頻度は減ったとは言え、相変わらず socket エラーが不定期に発生しています。
2006-07-27 12:37:47: (server.c.1220) [note] sockets disabled, out-of-fds
このエラーが発生すると、マズ間違いなく FastCGI との socket 通信が断絶して lighttpd のソース内では自動的に socket を再構築するようになっているのですが、socket が復帰した試しがありません。
このエラーが発生しないようにする(ってか低減する)対処方法は前回記述したとおり、lighttpd のコンパイル時に、
make install
みたく、FD_SETSIZE の値を明示的に増量してあげれることなのですが、どうせ socket 通信が復帰しないなら lighttpd をリスタートしてしまえと言う荒技にでることにしました。修正箇所は以下の通り。
server.c 1174 行目付近を quick hack
if (srv->sockets_disabled) { /* our server sockets are disabled, why ? */ // append by drk 2006.07.29 log_error_write(srv, __FILE__, __LINE__, "s", "[note] sockets error -> server restart"); log_error_close(srv); network_close(srv); connections_free(srv); plugins_free(srv); server_free(srv); execv("/etc/init.d/lighttpd", "restart"); if ((srv->cur_fds + srv->want_fds < srv->max_fds * 0.8) && /* we have enough unused fds */ (srv->conns->used < srv->max_conns * 0.9) && (0 == graceful_shutdown)) { for (i = 0; i < srv->srv_sockets.used; i++) { server_socket *srv_socket = srv->srv_sockets.ptr[i]; fdevent_event_add(srv->ev, &(srv_socket->fde_ndx), srv_socket->fd, FDEVENT_IN); } log_error_write(srv, __FILE__, __LINE__, "s", "[note] sockets enabled again"); srv->sockets_disabled = 0; } } else {
これで、socket エラーが発生したときは、サーバーのリソースを解放して /etc/init.d/lighttpd restart 経由で自動的に再起動されます。ひとまず対処をしてから当該エラーが発生していないので未検証ではありますが、うまく行くと思います。
同じ現象でお困りの方は試してみては如何でしょうか。
あ、ちなみにリスタート時に socket の解放を待つために sleep 3 くらい入れてます。/etc/init.d/lighttpd から抜粋。
case "$1" in start) start ;; stop) stop ;; restart) stop sleep 3 start ;;
コメントやシェアをお願いします!
通りすがり
1024->4096にして「頻度が減った」なら、それは4096ではまだ足りないかシステムワイドの制限にひっかかってるかどちらかです。再起動するにしても、外部(別プロセス)から監視して再起動をする方法を検討するほうがいいでしょう(簡単なものなら数行のシェルスクリプトです)。方法自体がバッドノウハウ的、なによりよく分からないままサーバのソースに手をいれるのは非常に危険ですので絶対にやめましょう。
drk
daibaさん>鋭い突っ込みですね。確かに stop する際に解放されそうな気がします。ソースそこまで追わなかったのでココで解放してしまいましたが、stop する際に解放済みって怒られるかも。。
まだ、問題が再発していないので検証できてません。。。
k.daiba
execv("/etc/init.d/lighttpd", "restart");
でリスタートするから,この中でstopするタイミングでリソースは開放されると思うんですが,明示的に
network_close(srv);
connections_free(srv);
plugins_free(srv);
server_free(srv);
をする必要があるということなんでしょうか?