2011-01-14 4 views
12

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

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

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

+1

Эй, Даниэль, мне было интересно, как это происходит. Я занимаюсь некоторыми исследованиями в этой области, и я считаю, что моя концепция серверов, управляемых событиями, может быть немного слабой прямо сейчас. Насколько мне известно, кажется, что если у нас есть событие, прошедшее назад (скажем, с использованием epoll), каждая функция, которая вызывается, должна быть не блокирующей ... может быть, это мой дизайн, но каждый запрос, который приходит, вызывает обращение к базе данных. если по какой-либо причине этот вызов медленный, все остальные запросы клиента в то же время также страдают из-за ожидания завершения ответа базы данных. Я могу создать нить .. Цель поражения. – Begui

+4

его не на самом деле, его законченный давно, используя libev :) некоторые функции по-прежнему блокируются в моем приложении, просто их блок-время действительно мало. но такие вещи, как запросы к базе данных, операции ввода-вывода (особенно когда они действительно интенсивные) должны быть неблокируемыми. в моем случае я использую mongodb с его асинхронным драйвером, поэтому у меня нет блокировок при использовании db. У меня есть пулы потоков для вещей, которые я не мог сделать асинхронными (т. е. обработка изображений ImageMagick и минимизаторы CSS/JS), но они управляются через очереди и контролируются epoll (реализация собственной очереди). – Daniel

ответ

11

libevent и libev источники, они хорошо читаемы и уже являются хорошей инфраструктурой для

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

+0

спасибо, пошли читать. – Daniel

+0

от того, что я вижу libevent, однопоточный, но очень эффективный. не удается найти примеры libevent + multithreading atm, но поиск в googling продолжается ... – Daniel

+1

да, оба из них обрабатывают многопоточность, проверяют комментарии к нескольким событиям. – Javier

12

..my Идея заключается в том followng: создать несколько потоков с собственным Epoll дескрипторов, основной поток принимает соединения и распределяет их между нитями Epoll.

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

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

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

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

-1

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

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

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

+0

Серверы haven ' был значительно быстрее с 2005 года. 4 ГГц (или около того), по-видимому, является пределом. – slebetman

+1

Я до сих пор не видел убедительного аргумента в пользу «epoll», просто много «localhost» бенчмаркинга и тому подобного. И я видел огромные причины, чтобы это не нравилось: всевозможные люди, пишущие серверы/приложения, которые используют «epoll» (и, следовательно, работают только в Linux), когда им нужно иметь дело только с дескрипторами файлов 2-10 ... –

+0

I действительно делаю тесты на localhost :), но все же, я играл с libevent2, и это дало мне ~ 10k r/s и 100% нагрузку на ядро, поэтому я думаю, что если я добавлю threading, он сможет сделать хотя бы 20-25k запросов (на ящике с четырьмя ящиками), поэтому я все еще хочу играть с потоками. – Daniel

 Смежные вопросы

  • Нет связанных вопросов^_^