以前の記事で以下のようなエラーがでるということを書きましたが、ちょっと嘘ついてたみたいというか、適当すぎたのでよく調べてみました。
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なるものもあるようで、負荷が増えてきたらこいつも設定してあげるといいのじゃろか。