http modern çağda hayatta kalma


92

Öyleyse, http hakkında bir iki şey bilen haproxy yazarına göre:

Canlı tutma, CPU'lar 100 kat daha yavaşken sunucularda CPU kullanımını azaltmak için icat edildi. Ancak söylenmeyen şey, kalıcı bağlantıların, onları açan müşteri dışında kimse tarafından kullanılamazken çok fazla hafıza tüketmesidir. Bugün 2009'da CPU'lar çok ucuz ve bellek, mimari veya fiyat açısından hala birkaç gigabayt ile sınırlı. Bir sitenin canlı tutulması gerekiyorsa, gerçek bir sorun vardır. Yüksek oranda yüklenmiş siteler, maksimum sayıda eşzamanlı istemciyi desteklemek için genellikle canlı tutma özelliğini devre dışı bırakır. Canlı tutmanın gerçek dezavantajı, nesneleri almak için biraz artan gecikmedir. Tarayıcılar, bunu telafi etmek için canlı olmayan sitelerdeki eşzamanlı bağlantı sayısını ikiye katlar.

( http://haproxy.1wt.eu/ adresinden )

Bu diğer insanların deneyimleriyle uyumlu mu? yani canlı tutma olmadan - sonuç şimdi zar zor farkedilebilir mi? (muhtemelen web soketleri vb. ile - çok duyarlı uygulamalar için her halükarda canlı tutma durumuna bakılmaksızın bir bağlantı "açık" tutulur). Sunucudan uzaktaki kişiler için etki daha mı büyüktür - yoksa bir sayfayı yüklerken aynı ana bilgisayardan yüklenecek çok sayıda yapı varsa? (CSS, resimler ve JS gibi şeylerin giderek önbellek dostu CDN'lerden geldiğini düşünüyorum).

Düşünceler?

(bunun bir serverfault.com olayı olup olmadığından emin değilim, ancak birisi oraya taşımamı söyleyene kadar postayı çaprazlamayacağım).


1
Canlı tutma haproksi belgelerinin başka yerlerinde daha uygun başka terimlerle bahsedildiğini belirtmekte fayda var. İnsanların deneyimlerini duymak isterim, özellikle de toplu ev sahipliği için.
Michael Neale

"Daha iyi tasarlanmış bir web / uygulama sunucusu edinin"? :-) Devamlı (benzer) bağlantı işleme ile daha yeni tasarımlar (Jetty gibi) bellek / iş parçacığı sorunlarını büyük ölçüde azaltır. Ayrıca, "birkaç GB" 2008/2009 sunucu terimine benziyor ;-)

3
Bana twaddle gibi geliyor. Yeni bir soket kurmaya dahil olan ekstra RTT, genellikle bir insan tarafından tespit edilebilecek kadar uzun olan ve bilinen fizik yasaları dahilinde azaltılamayan katı bir fiziksel sınırdır. Tersine, RAM ucuz, daha ucuz hale geliyor ve boşta duran bir soketin birkaç kB'den fazlasını kullanması için hiçbir neden yok.
Will Dean

2
ama ilginç olan, bu sadece teori değil - bu haproxy'nin yazarı. Tüm duyduğum şey teoriler ve varsayımlar.
Michael Neale

Yanıtlar:


142

Bu alıntıyı ben yazdığım için cevap vereceğim :-)

Büyük sitelerde iki büyük sorun vardır: eşzamanlı bağlantılar ve gecikme. Eşzamanlı bağlantı, içeriği indirmek için yaş alan yavaş istemcilerden ve boşta bağlantı durumlarından kaynaklanır. Bu boşta bağlantı durumları, canlı tutma olarak bilinen ve gecikme ile daha da artan birden çok nesneyi getirmek için bağlantının yeniden kullanılmasından kaynaklanır. İstemci sunucuya çok yakın olduğunda, bağlantıyı yoğun bir şekilde kullanabilir ve neredeyse hiçbir zaman boşta kalmamasını sağlayabilir. Ancak dizi bittiğinde, hiç kimse kanalı hızlı bir şekilde kapatmak istemez ve bağlantı uzun süre açık ve kullanılmadan kalır. Birçok insanın çok düşük bir canlı tutma zaman aşımı kullanmayı önermesinin nedeni budur. Apache gibi bazı sunucularda, ayarlayabileceğiniz en düşük zaman aşımı bir saniyedir ve genellikle yüksek yükleri sürdürmek için çok fazladır: Önünüzde 20000 istemciniz varsa ve her saniyede ortalama bir nesne alıyorlarsa, bu 20000 bağlantıyı kalıcı olarak kurmuş olacaksınız. Apache gibi genel amaçlı bir sunucuda 20000 eşzamanlı bağlantı çok büyüktür, hangi modüllerin yüklü olduğuna bağlı olarak 32 ile 64 GB arasında RAM gerektirir ve RAM ekleyerek bile çok daha yükseğe çıkmayı umamazsınız. Pratikte, 20000 istemci için sunucuda 40000 ila 60000 eşzamanlı bağlantı görebilirsiniz çünkü tarayıcılar, getirecek çok sayıda nesneye sahiplerse 2 ila 3 bağlantı kurmaya çalışır. ve muhtemelen RAM ekleyerek çok daha yükseğe çıkmayı umamazsınız. Pratikte, 20000 istemci için sunucuda 40000 ila 60000 eşzamanlı bağlantı görebilirsiniz çünkü tarayıcılar, getirecek çok sayıda nesneye sahiplerse 2 ila 3 bağlantı kurmaya çalışır. ve muhtemelen RAM ekleyerek çok daha yükseğe çıkmayı umamazsınız. Pratikte, 20000 istemci için sunucuda 40000 ila 60000 eşzamanlı bağlantı görebilirsiniz çünkü tarayıcılar, getirecek çok sayıda nesneye sahiplerse 2 ila 3 bağlantı kurmaya çalışır.

