Скорость Nginx и как ее воспроизвести


Я заинтересован в этом больше с академической точки зрения, чем с практической; я не планирую создавать производственный веб-сервер, чтобы конкурировать с nginx. Мне интересно, как именно nginx настолько быстр. Главным ответом google на это являетсяэтот поток , но он просто ссылается на загадочное слайд-шоу и общее покрытие различных стратегий ввода-вывода. Все остальные результаты, похоже, просто описывают, насколько быстр nginx, а не причину.

Я попробовал построить простой сервер erlang пытался конкурировать с nginx, но безуспешно; nginx победил. Все, что делает мой сервер-это создает новый процесс для каждого запроса, использует этот процесс для чтения файла в сокет, затем закрывает файл и убивает поток. Это не сложно, но учитывая легкие процессы erlang и лежащую в основе структуру aio, я думал, что она будет конкурировать, но nginx все равно выигрывает в среднем на 300 мс при тяжелом стресс-тесте.

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

4 8

4 ответа:

Оказывается, мой маленький тестовый сервер был вполне конкурентоспособен с nginx, когда я сказал ему читать файлы в двоичном режиме, а не в режиме списка.

Я думаю, что большая часть обсуждения в остальной части этой темы может сбить с толку кого-то, незнакомого с Erlang и дизайном сервера erlang. Я не хотел удалять поток, так как в нем есть хорошая информация о nginx (и я не могу, у него уже есть ответы), но я призываю всех, кто хочет создать сервер на основе erlang, провести некоторые исследования и писать много тестов, а не идти только то, что вы здесь прочитали.

Я буду держать это немного простым, так как я на самом деле не эксперт в этом вопросе. Но две самые важные вещи, которые делают Nginx быстрым, это то, что он использует опрос событий и он не блокирует.

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

Вторая самая важная вещь заключается в том, что вы не блокируете процесс Nginx. Если вы выполняете операцию блокировки, то все остальные соединения будут стоять в очереди, ожидая завершения. Если каждое соединение блокируется, то производительность быстро упадет до нуля.

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

Nginx написан на языке Си, поэтому он компилируется на родной машинный язык. У Эрланга есть своя виртуальная машина. Это само по себе означает, что вы никогда не будете соответствовать производительности хорошо разработанной программы C, использующей программу Erlang, учитывая интерпретатор байт-кода, через который должен пройти модуль Erlang.

Несмотря на то, что Erlang основан на облегченных процессах и предназначен для масштабирования на распределенной архитектуре, он никогда не сможет соответствовать производительности обработки в режиме реального времени. системы, написанные на родном языке или, в данном случае, Nginx.

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