Этот ответ дополняет другие и объясняет, почему Unicorn нужен nginx перед собой .
TL; DR Причина, по которой Unicorn обычно развертывается вместе с обратным прокси-сервером, таким как nginx, заключается в том, что его создатели специально спроектировали его таким образом, сделав компромисс для простоты.
Во-первых, ничто не мешает вам развернуть Unicorn без обратного прокси. Однако это было бы не очень хорошей идеей; посмотрим почему.
Unicorn следует философии Unix, которая заключается в том, чтобы делать одно и делать это хорошо , а именно обслуживать быстрых клиентов с малой задержкой (мы увидим, что это означает позже). Тот факт, что Unicorn разработан для быстрых клиентов с малой задержкой, также означает, что он не очень хорош для медленных клиентов с большой задержкой , что действительно верно. Это одна из слабых точек единорога и где обратный прокси - сервер входит в игру: он сидит перед единорогом и заботится о тех медленных клиентах (мы увидим , как позже).
К счастью, такой обратный прокси-сервер уже существует и называется nginx .
Решение работать только с быстрыми клиентами значительно упрощает дизайн Unicorn и позволяет использовать гораздо более простую и меньшую кодовую базу за счет некоторой дополнительной сложности в отделе развертывания (т. Е. Вам также необходимо развернуть nginx в дополнение к Unicorn).
Альтернативным решением может быть разработка Unicorn таким образом, чтобы ему не требовался обратный прокси. Однако это означает, что ему придется реализовать дополнительные функции, чтобы делать все то, что сейчас делает nginx, что приведет к более сложной кодовой базе и дополнительным инженерным усилиям.
Вместо этого его создатели приняли решение использовать существующее программное обеспечение, которое проверено в боях и очень хорошо спроектировано, чтобы не тратить время и силы на проблемы, уже решаемые другим программным обеспечением.
Но давайте перейдем к техническим вопросам и ответим на ваш вопрос:
Почему Unicorn нужно развертывать вместе с nginx?
Вот некоторые из основных причин:
Unicorn использует блокировку ввода-вывода для клиентов
Использование обратного прокси означает, что Unicorn не нужно использовать неблокирующий ввод-вывод. Вместо этого он может использовать блокирующий ввод-вывод, что по своей сути проще и легче для программиста.
Также, как говорится в документе DESIGN :
[Использование блокирующего ввода-вывода] позволяет использовать более простой код в интерпретаторе Ruby и уменьшить количество системных вызовов.
Однако это также имеет некоторые последствия:
Ключевой момент # 1: Unicorn неэффективен с медленными клиентами
(Для простоты мы предполагаем установку с 1 рабочим Unicorn)
Поскольку используется блокирующий ввод-вывод, рабочий Unicorn может обслуживать только одного клиента за раз , поэтому медленный клиент (то есть один с медленным подключением) будет эффективно держать рабочего занятым в течение более длительного времени (чем быстрый клиент). ). Тем временем другие клиенты будут просто ждать, пока рабочий снова освободится (т.е. запросы будут накапливаться в очереди).
Чтобы обойти эту проблему, перед Unicorn развертывается обратный прокси-сервер, который полностью буферизует входящие запросы и ответы приложения, а затем отправляет каждый из них сразу (иначе говоря, подает их с ложечки) Unicorn и клиентам, соответственно. В связи с этим можно сказать, что обратный прокси-сервер «защищает» Unicorn от медленных сетевых клиентов.
К счастью, Nginx - отличный кандидат на эту роль, поскольку он предназначен для эффективной обработки тысяч сотен одновременных клиентов.
Чрезвычайно важно, чтобы обратный прокси-сервер находился в той же локальной сети, что и Unicorn (обычно на той же физической машине, которая обменивается данными с Unicorn через сокет домена Unix), чтобы задержка в сети была минимальной.
Таким образом, такой прокси-сервер эффективно играет роль быстрого клиента, который Unicorn предназначен в первую очередь для обслуживания, поскольку он быстро передает запросы к Unicorn и обеспечивает занятость рабочих на минимально возможное время (по сравнению с тем, сколько времени клиент при медленном соединении подойдет).
Ключевой момент # 2: Unicorn не поддерживает HTTP / 1.1 keep-alive
Поскольку Unicorn использует блокирующий ввод-вывод, это также означает, что он не может поддерживать функцию сохранения активности HTTP / 1.1, поскольку постоянные соединения медленных клиентов быстро займут всех доступных рабочих Unicorn.
Поэтому угадайте, что для использования HTTP keep-alive: используется обратный прокси.
nginx, с другой стороны, может обрабатывать тысячи одновременных подключений, используя всего несколько потоков. Следовательно, у него нет ограничений параллелизма, которые есть у такого сервера, как Unicorn (который, по сути, ограничен количеством рабочих процессов), что означает, что он может нормально обрабатывать постоянные соединения. Подробнее о том, как это работает, можно узнать здесь .
Вот почему nginx принимает соединения keep-alive от клиентов и передает их Unicorn через простые соединения, как правило, через сокет Unix.
Пункт № 3: Unicorn не очень хорош в обслуживании статических файлов
Опять же, Unicorn может обслуживать статические файлы , но не предназначен для этого эффективно.
С другой стороны, обратные прокси, такие как nginx, намного лучше справляются с этим (т. sendfile(2)
Е. И кеширование).
Больше
Есть и другие моменты, которые изложены в документе ФИЛОСОФИЯ (см. «Повышение производительности за счет обратного проксирования» ).
См. Также некоторые из основных функций nginx .
Мы видим, что, используя существующее программное обеспечение (например, nginx) и следуя философии Unix «делать одно и делать это хорошо», Unicorn может упростить дизайн и реализацию, сохраняя при этом эффективность при обслуживании приложений Rack (например,. ваше приложение Rails).
Для получения дополнительной информации обратитесь к философии Unicorn и проектным документам, в которых более подробно объясняются варианты, лежащие в основе дизайна Unicorn, и почему nginx считается хорошим обратным прокси для Unicorn.