Обработка HTTP-запроса с помощью Apache2 (или Nginx). Создается ли новый процесс для каждого или набора из N запросов?

Будет ли веб-сервер (WS) (например, apache2 или nginix (или контейнер, такой как tomcat (TC)) создавать новый процесс для обработки входящего запроса. Меня беспокоят серверы, которые поддерживают большое количество параллельных пользователей (скажем, 20 000+ параллельных пользователей). < br> Я думаю, что балансировка нагрузки происходит на другой стороне веб-сервера (если он используется для работы с Tomcat и т. д.) Таким образом, теоретически, один веб-сервер должен принимать все (20 000+) входящих запросов, прежде чем он сможет распределить нагрузку на другие серверы, поддерживающие его.
Итак, возникает вопрос: обрабатывает ли веб-сервер (WS) все эти запросы в одном процессе или он разумно порождает другой процесс, чтобы помочь разделить работу (я знаю, что "клиент-сервер " происходит привязка - client_host:random_port плюс server_host:fixed_port).

Ссылка: до прочтения этой статьи:Front Tomcat с Apache Я думал, что всю умную работу выполняет один процесс. Но в этой статье упоминается MPM (Multi-Processing Module).

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

И по мере того, как это происходит, он становится все более изощренным, поскольку потоки также порождаются, как упоминалось выше. (это не потоки tomcat, которые обслуживают каждый отдельный запрос, вызывая метод службы, а потоки в Apache WS для обработки запросов и распределения их по узлам для обработки).
Если кто-то использовал MPM. Небольшое дальнейшее объяснение того, как все это работает, было бы здорово.
Вопросы типа -
(1) Поскольку дочерние процессы порождаются, какова их точная роль. Является ли дочерний процесс только для передачи запроса tomcat или чего-то еще. Если да, то после того, как дочерний процесс получит ответ от TC, пересылает ли дочерний процесс ответ родительскому процессу или непосредственно клиенту (поскольку он может знать client_host:random_port из родительского процесса. Я не уверен, что это разрешено теоретически, хотя дочерний процесс не может принять новый запрос в качестве fixed_port, который может быть привязан только к одному процессу уже привязан к родительскому процессу.
(2) Какая нагрузка разделяется с потоком дочерним или родительским процессом. Опять же, она должна быть почти такой же, как в (1). Но я не уверен, что даже в теория, если поток может напрямую отправить запрос клиенту.


person samshers    schedule 10.09.2016    source источник


Ответы (1)


Apache исторически использует префорковую модель обработки. В этой модели каждый запрос == отдельный процесс операционной системы (ОС). Он вызывает «prefork», потому что Apache разветвляет некоторые запасные процессы и обрабатывает запрос внутри. Если количество предварительно разветвленных процессов недостаточно - Apache разветвляется. Плюсы: процесс может выполнять другие модули или процессы и не заботиться о том, что они делают; минусы: каждый запрос = один процесс, слишком много используемой памяти и разветвление ОС также может быть медленным для ваших запросов.

Другая модель Apache — рабочий MPM. Почти то же самое, что и prefork, но с использованием не процессов ОС, а потоков ОС. Thread - это как бы облегченный процесс. Один процесс ОС может запускать множество потоков, используя одно пространство памяти. Рабочий MPM использовал гораздо меньше памяти, а новые потоки создавались быстрее. Минусы: модули должны поддерживать потоки, сбой модуля может привести к сбою всех потоков всего процесса ОС (но это не важно для вас, потому что вы используете apache только как обратный прокси). Другие минусы: процессор переключает контекст при переключении между потоками.

Так что да, worker намного лучше, чем prefork в вашем случае, но...

Но у нас есть Nginx :) Nginx использует другую модель (кстати, у Apache тоже есть event MPM). В этом случае у вас есть только один процесс (ну может быть несколько процессов, см. ниже). Как это устроено. Новое специальное событие запроса, процесс ОС просыпается, получает запрос, готовит ответ, записывает ответ и уходит в сон.

Вы можете сказать «вау, но это же не многозадачность» и будете правы. Но есть одно большое отличие этой модели от простой последовательной обработки запросов. Что произойдет, если вам нужно записать большие данные на медленный клиент? В синхронном режиме ваш процесс должен ждать подтверждения о получении данных и только после этого обрабатывать новый запрос. Модель событий Nginx и Apache использует асинхронную модель. Nginx говорит ОС отправить некоторый фрагмент данных, записать эти данные в буфер ОС и... уйти в сон или обработать новые запросы. Когда ОС отправит часть данных - в nginx будет отправлено специальное событие. Итак, основное отличие - Nginx не ждет ввода-вывода (например, подключение, чтение, запись), Nginx сообщает ОС, что он хочет, и ОС отправляет событие в Nginx, чем эта задача готова (сокет подключен, данные записаны или новые данные готовы к чтению). в локальном буфере). Кроме того, современные ОС могут работать с HDD асинхронно (чтение/запись) и даже отправлять файлы с HDD на TCP-сокет напрямую.

