天天看點

Apache三種多路處理子產品(prework 、worker、event模式)總結

 prefork模式:Apache在啟動之初,就預先fork一些子程序,然後等待請求進來。之是以這樣做,是為了減少頻繁建立和銷毀程序的開銷。每個子程序隻有一個線程,在一個時間點内,隻能處理一個請求。

優點:成熟穩定,相容所有新老子產品。同時,不需要擔心線程安全的問題。(我們常用的mod_php,PHP的拓展不需要支援線程安全)

缺點:一個程序占有更多的資源,消耗記憶體。不擅長處理高并發的請求,在這種情況下,将請求放入隊列,直到有可以處理的程序。

Apache的httpd.conf中的配置方式:

<IfModulempm_prefork_module>

    StartServers             5

    MinSpareServers          5

    MaxSpareServers         10

    MaxRequestWorkers      250

    MaxConnectionsPerChild   0

</IfModule>

prefork 控制程序在最初建立“StartServers”個子程序後,為了滿足MinSpareServers設定的需要建立一個程序,等待一秒鐘,繼續建立兩個,再等待一秒鐘,繼續建立四個……如此按指數級增加建立的程序數,最多達到每秒32個,直到滿足MinSpareServers設定的值為止。這種模式 可以不必在請求到來時再産生新的程序,進而減小了系統開銷以增加性能。

MaxSpareServers設定了最大的空閑程序數,如果空閑程序數大于這個值,Apache會自動kill掉一些多餘程序。這個值不要設得過大,但如果設的值比MinSpareServers小,Apache會自動把其調整為 MinSpareServers+1。如果站點負載較大,可考慮同時加大MinSpareServers和MaxSpareServers。 

  MaxRequestsPerChild設定的是每個子程序可處理的請求數。每個子程序在處理了“MaxRequestsPerChild”個請求後将自動銷毀。0意味着無限,即子程序永不銷毀。雖然預設設為0可以使每個子程序處理更多的請求,但如果設成非零值也有兩點重要的好處:

1、可防止意外的記憶體洩漏。2、在伺服器負載下降的時侯會自動減少子程序數。

是以,可根據伺服器的負載來調整這個值。

  MaxRequestWorkers指令集同時将服務請求的數量上的限制。任何連接配接嘗試在MaxRequestWorkerslimit将通常被排隊,最多若幹基于上ListenBacklog指令。

在apache2.3.13以前的版本MaxRequestWorkers被稱為MaxClients 。

(MaxClients是這些指令中最為重要的一個,設定的是 Apache可以同時處理的請求,是對Apache性能影響最大的參數。其預設值150是遠遠不夠的,如果請求總數已達到這個值(可通過ps -ef|grephttp|wc -l來确認),那麼後面的請求就要排隊,直到某個已處理請求完畢。這就是系統資源還剩下很多而HTTP通路卻很慢的主要原因。雖然理論上這個值越大,可以處理的請求就越多,但Apache預設的限制不能大于256。)

worker模式:是使用了多程序和多線程的混合模式。它也預先fork了幾個子程序(數量比較少),然後每個子程序建立一些線程,同時包括一個監聽線程。每個請求過來,會被配置設定到1個線程來服務。線程比起程序會更輕量,因為線程通常會共享父程序的記憶體空間,是以,記憶體的占用會減少一些。在高并發的場景下,因為比起prefork有更多的可用線程,表現會更優秀一些。

有些人會覺得奇怪,那麼這裡為什麼不完全使用多線程呢,還要引入多程序?

原因主要是需要考慮穩定性,如果一個線程異常挂了,會導緻父程序連同其他正常的子線程都挂了(它們都是同一個程序下的)。為了防止這場異常場景出現,就不能全部使用線程,使用多個程序再加多線程,如果某個線程出現異常,受影響的隻是Apache的一部分服務,而不是整個服務。

優點:占據更少的記憶體,高并發下表現更優秀。

缺點:必須考慮線程安全的問題,因為多個子線程是共享父程序的記憶體位址的。如果使用keep-alive的長連接配接方式,某個線程會一直被占據,也許中間幾乎沒有請求,需要一直等待到逾時才會被釋放。如果過多的線程,被這樣占據,也會導緻在高并發場景下的無服務線程可用。(該問題在prefork模式下,同樣會發生)

注:keep-alive的長連接配接方式,是為了讓下一次的socket通信複用之前建立的連接配接,進而,減少連接配接的建立和銷毀的系統開銷。保持連接配接,會讓某個程序或者線程一直處于等待狀态,即使沒有資料過來。

<IfModulempm_worker_module>

    StartServers             3

    MinSpareThreads         75

    MaxSpareThreads        250

    ThreadsPerChild         25

    MaxRequestWorkers      400

# StartServers:  初始數量的伺服器程序開始

#MinSpareThreads:  最小數量的工作線程,儲存備用

#MaxSpareThreads:  最大數量的工作線程,儲存備用

#ThreadsPerChild:  固定數量的工作線程在每個伺服器程序

# MaxRequestWorkers:  最大數量的工作線程

#MaxConnectionsPerChild:  最大連接配接數的一個伺服器程序服務

  Worker 由主要制程序生成“StartServers”個子程序,每個子程序中包含固定的ThreadsPerChild線程數,各個線程獨立地處理請求。同樣,為了不在請求到來時再生成線程,MinSpareThreads和MaxSpareThreads設定了最少和最多的空閑線程數;

  而MaxRequestWorkers設定了同時連入的clients最大總數。如果現有子程序中的線程總數不能滿足負載,控制程序将派生新的子程序

  MinSpareThreads和 MaxSpareThreads的最大預設值分别是75和250。這兩個參數對Apache的性能影響并不大,可以按照實際情況相應調節。

  ThreadsPerChild是worker MPM中與性能相關最密切的指令。ThreadsPerChild的最大預設值是64,如果負載較大,64也是不夠的。這時要顯式使用 ThreadLimit指令,它的最大預設值是20000。

  Worker模式下所能同時處理的請求總數是由子程序總數乘以ThreadsPerChild 值決定的,應該大于等于MaxRequestWorkers。如果負載很大,現有的子程序數不能滿足時,控制程序會派生新的子程序。預設最大的子程序總數是16,加大時 也需要顯式聲明ServerLimit(最大值是20000)。需要注意的是,如果顯式聲明了ServerLimit,那麼它乘以 ThreadsPerChild的值必須大于等于MaxRequestWorkers,而且MaxRequestWorkers必須是ThreadsPerChild的整數倍,否則 Apache将會自動調節到一個相應值。

 event MPM 模式:

這個是Apache中最新的模式,在現在版本裡的已經是穩定可用的模式。它和worker模式很像,最大的差別在于,它解決了keep-alive場景下,長期被占用的線程的資源浪費問題(某些線程因為被keep-alive,空挂在哪裡等待,中間幾乎沒有請求過來,甚至等到逾時)。event MPM中,會有一個專門的線程來管理這些keep-alive類型的線程,當有真實請求過來的時候,将請求傳遞給服務線程,執行完畢後,又允許它釋放。這樣增強了高并發場景下的請求處理能力。

     本文轉自wsw26 51CTO部落格,原文連結:http://blog.51cto.com/wsw26/1750699,如需轉載請自行聯系原作者