Ця відповідь доповнює інші, і пояснює, чому Єдинорогу потрібен nginx перед ним .
TL; DR Причина того, що Unicorn зазвичай розгортається разом із зворотним проксі-сервером на зразок nginx, полягає в тому, що його творці навмисно спроектували це, зробивши компроміс для простоти.
Перш за все, нічого не перешкоджає розгортанню Unicorn без нього зворотного проксі. Однак це було б не дуже хорошою ідеєю; подивимося чому.
Unicorn дотримується філософії Unix, яка полягає в тому, щоб робити одне і робити це добре , а це - обслуговувати швидких клієнтів з низькою затримкою (ми побачимо, що це означає далі). Той факт, що Unicorn призначений для швидких клієнтів з низькою затримкою, також означає, що це не дуже добре з повільними клієнтами з високою затримкою , що дійсно так. Це одна з слабких сторін Unicorn, і саме там починається зворотний проксі: він сидить перед Unicorn і піклується про тих повільних клієнтів (ми побачимо, як далі).
На щастя, такий зворотний проксі вже існує і називається nginx .
Рішення обробляти тільки швидких клієнтів, значно спрощує дизайн Unicorn та дозволяє значно простішу та меншу базу коду, ціною якоїсь додаткової складності у відділі розгортання (тобто вам доведеться також розгорнути nginx на додаток до Unicorn).
Альтернативне рішення могло б спроектувати Unicorn таким чином, щоб він не потребував зворотного проксі. Однак це означає, що йому доведеться впроваджувати додаткову функціональність, щоб виконувати все те, що зараз робить nginx, в результаті чого є більш складна база даних коду та більше зусиль з інженерії.
Натомість його творці прийняли рішення використати існуюче програмне забезпечення, яке пройшло випробування на бої та дуже добре розроблене, і уникати витрачати час та енергію на проблеми, вже вирішені іншим програмним забезпеченням.
Але давайте розберемося з технічним та відповімо на ваше запитання:
Чому Unicorn потрібно розгорнути разом із nginx?
Ось кілька ключових причин:
Unicorn використовує блокування вводу / виводу для клієнтів
Посилання на зворотний проксі означає, що Єдиноріг не потребує використання неблокуючих вводу-виводу. Натомість він може використовувати блокування вводу / виводу, що за своєю суттю простіше і простіше для програміста.
Також, як зазначено в документі DESIGN :
[Використання блокування вводу / виводу] дозволяє прослідкувати простіший шлях коду в інтерпретаторі Ruby і менше систематичних викликів.
Однак це також має деякі наслідки:
Ключовий момент №1: Єдиноріг не ефективний для повільних клієнтів
(Для простоти ми передбачаємо налаштування з 1 працівником Єдиноріг)
Оскільки блокування вводу-виводу використовується, працівник Unicorn може обслуговувати лише одного клієнта за один раз , тому повільний клієнт (тобто той, який має повільне з'єднання) фактично утримуватиме працівника зайнятим довше (ніж швидкий клієнт зробив би) ). Тим часом інші клієнти просто чекають, поки працівник знову не буде вільний (тобто запити збираються у черзі).
Щоб вирішити цю проблему, перед Unicorn розгорнуто зворотний проксі-сервер, який повністю буферизує вхідні запити та відповіді додатків, а потім надсилає кожен з них одразу (він же ложечкою подає їх) Unicorn та клієнтам відповідно. У зв'язку з цим можна сказати, що зворотний проксі "захищає" Єдиноріг від повільних мережевих клієнтів.
На щастя, Nginx є прекрасним кандидатом на цю роль, оскільки він розроблений для ефективної обробки тисяч сотень одночасно клієнтів.
Надзвичайно важливо, щоб зворотний проксі був у тій же локальній мережі, що і Unicorn (як правило, в тій же фізичній машині, що спілкується з Unicorn через розетку домену Unix), щоб затримка в мережі була мінімальною.
Таким чином, такий проксі-сервер ефективно грає роль швидкого клієнта, який Unicorn призначений для обслуговування в першу чергу, оскільки він надає прохання до Unicorn швидко та тримає працівників зайняті за найкоротший час (порівняно з тим, скільки часу клієнт з повільним зв’язком зробив би).
Ключовий момент №2: Єдиноріг не підтримує HTTP / 1.1
Оскільки Unicorn використовує блокування вводу-виводу, це також означає, що він не може підтримувати функцію HTTP / 1.1 у режимі "живого", оскільки стійкі з'єднання повільних клієнтів швидко займуть усіх доступних Unicorn працівників.
Тому, щоб використовувати HTTP в режимі "живого", вгадайте, що: використовується зворотний проксі.
nginx, з іншого боку, може обробляти тисячі одночасних з'єднань, використовуючи лише кілька потоків. Таким чином, у нього немає обмежень на сумісність на сервері, як у Unicorn (який по суті обмежений кількістю робочих процесів), а це означає, що він може добре працювати з стійкими з'єднаннями. Більше про те, як це насправді працює, можна прочитати тут .
Ось чому nginx приймає постійні з'єднання від клієнтів і передає їм Unicorn через звичайні з'єднання через типовий Unix-сокет.
Пункт №3: Єдиноріг не дуже добре обслуговує статичні файли
Знову ж, подання статичних файлів - це те, що Unicorn може зробити, але не призначене для ефективного виконання.
З іншого боку, зворотні проксі, як-от nginx, хоч і набагато краще в ньому (тобто. sendfile(2)
& Кешування).
Більше
Є й інші моменти, які викладені в документі PHILOSOPHY (див. «Покращення продуктивності за допомогою зворотного проксі» ).
Дивіться також деякі основні функції nginx .
Ми бачимо, що, використовуючи існуюче програмне забезпечення (наприклад, nginx) і дотримуючись філософії Unix "робити одну справу і робити це добре", Unicorn здатний дотримуватися більш простого дизайну та впровадження, зберігаючи ефективність при обслуговуванні додатків Rack (наприклад. ваш додаток Rails).
Для отримання додаткової інформації зверніться до філософії та дизайнерських документів Unicorn, які більш докладно пояснюють вибір дизайну Unicorn і чому nginx вважається хорошим реверс-проксі для Unicorn.