生產環境 Apache 和 php 配置優化(一)

 

多處理模塊(MPM)

    Apache HTTP 服務器被設計爲一個功能強大,而且靈活的 web 服務器, 能夠在不少平臺與環境中工做。不一樣平臺和不一樣的環境每每須要不一樣的特性,或可能以不一樣的方式實現相同的特性最有效率。Apache httpd 經過模塊化的設計來適應各類環境。這種設計容許網站管理員經過在 編譯時或運行時,選擇哪些模塊將會加載在服務器中,來選擇服務器特性。php

    Apache HTTP 服務器 2.0 擴展此模塊化設計到最基本的 web 服務器功能。 它提供了能夠選擇的多處理模塊(MPM),用來綁定到網絡端口上,接受請求, 以及調度子進程處理請求。html

    擴展到這一級別的服務器模塊化設計,帶來兩個重要的好處:web

  • Apache httpd 能更優雅,更高效率的支持不一樣的平臺。尤爲是 Apache httpd 的 Windows 版本如今更有效率了,由於 mpm_winnt 能使用原生網絡特性取代在 Apache httpd 1.3 中使用的 POSIX 層。它也能夠擴展到其它平臺 來使用專用的 MPM。
  • Apache httpd 能更好的爲有特殊要求的站點定製。例如,要求 更高伸縮性的站點能夠選擇使用線程的 MPM,即 worker 或 event; 須要可靠性或者與舊軟件兼容的站點可使用prefork

    在用戶看來,MPM 很像其它 Apache httpd 模塊。主要是區別是,在任什麼時候間, 必須有一個,並且只有一個 MPM 加載到服務器中。apache

    在所有平臺中,MPM 均可以構建爲靜態模塊。在構建時選擇一種 MPM,連接到服務器中。若是要改變 MPM,必須從新構建。安全

    爲了使用指定的 MPM,請在執行 configure 腳本 時,使用參數 --with-mpm=NAMENAME 是指定的 MPM 名稱。bash

    編譯完成後,可使用 ./httpd -l 來肯定選擇的 MPM。 此命令會列出編譯到服務器程序中的全部模塊,包括 MPM。服務器

    

    ./httpd -l 和 ./httpd -V  選項均可以看出當前選用的 MPM 的模式網絡

 

Apache的三種 MPM 模式

    三種穩定的MPM(Multi-Processing Module,多進程處理模塊)模式。它們分別是prefork,worker和event,三種模式在編譯的時候,能夠經過configure的參數來指定:多線程

--with-mpm=prefork|worker|event

    固然,也能夠在編譯時爲三種都支持,經過修改配置來更換:併發

--enable-mpms-shared=all

    這時,只須要在 httpd.conf 中修改 Apache 的多處理模式 MPM(modules文件夾下,會自動編譯出三個MPM的so):

LoadModule mpm_prefork_module modules/mod_mpm_prefork.so
#LoadModule mpm_worker_module modules/mod_mpm_worker.so
#LoadModule mpm_event_module modules/mod_mpm_event.so

    並在 httpd.conf 中添加 Include conf/extra/httpd-mpm.conf,httpd-mpm.conf 中包含了 MPM 的有關配置;

一、prefork MPM

    prefork 模式能夠算是很古老可是很是穩定的 Apache 模式。Apache 在啓動之初,就預先 fork 一些子進程,而後等待請求進來。之因此這樣作,是爲了減小頻繁建立和銷燬進程的開銷。每一個子進程只有一個線程,在一個時間點內,只能處理一個請求。

  1. 優勢:成熟穩定,兼容全部新老模塊。同時,不須要擔憂線程安全的問題。(咱們經常使用的mod_php,PHP 的拓展不須要支持線程安全)
  2. 缺點:一個進程相對佔用更多的系統資源,消耗更多的內存。並且,它並不擅長處理高併發請求,在這種場景下,它會將請求放進隊列中,一直等到有可用進程,請求才會被處理。

    prefork 模式在 httpd-mpm.conf 中的默認配置:

<IfModule mpm_prefork_module>
    StartServers             5
    MinSpareServers          5
    MaxSpareServers         10
    MaxRequestWorkers      250
    MaxConnectionsPerChild   0
</IfModule>

 

