Bu cevap diğerini tamamlar ve neden Unicorn'un önünde nginx'e ihtiyaç duyduğunu açıklar .
TL; DR Unicorn'un genellikle nginx gibi bir ters proxy ile birlikte konuşlandırılmasının nedeni, yaratıcılarının bunu kasıtlı olarak tasarlaması ve basitlik için bir ödün vermesidir.
Her şeyden önce, Unicorn'u ters proxy olmadan dağıtmaktan alıkoyan hiçbir şey yok . Ancak, bu çok iyi bir fikir olmazdı; neden olduğunu görelim.
Unicorn, bir şeyi yapmak ve iyi yapmak olan Unix felsefesini takip eder ve bu da hızlı, düşük gecikmeli istemcilere hizmet etmek demektir (bunun daha sonra ne anlama geldiğini göreceğiz). Unicorn'un hızlı, düşük gecikmeli istemciler için tasarlanması , aynı zamanda yavaş, yüksek gecikmeli istemciler için çok iyi olmadığını ima eder, bu gerçekten doğrudur. Bu, Unicorn'un zayıf noktalarından biridir ve ters bir proxy'nin devreye girdiği yer: Unicorn'un önünde oturur ve bu yavaş müşterilere bakar ( daha sonra nasıl olacağını göreceğiz ).
Neyse ki, böyle bir ters proxy zaten var ve buna nginx deniyor .
Sadece hızlı istemcileri yönetme kararı, Unicorn'un tasarımını büyük ölçüde basitleştirir ve dağıtım departmanında bazı ek karmaşıklık pahasına çok daha basit ve daha küçük bir kod tabanına izin verir (yani, Unicorn'a ek olarak nginx'i de dağıtmanız gerekir).
Alternatif bir karar, Unicorn'u ters bir proxy'ye ihtiyaç duymayacak şekilde tasarlamak olabilir. Bununla birlikte, bu, nginx'in şimdi yaptığı her şeyi yapmak için ekstra işlevsellik uygulamak zorunda kalacağı anlamına gelir ve bu da daha karmaşık bir kod tabanı ve daha fazla mühendislik çabası ile sonuçlanır.
Bunun yerine yaratıcıları, savaş testlerinden geçmiş ve çok iyi tasarlanmış mevcut yazılımlardan yararlanma ve diğer yazılımlar tarafından halihazırda çözülmüş sorunlarda zaman ve enerji kaybını önleme kararı aldı.
Ama teknik olarak alalım ve sorunuza cevap verelim:
Unicorn neden nginx ile birlikte dağıtılmalı?
İşte bazı temel nedenler:
Unicorn, istemciler için engelleme G / Ç kullanır
Ters bir proxy'ye güvenmek, Unicorn'un engellemeyen G / Ç kullanmasına gerek olmadığı anlamına gelir . Bunun yerine, programcının takip etmesi doğal olarak daha basit ve daha kolay olan engelleme G / Ç'yi kullanabilir.
Ayrıca DESIGN belgesinde belirtildiği gibi:
[Bloke G / Ç kullanılması] Ruby yorumlayıcısında daha basit bir kod yolunun ve daha az sistem çağrısının izlenmesini sağlar.
Bununla birlikte, bunun bazı sonuçları da vardır:
Anahtar nokta # 1: Unicorn yavaş müşterilerle verimli değil
(Basitlik adına, 1 Unicorn çalışanı ile bir kurulum varsayıyoruz)
Engelleme G / Ç kullanıldığından, bir Unicorn çalışanı aynı anda yalnızca bir istemciye hizmet verebilir , bu nedenle yavaş bir istemci (yavaş bağlantıya sahip bir istemci), işçiyi daha hızlı bir şekilde meşgul eder (hızlı bir istemciden daha uzun süre) ). Bu arada, diğer müşteriler sadece işçi tekrar serbest olana kadar beklerdi (yani, talepler kuyrukta birikir).
Bu sorunun üstesinden gelmek için, gelen istekleri ve uygulama yanıtlarını tam olarak arabelleğe alan Unicorn'un önüne bir ters proxy dağıtılır ve her birini sırasıyla bir kerede (diğer adıyla kaşıkla besler) Unicorn ve istemcilere gönderir . Bu bağlamda, ters proxy'nin Unicorn'u yavaş ağ istemcilerinden koruduğunu söyleyebilirsiniz.
Neyse ki Nginx bu rol için harika bir aday çünkü binlerce yüzlerce eşzamanlı müşteriyi verimli bir şekilde ele almak için tasarlandı.
Ters proxy'nin Unicorn ile aynı yerel ağda (genellikle Unix etki alanı soketi aracılığıyla Unicorn ile iletişim kuran aynı fiziksel makinede) olması çok önemlidir, böylece ağ gecikmesi minimumda tutulur.
Böylece böyle bir proxy , Unicorn'un ilk etapta hizmet etmek üzere tasarlandığı hızlı bir müşterinin rolünü etkili bir şekilde oynar , çünkü Unicorn'a hızlı bir şekilde istekte bulunur ve işçileri mümkün olan en kısa sürede meşgul eder (bir müşterinin ne kadar zamana kıyasla) yavaş bir bağlantı ile).
Anahtar nokta # 2: Unicorn HTTP / 1.1 canlı kalmayı desteklemiyor
Unicorn engelleme G / Ç kullandığından, aynı zamanda HTTP / 1.1 canlı tutma özelliğini destekleyemeyeceği anlamına gelir, çünkü yavaş istemcilerin sürekli bağlantıları mevcut tüm Unicorn işçilerini hızla işgal eder.
Bu nedenle HTTP canlı tutma özelliğinden yararlanmak için ne olduğunu tahmin edin: ters proxy kullanılır.
Öte yandan nginx, sadece birkaç iş parçacığı kullanarak binlerce eşzamanlı bağlantıyı işleyebilir. Bu nedenle, Unicorn gibi bir sunucunun eşzamanlılık limitleri yoktur (bu aslında çalışan süreçlerin miktarıyla sınırlıdır), bu da kalıcı bağlantıları gayet iyi idare edebileceği anlamına gelir. Bunun gerçekte nasıl çalıştığına dair daha fazla bilgiyi burada bulabilirsiniz .
Bu nedenle nginx, istemcilerden canlı tutma bağlantılarını kabul eder ve tipik olarak bir Unix soketi aracılığıyla düz bağlantılar üzerinden Unicorn'a vekalet eder.
Nokta # 3: Unicorn statik dosyaları sunmakta çok iyi değil
Yine, statik dosyaların sunulması Unicorn'un yapabileceği bir şeydir, ancak verimli bir şekilde yapmak için tasarlanmamıştır.
Öte yandan, nginx gibi ters proxy'ler de çok daha iyidir (yani. sendfile(2)
& Önbellekleme).
Daha
PHILOSOPHY belgesinde belirtilen başka noktalar da vardır (bkz. "Ters Proxy ile Geliştirilmiş Performans" ).
Ayrıca nginx'in bazı temel özelliklerine bakın .
Mevcut yazılımdan (yani nginx) yararlanarak ve Unix'in "bir şeyi yapma ve iyi yapma" felsefesini takip ederek Unicorn'un Rack uygulamalarına (ör. Rails uygulamanız).
Daha fazla bilgi için Unicorn'un tasarımının ardındaki seçenekleri ve nginx'in Unicorn için neden iyi bir ters proxy olarak kabul edildiğini açıklayan Unicorn'un felsefesine ve tasarım belgelerine bakın .