C: epoll и многопоточность

Мне нужно создать специализированный HTTP-сервер, для этого я планирую использовать epoll sycall, но я хочу использовать несколько процессоров/ядер, и я не могу придумать архитектурное решение. ATM моя идея следующая: создайте несколько потоков с собственными дескрипторами epoll, основной поток принимает соединения и распределяет их между потоками epoll. Но есть ли лучшие решения? Какие книги / статьи / руководства я могу прочитать на архитектурах с высокой нагрузкой? Я видел только C10K статье, но большинство ссылки на примеры мертвы : (и до сих пор нет глубоких книг по этой теме : (.

Спасибо за ответы.

UPD: пожалуйста, будьте более конкретными, мне нужны материалы и примеры (nginx не является примером, потому что его слишком сложный и имеет несколько слоев абстракции для поддержки нескольких систем).

3 ответов


Регистрация libevent и libev источники. они очень удобочитаемы, и уже хорошая инфраструктура для использования.

кроме того, в документации libev есть много примеров нескольких проверенных и истинных стратегий. Даже если вы предпочитаете писать прямо в epoll(), примеры могут привести к нескольким выводам.


..Моя идея следующая: создайте несколько потоков с собственным epoll дескрипторы, основной поток принимает соединения и распределяет их между потоками в epoll.

да, в настоящее время это лучший способ сделать это, и именно так Nginx это делает. Число потоков может быть увеличено или уменьшено в зависимости от нагрузки и/или количество физических ядер на машине.

компромисс между дополнительными потоками (больше, чем количество физических ядер) и события-это задержка и пропускная способность. Потоки улучшают задержку, поскольку они могут выполняться упреждающе, но за счет пропускной способности из-за накладных расходов, связанных с переключением контекста и созданием/удалением потоков. События улучшают пропускную способность, но имеют тот недостаток, что длительный код заставляет весь поток останавливаться.

вторым лучшим является то, как Apache2 делает это с помощью пула потоков блокировки потоков. Здесь нет обработки событий, поэтому реализация проще, а пул означает потоки не создаются и не уничтожаются без необходимости, но они не могут конкурировать с хорошо реализованным потоком / асинхронным гибридом, таким как то, что вы пытаетесь реализовать или Nginx.

третье лучшее-это асинхронная обработка событий, такая как Lighttpd или Node.js. Ну, это второй лучший если вы не делаете тяжелую обработку на сервере. Но как упоминалось ранее, один длительный цикл while блокирует весь сервер.


если у вас нет восходящей линии terabit и вы планируете обслуживать 10000 одновременных подключений с одного сервера, забудьте о epoll. Это просто безвозмездная непереносимость;poll или даже select будет делать так же хорошо. Имейте в виду, что к тому времени, когда terabit uplinks и такие стандартные, ваш сервер также будет достаточно быстрее, что вам все равно не понадобится epoll.

если вы просто обслуживаете статический контент, забудьте о потоках и используйте Linux sendfile syscall. Этот слишком нештатно, но по крайней мере оно предлагает огромные реальные преимущества представления.

также обратите внимание, что другие проектные решения (особенно избыточная сложность) будут гораздо более важным фактором в том, сколько нагрузки ваш сервер может обрабатывать. Например, просто посмотрите, как скромный однопоточный, однопоточный процесс thttpd сдувает Apache и друзей в производительности на статическом контенте-и, по моему опыту, даже на традиционном динамическом контенте cgi!