Кстати, если тема представляет еще для кого-то практический интерес, подключайтесь! (Сорри, что это оффтопик в рассылке nginx.) Я пока нарыл вот что. В server\mpm\prefork\prefork.c есть кусочек:
/* Set up the pollfd array */ /* ### check the status */ (void) apr_pollset_create(&pollset, num_listensocks, pchild, 0);
for (lr = ap_listeners, i = num_listensocks; i--; lr = lr->next) { apr_pollfd_t pfd = { 0 };
/* ### check the status */ (void) apr_pollset_add(pollset, &pfd); }
Эта штука создает список сокетов, на которых ниже происходит цикл ожидания активности (причем в этот цикл попадает только один процесс апача, остальные ждут на мьютексе):
Первый активный сокет будет подхвачен процессом. Так вот, мысль первая: если в кусочке выше добавлять в список не все сокеты, а только те, лимит коннектов на которые не превышен, то, теоретически, можно добиться принудительного ограничения на число коннектов.
Правда, непонятно, что делать, когда число соединений на каком-то сокете обратно стало меньше порогового. Освободившийся сокет в очередь легко не пропихнуть... Вернее, можно, конечно, выше в apr_pollset_poll() поставить не "вечный" тайм-аут, а 1 секунду (плюс новый apr_pollset_create() при наступлении тайм-аута), тогда он будет заново строить pollset, и вроде как проблема решается (ценой передергивания очереди раз в секунду).
теоретически - наверное возможно обучить апач параметру SocketMaxConn,
но большое количество listening сокетов - это неустранимый недостаток,
что может отрицательно сказаться потом на производительности сервера.
А что это за параметр, где он устанавливается? Мне сходу не удалось найти ничего похожего в системных вызовах...