Web sunucuları IP adreslerini nasıl dinler, keser ya da oy kullanır?


87

Web sunucularının daha düşük ayrıntılarını anlamaya çalışıyorum. Bir sunucunun Apache'nin yeni talepler için sürekli oylamada mı olduğunu yoksa bir kesme sistemi tarafından mı çalıştığını merak ediyorum. Bir kesinti ise, kesinti neyin yol açtığı, ağ kartı sürücüsü mü?


1
Anlaşılacak anahtar kelime "sunucu" dur . Sunucu-istemci modelinde (master-slave modeline göre) sunucu istemcilerden gelen istekleri bekler . Bu istekler, hizmet edilmesi gereken olaylardır . Bir web sunucusu bir uygulama programıdır. Sorunuz, ilgili kavramları aynı soyutlama katmanında tutmak yerine, uygulama SW'ı HW terminolojisiyle (örneğin, kesme ve NIC) birleştirir. NIC sürücüsü aslında bazen yoklama kullanabilir, örneğin Linux NAPI sürücüleri bir paket sel olduğunda yoklama için geriler. Ancak, olay işleme uygulaması SW ile alakasızdır.
talaş

1
@ sawdust Çok ilginç. Buradaki soru aslında SW ve HW işlemleri arasındaki bağlantıyı anlamak içindir
user2202911

1
Komut satırı (ve diğer GUI) programlarının klavyeyi dinleme biçimine çok benzer. Özellikle, çekirdeğin klavye cihazından veri alma ve odağı olan ve o pencereye veri veren pencereyi tanımlayan pencere yöneticisine devretme adımına sahip olduğunuz bir pencere sisteminde.
G-Man

@ G-Man: Teori, evet. Gerçekte çoğu daktilo, iki farklı mimariye sahip olmayı haklı kılan 1 Gbit / s'de yazmaz. Biri temiz, esnek ve yavaş, biri sakar ama çok hızlı.
MSalters

Yanıtlar:


181

Kısa cevap: bir çeşit kesme sistemi. Temel olarak, engelleme giriş / çıkışını kullanırlar, yani yeni veri beklerken uyurlar (bloklar).

  1. Sunucu bir dinleme soketi oluşturur ve yeni bağlantılar beklerken engellenir. Bu süre zarfında, çekirdek, işlemi kesilebilir bir uyku durumuna geçirir ve diğer işlemleri yürütür. Bu önemli bir nokta: Sürecin sürekli araştırılmasını sağlamak CPU'yu boşa harcar. Çekirdek, yapılması gereken işler olana kadar süreci engelleyerek sistem kaynaklarını daha verimli bir şekilde kullanabilir.

  2. Ağa yeni veriler geldiğinde, ağ kartı bir kesinti verir.

  3. Ağ kartında bir kesinti olduğunu görünce, çekirdek, ağ kartı sürücüsü aracılığıyla, yeni verileri ağ kartından okur ve hafızaya kaydeder. (Bu hızlı yapılmalı ve genellikle kesme işleyicisinin içinde ele alınmalıdır.)

  4. Çekirdek yeni gelen verileri işler ve onu bir soketle ilişkilendirir. Bu soketi bloke eden bir işlem çalıştırılabilir olarak işaretlenecek, bu da artık çalıştırılmaya uygun olduğu anlamına gelecektir. Mutlaka derhal çalıştırılmaz (çekirdek hala diğer işlemleri yapmaya karar verebilir).

  5. Boş zamanlarında, çekirdek engellenen web sunucusu işlemini uyandıracak. (Şimdi çalıştırılabilir olduğundan.)

  6. Web sunucusu işlemi, zaman geçmemiş gibi yürütülmesine devam eder. Engelleme sistemi çağrısı geri döner ve yeni verileri işler. Ardından ... 1. adıma gidin.


18
Web sunucusu işlemine karşı çekirdeğin net açıklaması için +1.
Russell Borogove

13
Bunun kadar net ve basit bir şekilde özetlenebileceği kadar karmaşık bir şeye inanamıyorum, ama siz yaptınız. +1
Brandon

8
+1 Harika cevap. Ayrıca, 2 ile 3 arasındaki adımlar, modern NIC'ler, işletim sistemleri ve sürücülerle biraz daha karmaşık hale gelebilir. Örneğin, Linux'taki NAPI ile, paketler aslında kesme bağlamında alınmaz. Bunun yerine, çekirdek "Tamam NIC, veri sahibi olduğunuzu anlıyorum. Beni rahatsız etmekten vazgeç (kesme kaynağını devre dışı bırak)" diyor ve bu paketi ve benden önce gelebilecek tüm paketleri almaya kısa bir süre sonra döneceğim .
Jonathon Reinhart

8
Hafif nitpick: Gerçekten bloke etmek gerekmez. Sunucu işlemi bir dinleme soketi oluşturduğunda, çekirdek, engellenmiş olmasanız bile, o bağlantı noktasında SYN'leri kabul eder accept. Onlar (neyse ki, ya da tamamen emmek!) Bağımsız, asenkron çalışan görevlerdir. Bağlantılar gelirken, acceptonları çeken bir kuyruğa yerleştirilirler . Sadece hiçbiri yoksa, engeller.
Damon

