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 accept
daha ö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, accept
hemen 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 accept
dö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 accept
sonraki bağlantıyı almak için tekrar arar . Bu nedenle, her zaman accept
alt 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 accept
ve read
ve write
onlar 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, select
veya 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. epoll
bunlardan biri hazır olana kadar engeller, sonra sen yaparsın. O zaman tekrar et. Sistem çağrıları gibi accept
ve read
ve write
blok, kısmen bunları istediğim zaman, çünkü hiçbir zaman epoll
sadece 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 EWOULDBLOCK
engelleme 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.