Her nesneden sonra bağlantıyı kapatırsanız, eşzamanlı bağlantıların sayısı önemli ölçüde düşer. Aslında, nesneler arasındaki süreye göre bir nesneyi indirmek için ortalama süreye karşılık gelen bir faktör kadar düşecektir. Bir nesneyi (minyatür bir fotoğraf, bir düğme vb.) İndirmek için 50 ms'ye ihtiyacınız varsa ve yukarıdaki gibi saniyede ortalama 1 nesne indirirseniz, istemci başına yalnızca 0,05 bağlantınız olur, bu yalnızca 1000'dir. 20000 istemci için eşzamanlı bağlantılar.

Şimdi yeni bağlantılar kurma zamanı sayılacak. Uzak istemciler hoş olmayan bir gecikme yaşayacaktır. Geçmişte, tarayıcılar canlı tutma devre dışı bırakıldığında büyük miktarda eşzamanlı bağlantı kullanıyordu. MSIE'de 4 ve Netscape'te 8 rakamlarını hatırlıyorum. Bu, gerçekten nesne başına ortalama gecikmeyi bu kadar bölerdi. Artık canlı tutma her yerde mevcut olduğuna göre, artık bu yüksek sayıları görmüyoruz çünkü bunu yapmak uzak sunuculardaki yükü daha da artırıyor ve tarayıcılar İnternet altyapısını korumaya özen gösteriyor.

Bu, günümüz tarayıcılarında, canlı tutma hizmetlerini canlı tutma hizmetleri kadar duyarlı hale getirmenin daha zor olduğu anlamına gelir. Ayrıca, bazı tarayıcılar (örneğin: Opera) ardışık düzeni kullanmayı denemek için buluşsal yöntemler kullanır. Ardışık düzen, canlı tutma özelliğini kullanmanın etkili bir yoludur, çünkü bir yanıt beklemeden birden çok istek göndererek gecikmeyi neredeyse ortadan kaldırır. 100 küçük fotoğraf içeren bir sayfada denedim ve ilk erişim, canlı tutma olmadan yaklaşık iki kat daha hızlı, ancak sonraki erişim yaklaşık 8 kat daha hızlı, çünkü yanıtlar o kadar küçük ki yalnızca gecikme önemlidir (yalnızca "304" yanıtları).

İdeal olarak, tarayıcılarda, getirilen nesneler arasındaki bağlantıları canlı tutmaları ve sayfa tamamlandığında hemen bırakmaları için bazı ayarlara sahip olmamız gerektiğini söyleyebilirim. Ama maalesef bunu görmüyoruz.

Bu nedenle, ön tarafa Apache gibi genel amaçlı sunucular kurması gereken ve büyük miktarda istemciyi desteklemesi gereken bazı siteler, genellikle canlı tutma özelliğini devre dışı bırakmak zorundadır. Ve tarayıcıları bağlantı sayısını artırmaya zorlamak için, indirmelerin paralelleştirilebilmesi için birden çok alan adı kullanırlar. Bu özellikle yoğun SSL kullanan sitelerde sorunludur, çünkü ek bir gidiş dönüş olduğu için bağlantı kurulumu daha da yüksektir.