3
“yeni verileri ağ kartından okur ve hafızaya kaydeder. (Bu hızlı bir şekilde yapılmalı ve genellikle kesme işleyicisinin içinde ele alınmalıdır.)” Doğrudan hafıza erişimiyle yapılmadı mı?
Siyuan Ren

9

Oldukça fazla "daha düşük" ayrıntı var.

Öncelikle, çekirdeğin bir işlem listesine sahip olduğunu ve herhangi bir zamanda bu işlemlerin bazılarının çalıştığını ve bazılarının çalışmadığını düşünün. Çekirdek, çalışan her bir işlemin bir dilim CPU zamanına izin verir, sonra keser ve bir sonrakine geçer. Çalıştırılabilir işlem yoksa, çekirdek muhtemelen bir donanım kesintisi gerçekleşene kadar CPU'yu askıya alan CPU'ya HLT gibi bir komut verecektir .

Sunucuda bir yerde "bana yapacak bir şeyler ver" yazan bir sistem çağrısı var. Bunun yapılabileceği iki geniş yol kategorisi vardır. Apache durumunda, Apache'nin acceptdaha önce açmış olduğu, muhtemelen 80 numaralı bağlantı noktasını dinleyen bir sokete çağrı yapar. Çekirdek, bir bağlantı girişimi sırasını korur ve her TCP SYN aldığında bu kuyruğa ekler . Çekirdeğin bir TCP SYN'nin alındığını bildiği aygıt sürücüsüne bağlıdır; Birçok NIC için, ağ verileri alındığında muhtemelen bir donanım kesintisi vardır.

acceptçekirdeğin bir sonraki bağlantı başlangıcında bana dönmesini ister. Sıra boş değilse, accepthemen geri döner. Sıra boşsa, işlem (Apache) çalışan işlemler listesinden kaldırılır. Bir bağlantı daha sonra başlatıldığında, işlem sürdürülür. Buna "engelleme" denir, çünkü onu çağıran işlem accept()için, bir süre sonra ortaya çıkacak olana kadar geri dönmeyen bir işleve benziyor. Bu süre zarfında işlem başka hiçbir şey yapamaz.

Bir kez acceptdöndüğünde, Apache birisinin bir bağlantı kurmaya çalıştığını biliyor. Daha sonra Apache işlemini iki özdeş işlemle bölmek için çatal çağırır . Bu işlemlerden biri HTTP isteğini işlemeye devam eder, diğeri bir acceptsonraki bağlantıyı almak için tekrar arar . Bu nedenle, her zaman acceptalt işlemleri çağırma ve yumurtlama dışında hiçbir şey yapmayan bir ana işlem vardır ve ardından her istek için bir alt işlem vardır.

Bu bir sadeleştirmedir: Bunu işlem yerine iş parçacığıyla yapmak mümkündür ve forkönceden bir işlem yapılması mümkündür , bu nedenle bir istek alındığında hazır bir çalışan işlem vardır, böylece başlangıç ​​ek yükünü azaltır. Apache'nin nasıl yapılandırıldığına bağlı olarak, bunların her ikisini de yapabilir.

İşte bunu nasıl ilk geniş bir kategori, ve denir IO engelleme sistemi gibi çağrılarının acceptve readve writeonlar dönmek için bir şey var kadar işlemi askıya alacaktır yuvalarına üzerinde faaliyet gösterdikleri.

Bunu yapmanın diğer geniş yolu engelleyici olmayan veya olay temelli veya asenkron IO olarak adlandırılır . Bu, selectveya benzeri sistem çağrıları ile uygulanır epoll. Bunların her biri aynı şeyi yapar: onlara bir yuva listesi (veya genel olarak dosya tanımlayıcıları) ve onlarla ne yapmak istediğinizi ve çekirdek bunlardan birini yapmaya hazır olana kadar blokları verir.

Bu modelle, çekirdeğe (ile epoll), "Bağlantı noktası 80'de yeni bir bağlantı olduğunda bana söyle veya açmış olduğum bu 9471 diğer bağlantılardan herhangi birini okumak için yeni veriler olduğunda" diyebilirsiniz. epollbunlardan biri hazır olana kadar engeller, sonra sen yaparsın. O zaman tekrar et. Sistem çağrıları gibi acceptve readve writeblok, kısmen bunları istediğim zaman, çünkü hiçbir zaman epollsadece engellemek için hiçbir neden yoktur olurdu böylece hazır olduklarını ve soket veya belirttiğiniz dosyayı açtığınızda bunları istediğiniz nedeniyle de söylemiştim engelleme modundayken, bu çağrılar EWOULDBLOCKengelleme yerine başarısız olur .

Bu modelin avantajı, sadece bir sürece ihtiyaç duymanızdır. Bu, her istek için bir yığın ve çekirdek yapıları ayırmanız gerekmediği anlamına gelir. Nginx ve HAProxy bu modeli kullanıyor ve benzer donanımdaki Apache'den çok daha fazla bağlantıyla başa çıkabilmelerinin büyük bir nedeni.

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.