Конечно, все математические операции в этом процессе Nginx будут блокировать этот процесс и его остановку для обработки новых и существующих запросов. Но когда основным рабочим процессом является работа с сетью (обратный прокси, перенаправление запросов на FastCGI или другой внутренний сервер) плюс отправка статических файлов (тоже асинхронная) — Nginx может обслуживать тысячи одновременных запросов в одном процессе ОС! Кроме того, поскольку один процесс ОС (и один поток) - ЦП будет выполнять его в одном контексте.

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

Итак, плюсы: меньшее переключение контекста процессора, меньше памяти (по сравнению с рабочим MPM тоже), быстрая обработка соединения. Дополнительные плюсы: Nginx создан как балансировщик нагрузки HTTP и имеет множество опций для него (и даже больше в коммерческом Nginx Plus). Минусы: если вам нужна сложная математика внутри процесса ОС, этот процесс будет заблокирован (но все, что вам нужно, это математика в Tomcat, поэтому Nginx только балансировщик).

PS: исправление опечатки будет позже, не вовремя. Кроме того, мой английский плохой, поэтому исправления всегда приветствуются :)

PPS: Ответьте на вопрос о номере темы TC, заданный в комментариях (был слишком длинным для публикации в качестве комментария):

Лучший способ это узнать — протестировать с помощью инструментов стресс-нагрузки. Потому что это число зависит от профиля приложения. Время отклика недостаточно, чтобы помочь ответить. Потому что, например, большая разница между 200 мс 100% математики (100% привязка к процессору) и 50 мс математики + 150 мс ожидания ответа базы данных.

Если приложение на 100% привязано к процессору - возможно, один поток на одно ядро, но в реальных случаях все приложения также тратят некоторое время на ввод-вывод (получение запроса, отправка ответа клиенту).

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

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

Конечно, здесь я говорю только о динамическом контенте, запросы на статические файлы с диска должны обрабатываться до tomcat (например, Nginx).

person Dmitry MiksIr    schedule 10.09.2016
comment
большие детали. Тх. Еще один важный параметр конфигурации, который я хочу спросить: какое безопасное значение для количества потоков, которые можно использовать для каждого рабочего tomcat. (Предпочтительно в зависимости от количества ядер процессора — NC и количества HT, если таковые имеются на процессор HTP). У меня NC=4 и HTP=2, поэтому общее количество доступных логических процессоров равно 8. Тогда каким должно быть общее количество потоков для этого рабочего процесса. Это может быть сложно ответить с небольшой информацией, но некоторые рекомендации помогут. Тх - person samshers; 10.09.2016
comment
Я ответил на ваш вопрос как PPS в ответе выше, потому что слишком много символов для этого комментария. - person Dmitry MiksIr; 10.09.2016
comment
это то, что отвечает на мой запрос: если приложение на 100% привязано к процессору - возможно, один поток на одно ядро. Превосходно. Остальное, я могу сравнить приложения, не требующие интенсивного использования процессора, через загрузку процессора (системы и пользователя) по сравнению со временем простоя и т. д. Спасибо. - person samshers; 11.09.2016