Günümüzde daha sık gözlemlenen şey, bu tür sitelerin on ila yüzbinlerce eşzamanlı bağlantıyla ilgili hiçbir problemi olmayan haproxy veya nginx gibi hafif ön uçlar kurmayı tercih etmeleri, istemci tarafında canlı tutmayı etkinleştirmeleri ve bunu devre dışı bırakmalarıdır. Apaçi tarafı. Bu tarafta, bir bağlantı kurmanın maliyeti CPU açısından neredeyse sıfırdır ve zaman açısından hiç fark edilmez. Bu şekilde bu, her iki dünyanın da en iyisini sağlar: İstemci tarafında çok düşük zaman aşımları ile canlı tutma nedeniyle düşük gecikme ve sunucu tarafında düşük bağlantı sayısı. Herkes mutlu :-)

Bazı ticari ürünler, ön yük dengeleyici ile sunucu arasındaki bağlantıları yeniden kullanarak ve tüm istemci bağlantılarını bunlar üzerinden çoklayarak bunu daha da iyileştirir. Sunucular LB'ye yakın olduğunda, kazanç önceki çözümden çok daha yüksek değildir, ancak birden çok kullanıcı arasında beklenmedik bir bağlantı paylaşımı nedeniyle kullanıcılar arasında oturum geçişi riski olmadığından emin olmak için genellikle uygulamada uyarlamalar gerektirir. . Teoride bu asla olmamalı. Gerçek çok farklı :-)


1
Tam ve kapsamlı cevap için teşekkürler! Hayatta kalmayla ilgili sayfadaki çeşitli yorumlar kafamı biraz karıştırdı - ama bunların hepsi mantıklı.
Michael Neale

İlginç bir şekilde - Linux üzerinde Chrome'un birkaç saniye boyunca canlı tutulan bir bağlantıyı yeniden kullandığını gözlemledim - yani başka bir sekme açmak için geçen süre - bu diğer sekme farklı bir ana bilgisayar adındaydı, ancak DNS joker karakteriyle aynı sunucuya çözüldü (toplu sanal barındırma) - ve böylece aynı bağlantıyı yeniden kullandı! (bu beni biraz şaşırttı, iyi bir tür değil - tabii ki hayatta kalmak sadece müşteri tarafı ise sorun değil).
Michael Neale

Tek duyduğum "apache'den başka bir şey kullanmak ve bu önemli bir şey değil" oldu. Tahmin ettiğim şey "mod_php ve yolcuları devre dışı bırak, sonra apache'nin bile bir mücadele şansı olabilir" idi.
coolaj86

@ CoolAJ86: Önemli olan kesinlikle Apache'ye eziyet etmek değil ve ben şahsen kullanıyorum. Önemli olan, sunucu ne kadar genel olursa, ölçeklemeniz gereken en az seçeneğin olmasıdır. Bazı modüller çatal öncesi modeli gerektirir, bu durumda çok sayıda bağlantıya ölçeklenemezsiniz. Ancak açıklandığı gibi, haproksi gibi başka bir ücretsiz bileşenle birleştirebileceğiniz için bu büyük bir sorun değil. Bu durumda neden kimse her şeyin yerini alsın? Uygulamanızı başka bir sunucu kullanarak yeniden uygulama zahmetine girmektense haproxy'yi kurun!
Willy Tarreau

22

