Подтвердить что ты не робот

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

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

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

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

4b9b3361

Ответ 1

проверьте libevent и libev источники, они хорошо читаемы и уже имеют хорошую инфраструктуру.

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

Ответ 2

.. моя идея followng: создать несколько потоков с собственной эпопеей дескрипторы, основной поток принимает соединения и распределяет их среди тем epoll.

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

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

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

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

Ответ 3

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

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

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