Ta odpowiedź jest komplementarna w stosunku do innych i wyjaśnia, dlaczego Jednorożec potrzebuje przed sobą nginx .
TL; DR Powodem, dla którego Unicorn jest zwykle wdrażany razem z odwrotnym proxy, takim jak nginx, jest to, że jego twórcy celowo go tak zaprojektowali, poświęcając prostotę.
Przede wszystkim nic nie stoi na przeszkodzie, aby wdrożyć Unicorn bez odwrotnego proxy. Jednak nie byłby to dobry pomysł; zobaczmy, dlaczego.
Unicorn podąża za filozofią Unix, która polega na zrobieniu jednej rzeczy i robieniu tego dobrze , a mianowicie na obsłudze szybkich klientów o niskim opóźnieniu (zobaczymy, co to oznacza później). Fakt, że Unicorn jest przeznaczony dla szybkich klientów o małych opóźnieniach, oznacza również, że nie jest zbyt dobry w przypadku wolnych klientów z dużymi opóźnieniami , co jest rzeczywiście prawdą. Jest to jeden ze słabych punktów Unicorn i tam właśnie wchodzi do gry odwrotne proxy: siedzi przed Unicorn i dba o tych powolnych klientów (zobaczymy, jak później).
Na szczęście takie odwrotne proxy już istnieje i nazywa się nginx .
Decyzja o obsłudze tylko szybkich klientów znacznie upraszcza projektowanie Unicorn i pozwala na znacznie prostszą i mniejszą bazę kodów, kosztem dodatkowej złożoności działu wdrażania (tj. Oprócz Unicorn trzeba również wdrożyć nginx).
Alternatywną decyzją może być zaprojektowanie Unicorn w taki sposób, aby nie potrzebował odwrotnego proxy. Oznacza to jednak, że musiałby zaimplementować dodatkową funkcjonalność, aby robić wszystkie rzeczy, które teraz robi nginx, co skutkuje bardziej złożoną bazą kodu i większymi wysiłkami inżynieryjnymi.
Zamiast tego jego twórcy podjęli decyzję o wykorzystaniu istniejącego oprogramowania, które jest przetestowane w walce i bardzo dobrze zaprojektowane oraz aby uniknąć marnowania czasu i energii na problemy już rozwiązane przez inne oprogramowanie.
Ale przejdźmy do kwestii technicznych i odpowiedzmy na twoje pytanie:
Dlaczego Unicorn musi zostać wdrożony razem z nginx?
Oto kilka kluczowych powodów:
Unicorn używa blokowania we / wy dla klientów
Poleganie na odwrotnym proxy oznacza, że Unicorn nie musi używać nieblokujących operacji wejścia / wyjścia. Zamiast tego może używać blokowania I / O, co jest z natury prostsze i łatwiejsze do naśladowania przez programistę.
Również, jak stwierdza dokument PROJEKT :
[Używanie blokujących operacji we / wy] pozwala na prostszą ścieżkę kodu w interpreterze Ruby i mniejszą liczbę wywołań systemowych.
Ma to jednak również konsekwencje:
Kluczowy punkt 1: Unicorn nie jest wydajny w przypadku powolnych klientów
(Dla uproszczenia zakładamy konfigurację z 1 pracownikiem jednorożca)
Ponieważ używane jest blokowanie operacji we / wy, pracownik Unicorn może obsługiwać tylko jednego klienta na raz , więc powolny klient (tj. Taki z wolnym połączeniem) efektywnie utrzymywałby pracę roboczą przez dłuższy czas (niż zrobiłby to szybki klient ). W międzyczasie inni klienci po prostu czekali, aż pracownik znów będzie wolny (tj. Żądania będą gromadzić się w kolejce).
Aby obejść ten problem, przed Unicorn wdrażany jest zwrotny serwer proxy, który w pełni buforuje przychodzące żądania i odpowiedzi aplikacji, a następnie wysyła każde z nich na raz (inaczej podaje je łyżką) odpowiednio do Unicorn i klientów. W związku z tym można powiedzieć, że odwrotne proxy „chroni” Unicorn przed powolnymi klientami sieciowymi.
Na szczęście Nginx jest świetnym kandydatem do tej roli, ponieważ jest zaprojektowany do wydajnej obsługi tysięcy setek równoległych klientów.
Niezwykle ważne jest, aby zwrotny serwer proxy znajdował się w tej samej sieci lokalnej co Unicorn (zwykle na tej samej fizycznej maszynie komunikującej się z Unicorn przez gniazdo domeny Unix), tak aby opóźnienie sieci było ograniczone do minimum.
Tak więc taki serwer proxy skutecznie pełni rolę szybkiego klienta, którego Unicorn został zaprojektowany do obsługi w pierwszej kolejności, ponieważ szybko przekazuje żądania do Unicorn i zajmuje pracowników przez możliwie najkrótszy czas (w porównaniu z tym, ile czasu klient z wolnym połączeniem wystarczy).
Kluczowy punkt 2: Unicorn nie obsługuje utrzymywania aktywności HTTP / 1.1
Ponieważ Unicorn używa blokowania we / wy, oznacza to również, że nie może obsługiwać funkcji utrzymywania aktywności HTTP / 1.1, ponieważ trwałe połączenia powolnych klientów szybko zajęłyby wszystkich dostępnych pracowników Unicorn.
Dlatego, aby wykorzystać utrzymywanie aktywności HTTP, zgadnij, co: używany jest odwrotny serwer proxy.
Z drugiej strony nginx może obsługiwać tysiące równoczesnych połączeń przy użyciu zaledwie kilku wątków. Dlatego nie ma ograniczeń współbieżności, jakie ma serwer, taki jak Unicorn (które zasadniczo ograniczają się do liczby procesów roboczych), co oznacza, że może dobrze obsługiwać trwałe połączenia. Więcej informacji o tym, jak to faktycznie działa, można znaleźć tutaj .
Dlatego nginx akceptuje połączenia utrzymujące aktywność od klientów i przekazuje je do Unicorn przez zwykłe połączenia za pośrednictwem zwykle gniazda Unix.
Punkt 3: Unicorn nie radzi sobie zbyt dobrze z serwowaniem plików statycznych
Ponownie, obsługa plików statycznych jest rzeczą, którą Unicorn może zrobić, ale nie jest zaprojektowana do wydajnej pracy.
Z drugiej strony, odwrotne serwery proxy, takie jak nginx, są w tym znacznie lepsze (tj. sendfile(2)
& Buforowanie).
Więcej
Istnieją inne punkty, które zostały zarysowane w dokumencie FILOZOFIA (patrz „Poprawa wydajności dzięki odwrotnemu proxy” ).
Zobacz także niektóre z podstawowych funkcji nginx .
Widzimy, że wykorzystując istniejące oprogramowanie (np. Nginx) i kierując się filozofią Uniksa polegającą na „robieniu jednej rzeczy i rób to dobrze”, Unicorn jest w stanie podążać za prostszym projektem i implementacją, jednocześnie zachowując wydajność w obsłudze aplikacji Rack (np. Twoja aplikacja Rails).
Aby uzyskać więcej informacji, zapoznaj się z filozofią i dokumentami projektowymi Unicorn, które bardziej szczegółowo wyjaśniają wybory stojące za projektem Unicorn i dlaczego nginx jest uważany za dobry odwrotny proxy dla Unicorn.