二、worker MPM

    worker 模式比起上一個,是使用了多進程和多線程的混合模式。它也預先 fork 了幾個子進程(數量比較少),而後每一個子進程建立一些線程,同時包括一個監聽線程。每一個請求過來,會被分配到 1 個線程來服務。線程比起進程會更輕量,由於線程一般會共享父進程的內存空間,所以,內存的佔用會減小一些。在高併發的場景下,由於比起 prefork 有更多的可用線程,表現會更優秀一些。
    有些人會以爲奇怪,那麼這裏爲何不徹底使用多線程呢,還要引入多進程?
    緣由主要是須要考慮穩定性,若是一個線程異常掛了,會致使父進程連同其餘正常的子線程都掛了(它們都是同一個進程下的)。爲了防止這場異常場景出現,就不能所有使用線程,使用多個進程再加多線程,若是某個線程出現異常,受影響的只是 Apache 的一部分服務,而不是整個服務。

  1. 優勢:佔據更少的內存,高併發下表現更優秀。
  2. 缺點:必須考慮線程安全的問題,由於多個子線程是共享父進程的內存地址的。若是使用 keep-alive 的長鏈接方式,某個線程會一直被佔據,也許中間幾乎沒有請求,須要一直等待到超時纔會被釋放。若是過多的線程,被這樣佔據,也會致使在高併發場景下的無服務線程可用。(該問題在 prefork 模式下,一樣會發生)

    注:keep-alive 的長鏈接方式,是爲了讓下一次的 socket 通訊複用以前建立的鏈接,從而,減小鏈接的建立和銷燬的系統開銷。保持鏈接,會讓某個進程或者線程一直處於等待狀態,即便沒有數據過來。

    worker 模式在 httpd-mpm.conf 中的默認配置:

<IfModule mpm_worker_module>
    StartServers             3
    MinSpareThreads         75
    MaxSpareThreads        250
    ThreadsPerChild         25
    MaxRequestWorkers      400
    MaxConnectionsPerChild   0
</IfModule>

三、event MPM

    這個是 Apache 中最新的模式,在如今版本里的已是穩定可用的模式。它和 worker 模式很像,最大的區別在於,它解決了 keep-alive 場景下,長期被佔用的線程的資源浪費問題(某些線程由於被 keep-alive,空掛在哪裏等待,中間幾乎沒有請求過來,甚至等到超時)。event MPM中,會有一個專門的線程來管理這些 keep-alive 類型的線程,當有真實請求過來的時候,將請求傳遞給服務線程,執行完畢後,又容許它釋放。這樣加強了高併發場景下的請求處理能力。

event MPM 在遇到某些不兼容的模塊時,會失效,將會回退到 worker 模式,一個工做線程處理一個請求。官方自帶的模塊,所有是支持 event MPM 的。

注意一點,event MPM 須要Linux系統(Linux 2.6+)對 EPoll 的支持,才能啓用。

還有,須要補充的是 HTTPS 的鏈接(SSL),它的運行模式仍然是相似 worker 的方式,線程會被一直佔用,知道鏈接關閉。部分比較老的資料裏,說 event MPM 不支持 SSL,那個說法是幾年前的說法,如今已經支持了。

    event 模式在 httpd-mpm.conf 中的默認配置:

<IfModule mpm_event_module>
    StartServers             3
    MinSpareThreads         75
    MaxSpareThreads        250
    ThreadsPerChild         25
    MaxRequestWorkers      400
    MaxConnectionsPerChild   0
</IfModule>

 

生產環境 Apache MPM 優化

    生產環境接入層硬件配置:

4 臺 8 核 16G 內存阿里雲 VPC ECS

    實際壓測統計 httpd 消耗內存大約每一個 httpd 進程在 2M 左右:

[root@iZ23s96w2paZ ~]# ps -ylC httpd --sort:rss | awk '{sum+=$8; ++n} END {print "Tot="sum"("n")";print "Avg="sum"/"n"="sum/n/1024"MB"}'
Tot=1106968(503)
Avg=1106968/503=2.23159MB

    預留 5G 內存給 Apache 使用,同時爲了不在 apache 在 fork 進程等操做消耗,保留足夠的工做進程,因爲沒有兼容性相關的測試,生產環境選用最原始的 profork 模式,配置以下:

<IfModule mpm_prefork_module>
    StartServers                 500
    ServerLimit   		         2500
    MinSpareServers              500
    MaxSpareServers              1000
    MaxRequestWorkers            2000  
    MaxConnectionsPerChild       0
</IfModule>
相關文章
相關標籤/搜索