Bunun yazılmasından (ve burada stackoverflow'a gönderilmesinden) bu yana geçen yıllarda, artık popülerliği artan nginx gibi sunucularımız var.

Örneğin nginx, yalnızca 2,5 MB (megabayt) RAM ile tek bir işlemde 10.000 açık canlı tutma bağlantısını tutabilir. Aslında, çok az RAM ile birden çok binlerce bağlantıyı açık tutmak kolaydır ve vuracağınız tek sınır, açık dosya tanıtıcılarının sayısı veya TCP bağlantıları gibi diğer sınırlar olacaktır.

Canlı tutma, canlı tutma spesifikasyonunun kendisiyle ilgili herhangi bir sorundan değil, Apache'nin süreç tabanlı ölçeklendirme modeli ve mimarisi onu barındıracak şekilde tasarlanmamış bir sunucuya hacklenen canlı tutma nedeniyle bir sorundu.

Özellikle sorunlu olan Apache Prefork + mod_php + canlı tutma. Bu, her bir bağlantının, tamamen boşta olsa ve yalnızca canlı tutma olarak açık kalsa bile, bir PHP işleminin kapladığı tüm RAM'i işgal etmeye devam edeceği bir modeldir. Bu ölçeklenebilir değil. Ancak sunucuların bu şekilde tasarlanması gerekmez - bir sunucunun her canlı tutma bağlantısını ayrı bir işlemde tutması için özel bir neden yoktur (özellikle bu tür her işlemin tam bir PHP yorumlayıcısı olduğunda). PHP-FPM ve nginx'teki gibi olay tabanlı bir sunucu işleme modeli sorunu zarif bir şekilde çözer.

2015 Güncellemesi:

SPDY ve HTTP / 2, HTTP'nin canlı tutma işlevini daha da iyi bir şeyle değiştirir: yalnızca bir bağlantıyı canlı tutma ve üzerinden birden çok istek ve yanıt verme yeteneği değil, aynı zamanda yanıtların herhangi bir sırayla gönderilebilmesi için çoğaltılması ve yalnızca talep edilen sırayla değil, paralel olarak. Bu, yavaş yanıtların daha hızlı olanları engellemesini önler ve tarayıcıların tek bir sunucuya birden çok paralel bağlantı açık tutma eğilimini ortadan kaldırır. Bu teknolojiler ayrıca mod_php yaklaşımının yetersizliklerini ve PHP-FPM gibi bir şeyle ayrı ayrı birleştirilen olay tabanlı (veya en azından çok iş parçacıklı) bir web sunucusu gibi bir şeyin faydalarını vurgulamaktadır.


2

Anladığım kadarıyla CPU ile çok az ilgisi vardı, ancak tekrar eden soketlerin dünyanın diğer tarafına açılmasındaki gecikme. Sonsuz bant genişliğiniz olsa bile, bağlantı gecikmesi tüm süreci yavaşlatacaktır. Sayfanızda düzinelerce nesne varsa büyütülür. Kalıcı bir bağlantının bile bir istek / yanıt gecikmesi vardır, ancak ortalama olarak 2 soketiniz olduğunda azalır, biri veri akışı yaparken diğeri engelliyor olabilir. Ayrıca, bir yönlendirici, yazmanıza izin vermeden önce bir soketin bağlandığını varsaymaz. Tam gidiş-dönüş anlaşmasına ihtiyacı var. Yine, uzman olduğumu iddia etmiyorum, ama bunu hep böyle görüyorum. gerçekten harika olan şey tamamen ASYNC protokolüdür (hayır, tamamen hasta bir protokol değil).


evet - bu benim varsayımım olurdu. belki bu bir değiş tokuş - gecikmenin (mesafeden dolayı) gerçek bir sorun olduğu anlamına geldiği bir nokta var
Michael Neale

Tamam, bu nedenle modern tipografi yakında (belki) bir proxy'ye bağlanmanızı sağlar. ama sonra soruyu proxy'lerin kalıcı bağlantılar kullanması gerekip gerekmediğine mi genişletiyorsunuz?
catchpolenet

@Michael Neale ayrıca, TCP yavaş başlatma gibi şeyler nedeniyle, gerçek gecikme cezası beklediğinizden çok daha kötü.
MartinodF

belki de değiş tokuş çok daha kısa bir zaman aşımı süresidir. yedeklenen talepleriniz varsa, neden soketi kapatıp yeniden başlayın? 1 saniye bile bir sayfanın tam kalıcılıkla yüklenmesine izin verir ve ardından hemen ardından soketleri kapatır.
catchpolenet

2

CloudFront veya CloudFlare gibi bir "kaynak çekme" CDN kullanıyorsanız, çok uzun süre canlı tutma yararlı olabilir. Aslında, tamamen dinamik içerik sunuyor olsanız bile bu, hiç CDN olmamasından daha hızlı olabilir.

Her bir PoP'nin sunucunuzla temelde kalıcı bir bağlantısı olacak şekilde uzun süre hayatta kalırsanız, kullanıcılar sitenizi ilk kez ziyaret ettiklerinde, sizinle yavaş bir el sıkışma yerine yerel PoP'ları ile hızlı bir TCP anlaşması yapabilirler. (Light'ın fiber aracılığıyla dünyanın yarısına gelmesi yaklaşık 100 ms sürer ve bir TCP bağlantısı kurmak, üç paketin ileri geri aktarılmasını gerektirir . SSL, üç gidiş- dönüş gerektirir .)


1
+1 almak istedim, ancak ikinci paragrafınızda bu yanlış ışık notu var, dünyanın yarısını dolaşması yalnızca 10 ms sürüyor. Vakumda 10 ms'lik ışık hızı 3000 km'dir ve bir fiberde 10 ms'lik ışık hızı 2000 km'den fazla değildir; dünyanın yarı yolu (yüzey boyunca) 20.000 km'dir. Yani bu 100 ms olurdu - eğer fiberiniz Afrika'yı deniz yoluyla dolaşmak veya Hawaii'den uzun bir rota almak yerine doğrudan Londra'dan Sidney'e gitse ...
piramitler

@pyramids Haklısın, ya bunu yazdım ya da sadece saçmaladım. Güncellenecek.
mjs
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.