'Действительно ли epoll' является существенной причиной, что Tornadoweb (или Nginx) так быстр?

Tornadoweb и Nginx являются популярными веб-серверами в настоящий момент, и много сопоставительного анализа показывают, что у них есть лучшая производительность, чем Apache при определенных обстоятельствах. Таким образом, мой вопрос:

'Действительно ли epoll' является самой существенной причиной, которые делают их настолько быстро? И что я могу узнать из этого, если я хочу записать хороший сервер сокета?

23
задан Mickey Shine 6 April 2010 в 08:21
поделиться

2 ответа

Если вы хотите написать сокет-сервер, хорошей отправной точкой будет статья Дэна Кегеля о C10k несколько лет назад:

http://www.kegel.com/c10k.html

Я также нашел Beej's Guide to Network Programming довольно удобным:

http://beej.us/guide/bgnet/

Наконец, если вам нужен большой справочник, есть UNIX Network Programming by W. Richard Stevens et. al.:

http://www.amazon.com/Unix-Network-Programming-Sockets-Networking/dp/0131411551/ref=dp_ob_title_bk

В любом случае, отвечая на ваш вопрос, основное различие между Apache и Nginx заключается в том, что Apache использует один поток на клиента с блокирующим вводом/выводом, тогда как Nginx - однопоточный с неблокирующим вводом/выводом. Рабочий пул в Apache действительно снижает накладные расходы на запуск и завершение процессов, но он все равно заставляет CPU переключаться между несколькими потоками при обслуживании нескольких клиентов. Nginx, с другой стороны, обрабатывает все запросы в одном потоке. Когда одному запросу нужно сделать сетевой запрос (скажем, к бэкенду), Nginx прикрепляет обратный вызов к запросу бэкенда, а затем работает над другим активным клиентским запросом. На практике это означает, что он возвращается в цикл событий (epoll, kqueue или select) и запрашивает файловые дескрипторы, которым есть что сообщить. Обратите внимание, что системный вызов в главном цикле событий на самом деле является блокирующей операцией, потому что нечего делать, пока один из файловых дескрипторов не будет готов к чтению или записи.

Таким образом, это основная причина, по которой Nginx и Tornado эффективны при обслуживании многих одновременных клиентов: здесь всегда только один процесс (что экономит оперативную память) и только один поток (что экономит CPU от переключения контекста). Что касается epoll, то это просто более эффективная версия select. Если есть N открытых файловых дескрипторов (сокетов), он позволяет вам выбрать те, которые готовы к чтению, за время O(1) вместо O(N). На самом деле, Nginx может использовать select вместо epoll, если вы скомпилируете его с опцией --with-select_module, и я готов поспорить, что он все равно будет эффективнее Apache. Я не так хорошо знаком с внутренним устройством Apache, но быстрый grep показывает, что он действительно использует select и epoll - вероятно, когда сервер прослушивает несколько портов/интерфейсов, или если он выполняет одновременные бэкенд-запросы для одного клиента.

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

http://www.evanmiller.org/nginx-modules-guide.html

(Внимание: руководство было написано для Nginx 0.5-0.6, и API могли измениться). Если вы делаете что-нибудь с HTTP, я бы посоветовал попробовать Nginx, потому что в нем проработаны все тонкости работы с глупыми клиентами. Например, маленький сокет-сервер, который я написал для развлечения, отлично работал со всеми клиентами - кроме Safari, и я так и не понял, почему. Даже для других протоколов Nginx может быть правильным решением; обработка событий довольно хорошо абстрагирована от протоколов, вот почему он может проксировать HTTP, а также IMAP. Кодовая база Nginx очень хорошо организована и очень хорошо написана, за одним исключением, о котором стоит упомянуть. Я бы не стал следовать его примеру, когда дело доходит до ручной разработки парсера протоколов; вместо этого используйте генератор парсера. Я написал кое-что об использовании генератора парсера (Ragel) с Nginx здесь:

http://www.evanmiller.org/nginx-modules-guide-advanced.html#parsing

Все это, вероятно, было больше информации, чем вы хотели, но, надеюсь, вы найдете что-то из этого полезным.

66
ответ дан 29 November 2019 в 00:56
поделиться

Да и нет. Хотя они оба используют epoll, технически они оба используют цикл событий для обработки запросов. Дополнительную информацию о том, что такое циклы событий и как они используются, можно найти в wikipedia .

Ознакомьтесь с libevent (используется gevent , обычно быстрее и стабильнее, чем tornado) или libev для реализации.

5
ответ дан 29 November 2019 в 00:56
поделиться
Другие вопросы по тегам:

Похожие вопросы: