LighttpdのFD_SETSIZE【続】

以前の記事で以下のようなエラーがでるということを書きましたが、ちょっと嘘ついてたみたいというか、適当すぎたのでよく調べてみました。

2009-08-31 14:05:37: (server.c.1337) [note] sockets enabled again
2009-08-31 14:07:16: (server.c.1383) [note] sockets disabled, connection limit reached

FD_SETSIZEを変更してビルドし直したのですが、またエラーが出るようになりました。色々調べていると、server.max-connectionsなるものがあるらしい。こいつにはまったく手をつけていませんでした。以下のように設定を変更。

# max-fdsは、max-connectionsの2倍以上の値が必要
server.max-fds = 8192
server.max-connections = 4096

max-connectionsは、未設定の場合、(max-fds / 3)の値が適用されるようです。ということは1365くらいになってたってことか。

それでよくよくソースコードを見てみると、今回の場合は、そもそもがFD_SETSIZEを変更してビルドする必要はなかったようです。
event-handlerという設定があるのですが、こちらはデフォルトで「0」が設定されているようなので、以下の条件に一致します。

        if (srv->srvconf.event_handler->used == 0) {
/* choose a good default
*
* the event_handler list is sorted by 'goodness'
* taking the first available should be the best solution
*/
srv->event_handler = event_handlers[0].et;
if (FDEVENT_HANDLER_UNSET == srv->event_handler) {
log_error_write(srv, __FILE__, __LINE__, "s",
"sorry, there is no event handler for this system");
return -1;
}
} else {

event_handlersの最初の値が使われるようです。

        struct ev_map { fdevent_handler_t et; const char *name; } event_handlers[] =
{
/* - poll is most reliable
* - select works everywhere
* - linux-* are experimental
*/
#ifdef USE_POLL
{ FDEVENT_HANDLER_POLL,           "poll" },
#endif
#ifdef USE_SELECT
{ FDEVENT_HANDLER_SELECT,         "select" },
#endif
#ifdef USE_LINUX_EPOLL
{ FDEVENT_HANDLER_LINUX_SYSEPOLL, "linux-sysepoll" },
#endif
#ifdef USE_LINUX_SIGIO
{ FDEVENT_HANDLER_LINUX_RTSIG,    "linux-rtsig" },
#endif
#ifdef USE_SOLARIS_DEVPOLL
{ FDEVENT_HANDLER_SOLARIS_DEVPOLL,"solaris-devpoll" },
#endif
#ifdef USE_FREEBSD_KQUEUE
{ FDEVENT_HANDLER_FREEBSD_KQUEUE, "freebsd-kqueue" },
{ FDEVENT_HANDLER_FREEBSD_KQUEUE, "kqueue" },
#endif
{ FDEVENT_HANDLER_UNSET,          NULL }
}; 

Linux環境だったので、poll、select、linux-sysepoll、linux-rtsigから選択できる感じなのでしょうか?デフォルトでは、pollが使用されるようですが、カーネルが2.6以上の場合は、epollを使うと効率的らしいです。
Server.event-handlerDetails – Lighttpd – lighty labs
ということは、デフォルトでpollを使っているならば、初期値は以下の4096が適用される感じになるはず。

        if (srv->event_handler == FDEVENT_HANDLER_SELECT) {
/* select limits itself
*
* as it is a hard limit and will lead to a segfault we add some safety
* */
srv->max_fds = FD_SETSIZE - 200;
} else {
srv->max_fds = 4096;
}

さらに、max-fdsを設定しているならば、以下のように設定された値がそのまま使われるようです。

                if (use_rlimit && srv->srvconf.max_fds) {
/* set rlimits */
rlim.rlim_cur = srv->srvconf.max_fds;
rlim.rlim_max = srv->srvconf.max_fds;
if (0 != setrlimit(RLIMIT_NOFILE, &rlim)) {
log_error_write(srv, __FILE__, __LINE__,
"ss", "couldn't set 'max filedescriptors'",
strerror(errno));
return -1;
}
}
if (srv->event_handler == FDEVENT_HANDLER_SELECT) {
srv->max_fds = rlim.rlim_cur < FD_SETSIZE - 200 ? rlim.rlim_cur : FD_SETSIZE - 200;
} else {
srv->max_fds = rlim.rlim_cur;
}

ということなので、event-handlerを特に設定していない状態で、selectを指定していないのであれば、FD_SETSIZEを変更して、ビルドし直す必要はなかった・・・でした。
あとは、max-workerなるものもあるようで、負荷が増えてきたらこいつも設定してあげるといいのじゃろか。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です