(1).Apache運行模式說明
Apache目前一共有三種穩定的MPM(Multi-Processing Module,多進程處理模塊)模式:Prefork(進程模式)、Worker(線程模式)、Event(事件模式,2.4版本后開始穩定)。
1)Prefork
Prefork模式實現了一個非線程的、預派生的Web服務器。它在Apache啟動之初,就先預派生一些子進程,然后等待連接;可以減少頻繁創建和銷毀進程的開銷,每個子進程只有一個線程,在一個時間點內,一個線程只能處理一個請求。這是一個成熟穩定,可以兼容新老模塊,也不需要擔心線程安全問題,但是一個進程相對占用資源,消耗大量內存,不擅長處理高並發的場景。
最重要的是將MaxClients設置為一個足夠大的數值以處理潛在的請求高峰,同時又不能太大,以致需要使用的內存超出物理內存的大小。所以現在已經不常用這個模式了。 而且Apache2.4版本以后,默認使用的是worker模式。
優點:可以兼容新老模塊;每個進程使用單獨的內存空間,較安全,一個進程壞了不會影響其他進程。
缺點:占用較大內存,不擅長處理高並發。
運行原理圖如下:
2)Worker
Worker模式和Prefork模式相比,Worker模式使用了多進程和多線程的混合模式,Worker模式也同樣會先預派生一些子進程,然后每個子進程創建一些線程,同時包括一個監聽線程,每個請求會被分配到一個線程來服務。線程比起進程會更輕量,因為線程是通過共享父進程的內存空間,因此,內存的占用會減少一些,在高並發的場景下會比prefork有更多可用的線程,表現會更優秀一些;另外,如果一個線程出現了問題也會導致同一進程下的線程出現問題,如果是多個線程出現問題,也只是影響Apache的一部分,而不是全部。由於用到多進程多線程,需要考慮到線程的安全了,在使用keep-alive長連接的時候,某個線程會一直被占用,即使中間沒有請求,需要等待到超時才會被釋放(該問題在prefork模式下也存在)。
優點:可以處理海量請求,而系統資源的開銷小。
缺點:不太安全。如果一個線程壞了。 整個進程都要壞了。另外存在keep-alive長連接占用資源時間過長。
運行原理圖如下:
不管是Worker模式或是Prefork 模式,Apache總是試圖保持一些備用的(spare)或者是空閑的子進程(空閑的服務線程池)用於迎接即將到來的請求。這樣客戶端就不需要在得到服務前等候子進程的產生。這就是預先派生進程或線程。
3)Event
Event模式是在2.4版本中才可以穩定運行。這是Apache最新的工作模式,它和worker模式很像,不同的是在於它解決了keep-alive長連接的時候占用線程資源被浪費的問題,在event工作模式中,會有一些專門的線程用來管理這些keep-alive類型的線程,當有真實請求過來的時候,將請求傳遞給服務器的線程,執行完畢后,又允許它釋放。這增強了在高並發場景下的請求處理。
當某個連接沒有請求時,會主動關閉連接,在work模式下,必須等keep-alive超時,才可以釋放。
運行原理圖如下:
4)總結
在configure配置編譯參數的時候,可以使用 --with-mpm=prefork|worker|event 來指定編譯為那一種MPM。也可以編譯為三種都支持:--enable-mpms-shared=all,這樣在編譯的時候會在modules目錄下自動編譯出三個MPM文件的so,然后通過修改httpd.conf配置文件更改MPM(LoadModule mpm_event_module modules/mod_mpm_event.so;LoadModule mpm_prefork_module modules/mod_mpm_prefork.so;LoadModule mpm_worker_module modules/mod_mpm_worker.so啟用這三個中的一個,注釋其他兩個)。
5)查看Apache當前運行模式
方法一:使用httpd -l來確定當前使用的MPM
[root@youxi1 ~]# /usr/local/apache2.4.39/bin/httpd -l Compiled in modules: core.c mod_so.c http_core.c event.c //當前運行模式
方法二:使用httpd -V查看當前使用的MPM
[root@youxi1 ~]# /usr/local/apache2.4.39/bin/httpd -V Server version: IIS/7.0.0 (Unix) Server built: Aug 8 2019 17:04:07 Server's Module Magic Number: 20120211:84 Server loaded: APR 1.6.5, APR-UTIL 1.6.1 Compiled using: APR 1.6.5, APR-UTIL 1.6.1 Architecture: 64-bit Server MPM: event //當前運行模式 threaded: yes (fixed thread count) forked: yes (variable process count) Server compiled with.... -D APR_HAS_SENDFILE -D APR_HAS_MMAP -D APR_HAVE_IPV6 (IPv4-mapped addresses enabled) -D APR_USE_SYSVSEM_SERIALIZE -D APR_USE_PTHREAD_SERIALIZE -D SINGLE_LISTEN_UNSERIALIZED_ACCEPT -D APR_HAS_OTHER_CHILD -D AP_HAVE_RELIABLE_PIPED_LOGS -D DYNAMIC_MODULE_LIMIT=256 -D HTTPD_ROOT="/usr/local/apache2.4.39" -D SUEXEC_BIN="/usr/local/apache2.4.39/bin/suexec" -D DEFAULT_PIDLOG="logs/httpd.pid" -D DEFAULT_SCOREBOARD="logs/apache_runtime_status" -D DEFAULT_ERRORLOG="logs/error_log" -D AP_TYPES_CONFIG_FILE="conf/mime.types" -D SERVER_CONFIG_FILE="conf/httpd.conf"
6)切換Apache的運行模式
如果是yum安裝的httpd,想要切換運行模式,這個網上有很多了,可以查看Apache工作模式切換。
我這里重點介紹源碼安裝的Apache切換運行模式。
首先使用命令查看安裝的MPM模塊,static表示是編譯安裝時一起安裝的,shared則是DSO方式安裝的。並查看編譯設置
[root@youxi1 ~]# /usr/local/apache2.4.39/bin/apachectl -M | grep mpm mpm_event_module (static) [root@youxi1 ~]# /usr/local/apache2.4.39/bin/httpd -V Server version: IIS/7.0.0 (Unix) Server built: Aug 8 2019 17:04:07 Server's Module Magic Number: 20120211:84 Server loaded: APR 1.6.5, APR-UTIL 1.6.1 Compiled using: APR 1.6.5, APR-UTIL 1.6.1 Architecture: 64-bit Server MPM: event threaded: yes (fixed thread count) forked: yes (variable process count) Server compiled with.... -D APR_HAS_SENDFILE -D APR_HAS_MMAP -D APR_HAVE_IPV6 (IPv4-mapped addresses enabled) -D APR_USE_SYSVSEM_SERIALIZE -D APR_USE_PTHREAD_SERIALIZE -D SINGLE_LISTEN_UNSERIALIZED_ACCEPT -D APR_HAS_OTHER_CHILD -D AP_HAVE_RELIABLE_PIPED_LOGS -D DYNAMIC_MODULE_LIMIT=256 -D HTTPD_ROOT="/usr/local/apache2.4.39" -D SUEXEC_BIN="/usr/local/apache2.4.39/bin/suexec" -D DEFAULT_PIDLOG="logs/httpd.pid" -D DEFAULT_SCOREBOARD="logs/apache_runtime_status" -D DEFAULT_ERRORLOG="logs/error_log" -D AP_TYPES_CONFIG_FILE="conf/mime.types" -D SERVER_CONFIG_FILE="conf/httpd.conf"
接着重現編譯生成httpd二進制文件
[root@youxi1 httpd-2.4.39]# cd /usr/local/src/httpd-2.4.39/ //再原有的./configure配置上重新執行預編譯,以及make。我這里改為worker作為演示 [root@youxi1 httpd-2.4.39]# ./configure --prefix=/usr/local/apache2.4.39 --enable-so --enable-rewrite --enable-ssl --enable-deflate --enable-expires --with-apr=/usr/local/apr --with-apr-util=/usr/local/apr-util --with-mpm=worker [root@youxi1 httpd-2.4.39]# make [root@youxi1 httpd-2.4.39]# mv /usr/local/apache2.4.39/bin/httpd{,.bak} //備份已有的httpd [root@youxi1 httpd-2.4.39]# cp httpd /usr/local/apache2.4.39/bin/ //拷貝新生成的httpd [root@youxi1 bin]# /etc/init.d/httpd graceful //重新加載,也可以restart [root@youxi1 httpd-2.4.39]# /usr/local/apache2.4.39/bin/httpd -V Server version: IIS/7.0.0 (Unix) Server built: Aug 8 2019 17:13:33 Server's Module Magic Number: 20120211:84 Server loaded: APR 1.4.8, APR-UTIL 1.5.2 Compiled using: APR 1.6.5, APR-UTIL 1.6.1 Architecture: 64-bit Server MPM: worker threaded: yes (fixed thread count) forked: yes (variable process count) Server compiled with.... -D APR_HAS_SENDFILE -D APR_HAS_MMAP -D APR_HAVE_IPV6 (IPv4-mapped addresses enabled) -D APR_USE_SYSVSEM_SERIALIZE -D APR_USE_PTHREAD_SERIALIZE -D SINGLE_LISTEN_UNSERIALIZED_ACCEPT -D APR_HAS_OTHER_CHILD -D AP_HAVE_RELIABLE_PIPED_LOGS -D DYNAMIC_MODULE_LIMIT=256 -D HTTPD_ROOT="/usr/local/apache2.4.39" -D SUEXEC_BIN="/usr/local/apache2.4.39/bin/suexec" -D DEFAULT_PIDLOG="logs/httpd.pid" -D DEFAULT_SCOREBOARD="logs/apache_runtime_status" -D DEFAULT_ERRORLOG="logs/error_log" -D AP_TYPES_CONFIG_FILE="conf/mime.types" -D SERVER_CONFIG_FILE="conf/httpd.conf"
切換我已經自己試過了,但不知道會不會有其他漏洞。注意:這只是指定單個mpm時,這樣使用。如果實在編譯時使用--enable-mpms-shared=all安裝所有運行模式,這個需要到Apache主目錄下的conf/目錄下修改httpd.conf,找到里面的LoadModule中的相應模塊(LoadModule mpm_event_module modules/mod_mpm_event.so;LoadModule mpm_prefork_module modules/mod_mpm_prefork.so;LoadModule mpm_worker_module modules/mod_mpm_worker.so啟用這三個中的一個,注釋其他兩個)。
(2).Apache運行模式調優
1)prefork(Apache2.4以后已經很少用到,簡單了解)
查看是否啟用MPM的配置文件
[root@youxi1 ~]# vim /usr/local/apache2.4.39/conf/httpd.conf Include conf/extra/httpd-mpm.conf //啟用mpm的配置文件 //如果是使用--enable-mpms-shared=all安裝了所有運行模式,確保prefork模式是啟用狀態,worker和event是注釋狀態 #LoadModule mpm_event_module modules/mod_mpm_event.so LoadModule mpm_prefork_module modules/mod_mpm_prefork.so #LoadModule mpm_worker_module modules/mod_mpm_worker.so
查看prefork的配置參數,根據需求修改
[root@youxi1 ~]# vim /usr/local/apache2.4.39/conf/extra/httpd-mpm.conf <IfModule mpm_prefork_module> StartServers 5 //啟動Apache時創建的服務進程數量(子進程) MinSpareServers 5 //最小空閑進程數 MaxSpareServers 10 //最大空閑進程數 MaxRequestWorkers 250 //最大並發數,這里指進程的總數 MaxConnectionsPerChild 0 //最大連接數量 </IfModule> [root@youxi1 ~]# /etc/init.d/httpd graceful //重新加載 [root@youxi1 ~]# /usr/local/apache2.4.39/bin/httpd -V Server version: Apache/2.4.39 (Unix) Server built: Aug 9 2019 09:20:58 Server's Module Magic Number: 20120211:84 Server loaded: APR 1.6.5, APR-UTIL 1.6.1 Compiled using: APR 1.6.5, APR-UTIL 1.6.1 Architecture: 64-bit Server MPM: prefork //當前運行狀態 threaded: no forked: yes (variable process count) Server compiled with.... -D APR_HAS_SENDFILE -D APR_HAS_MMAP -D APR_HAVE_IPV6 (IPv4-mapped addresses enabled) -D APR_USE_SYSVSEM_SERIALIZE -D APR_USE_PTHREAD_SERIALIZE -D SINGLE_LISTEN_UNSERIALIZED_ACCEPT -D APR_HAS_OTHER_CHILD -D AP_HAVE_RELIABLE_PIPED_LOGS -D DYNAMIC_MODULE_LIMIT=256 -D HTTPD_ROOT="/usr/local/apache2.4.39" -D SUEXEC_BIN="/usr/local/apache2.4.39/bin/suexec" -D DEFAULT_PIDLOG="logs/httpd.pid" -D DEFAULT_SCOREBOARD="logs/apache_runtime_status" -D DEFAULT_ERRORLOG="logs/error_log" -D AP_TYPES_CONFIG_FILE="conf/mime.types" -D SERVER_CONFIG_FILE="conf/httpd.conf" [root@youxi1 ~]# ps aux | grep httpd root 34123 0.0 0.2 72808 2624 ? Ss 09:58 0:00 /usr/local/apache2.4.39/bin/httpd daemon 34133 0.0 0.1 72808 1436 ? S 09:59 0:00 /usr/local/apache2.4.39/bin/httpd daemon 34134 0.0 0.1 72808 1436 ? S 09:59 0:00 /usr/local/apache2.4.39/bin/httpd daemon 34135 0.0 0.1 72808 1436 ? S 09:59 0:00 /usr/local/apache2.4.39/bin/httpd daemon 34136 0.0 0.1 72808 1436 ? S 09:59 0:00 /usr/local/apache2.4.39/bin/httpd daemon 34137 0.0 0.1 72808 1436 ? S 09:59 0:00 /usr/local/apache2.4.39/bin/httpd root 34158 0.0 0.0 112724 988 pts/0 R+ 10:09 0:00 grep --color=auto httpd
配置參數詳細說明:
MinSpareServers參數設置空閑子進程的最小數量。所謂空閑子進程是指沒有正在處理請求的子進程。如果當前空閑子進程數少於MinSpareServers ,那么Apache將以第一秒一個,第二秒兩個,第三秒四個,按指數遞增個數的速度產生新的子進程。如此按指數級增加創建的進程數,最多達到每秒32個,直到滿足 MinSpareServers設置的值為止;這就是預派生(prefork)的由來;這種模式可以不必在請求到來時再產生新的進程,從而減小了系統開銷以增加性能。
MaxSpareServers參數設置空閑子進程的最大數量。如果當前有超過MaxSpareServers數量的空閑子進程,那么父進程將殺死多余的子進程。
可以調整MinSpareServers 和MaxSpareServers這兩個參數,但是這兩個參數的值不能設得太大,否則Apache進程太多,會導致內存占用太多。例如:在一台壓力大(並發訪問2000)的服務器上,MaxSpareServers這個值設置的是200。保留最大並發數的10分之一。設置了這個值的好處是不會有太多的空閑的進程在消耗資源,關閉空閑Apache進程的同時,會釋放內存,進而減少系統資源消耗。
MaxRequestWorkers參數設置最大同時處理請求的進程數量,也是最大的同時連接數,表示了Apache的最大請求並發能力,超過該數目后的請求,將排隊。
MaxConnectionsPerChild參數設置進程生命周期內,處理的最大請求數目。達到該數目后,進程將死掉。如果設置為0,表示沒有限制。該參數的意義在於,避免了可能存在的內存泄露帶來的系統問題。將MaxRequestsPerChild設置成非零值有兩個好處:可以防止(偶然的)內存泄漏無限進行,從而耗盡內存;給進程一個有限壽命,從而有助於當服務器負載減輕的時候減少活動進程的數量。注:當KeepAlive為On, 即開啟長鏈接時,發送的請求在MaxRequestsPerChild里面只算一個,不管這個連接發送了多少個請求。
2)worker
查看是否啟用MPM的配置文件
[root@youxi1 ~]# vim /usr/local/apache2.4.39/conf/httpd.conf Include conf/extra/httpd-mpm.conf //啟用MPM的配置文件 //如果是使用--enable-mpms-shared=all安裝了所有運行模式,確保worker模式是啟用狀態,prefork和event是注釋狀態 #LoadModule mpm_event_module modules/mod_mpm_event.so #LoadModule mpm_prefork_module modules/mod_mpm_prefork.so LoadModule mpm_worker_module modules/mod_mpm_worker.so
查看worker的配置參數,根據需求修改
[root@youxi1 ~]# vim /usr/local/apache2.4.39/conf/extra/httpd-mpm.conf <IfModule mpm_worker_module> StartServers 3 //啟動時子進程數 MinSpareThreads 75 //最小空閑線程數 MaxSpareThreads 250 //最大空閑線程數 ThreadsPerChild 25 //每個進程可以啟動的線程數 MaxRequestWorkers 400 //最大並發數,這里指線程的總數 MaxConnectionsPerChild 0 //最大連接數 </IfModule> [root@youxi1 ~]# /etc/init.d/httpd graceful //重新加載,有時候可能會關閉需要重新啟動httpd [root@youxi1 ~]# /usr/local/apache2.4.39/bin/httpd -V Server version: Apache/2.4.39 (Unix) Server built: Aug 9 2019 09:20:58 Server's Module Magic Number: 20120211:84 Server loaded: APR 1.6.5, APR-UTIL 1.6.1 Compiled using: APR 1.6.5, APR-UTIL 1.6.1 Architecture: 64-bit Server MPM: worker //當前運行狀態 threaded: yes (fixed thread count) forked: yes (variable process count) Server compiled with.... -D APR_HAS_SENDFILE -D APR_HAS_MMAP -D APR_HAVE_IPV6 (IPv4-mapped addresses enabled) -D APR_USE_SYSVSEM_SERIALIZE -D APR_USE_PTHREAD_SERIALIZE -D SINGLE_LISTEN_UNSERIALIZED_ACCEPT -D APR_HAS_OTHER_CHILD -D AP_HAVE_RELIABLE_PIPED_LOGS -D DYNAMIC_MODULE_LIMIT=256 -D HTTPD_ROOT="/usr/local/apache2.4.39" -D SUEXEC_BIN="/usr/local/apache2.4.39/bin/suexec" -D DEFAULT_PIDLOG="logs/httpd.pid" -D DEFAULT_SCOREBOARD="logs/apache_runtime_status" -D DEFAULT_ERRORLOG="logs/error_log" -D AP_TYPES_CONFIG_FILE="conf/mime.types" -D SERVER_CONFIG_FILE="conf/httpd.conf" [root@youxi1 ~]# ps aux | grep httpd root 37283 0.0 0.2 73064 2392 ? Ss 11:18 0:00 /usr/local/apache2.4.39/bin/httpd -k restart daemon 37284 0.0 0.4 362028 4200 ? Sl 11:18 0:00 /usr/local/apache2.4.39/bin/httpd -k restart daemon 37285 0.0 0.4 362028 4200 ? Sl 11:18 0:00 /usr/local/apache2.4.39/bin/httpd -k restart daemon 37286 0.0 0.4 362028 4200 ? Sl 11:18 0:00 /usr/local/apache2.4.39/bin/httpd -k restart root 37369 0.0 0.0 112724 988 pts/0 R+ 11:19 0:00 grep --color=auto httpd
配置參數詳細說明:
StartServers參數設置啟動時進程數。一般設同cpu核心數一樣或是cpu核心數的2倍。
MinSpareThreads參數設置基於整個服務器監視的最小空閑線程數,如果空閑的線程小於設定值,Apache會自動建立線程。假設一個網站每天正常被用戶使用的時間為早上7:00到晚上2:00。那么MinSpareThreads應該配置為,這一時間段內最小並發訪問量的3倍。比如7:00最少並發為25,那就配置成75。
MaxSpareThreads參數設置基於整個服務器監視的最大空閑線程數,如果空閑的線程大於設定值,Apache會自動kill掉多余的線程。一般配置為一天中最大並發量的一半。如這台服務器能處理的最大並量為2500。那么此值應該為1250。因為內存閑着也是閑着,可以按linux下盡可能使用內存的原則,配置成1250.這樣在突然到來更多訪問量時,響應會更及時。
ThreadsPerChild參數設置每個子進程包含的線程數,如果是並發量比較大,可以考慮加大這個值。此參數在worker模式中,是影響最大的參數。生產環境中,在帶寬和硬盤性能充足的情況下,希望這個這台可以完成2000左右的並發。那么此值應該為:2000/ StartServers的值(我這里是16)=125 。但是一個進程不可能包括無數的線程,包括太多,會導致進程不穩定,容易崩潰。所以我們認為一個進程最多包括125線程就很好了。所以如果還想處理更多的請求,可以把StartServers的值增加,而不是增大ThreadsPerChild的值。 因為ThreadsPerChild值過大,會導致Apache運行不穩定。系統調優,穩定是一切的前提。
MaxRequestWorkers參數設置所有線程數量的最大值,通常表示了一個web服務的最大並發值。MaxRequestWorkers必須是ThreadsPerChild的整數倍,否則Apache會提示調整到一個相近的值。一般設置時為MaxRequestWorkers=StartServers* ThreadsPerChild。
MaxConnectionsPerChild參數設置每個子進程可以處理的最大請求數。達到該數目后,進程將死掉。如果設置為0,表示沒有限制。MaxConnectionsPerChild/ThreadsPerChild的值作為一個判斷標准。一個線程處理太多的請求,也會出現內存溢出,導致進程崩潰。
A.一台服務器最大可以設置多少個子進程?
首選進行壓測,計算子進程的平均使用內存大小。
其次服務器可以使用的內存大小(只考慮分布式)。一般來說,一台8G內存服務器,留2G內存給系統使用;一台16G內存服務器,留4G內存給系統使用;一台32G內存服務器,留8G給系統使用;一台64G內存服務器,留8G內存給系統使用。(最多8G就足夠了)
最后,(總內存-系統內存)/子進程的平均內存=最大可以設置的子進程。
B.擴展:選擇服務器時,CPU與內存的搭配比例
通用型服務器選擇標准:CPU與內存比例1:4;計算型服務器選擇標准:CPU與內存比例1:2;內存型服務器選擇標准:CPU與內存比例1:8。
3)event
查看是否啟用MPM的配置文件
[root@youxi1 ~]# vim /usr/local/apache2.4.39/conf/httpd.conf Include conf/extra/httpd-mpm.conf //啟用MPM的配置文件 //如果是使用--enable-mpms-shared=all安裝了所有運行模式,確保event模式是啟用狀態,prefork和worker是注釋狀態 LoadModule mpm_event_module modules/mod_mpm_event.so #LoadModule mpm_prefork_module modules/mod_mpm_prefork.so #LoadModule mpm_worker_module modules/mod_mpm_worker.so
查看worker的配置參數,根據需求修改
[root@youxi1 ~]# vim /usr/local/apache2.4.39/conf/extra/httpd-mpm.conf <IfModule mpm_event_module> StartServers 3 //啟動時子進程數 MinSpareThreads 75 //最小空閑線程數 MaxSpareThreads 250 //最大空閑線程數 ThreadsPerChild 25 //每個進程可以啟動的線程數 MaxRequestWorkers 400 //最大並發數,這里指線程的總數 MaxConnectionsPerChild 0 //最大連接數 </IfModule> [root@youxi1 ~]# /etc/init.d/httpd graceful //重新加載,有時候可能會關閉,需要重新啟動htpd [root@youxi1 ~]# /usr/local/apache2.4.39/bin/httpd -V Server version: Apache/2.4.39 (Unix) Server built: Aug 9 2019 09:20:58 Server's Module Magic Number: 20120211:84 Server loaded: APR 1.6.5, APR-UTIL 1.6.1 Compiled using: APR 1.6.5, APR-UTIL 1.6.1 Architecture: 64-bit Server MPM: event //當前運行狀態 threaded: yes (fixed thread count) forked: yes (variable process count) Server compiled with.... -D APR_HAS_SENDFILE -D APR_HAS_MMAP -D APR_HAVE_IPV6 (IPv4-mapped addresses enabled) -D APR_USE_SYSVSEM_SERIALIZE -D APR_USE_PTHREAD_SERIALIZE -D SINGLE_LISTEN_UNSERIALIZED_ACCEPT -D APR_HAS_OTHER_CHILD -D AP_HAVE_RELIABLE_PIPED_LOGS -D DYNAMIC_MODULE_LIMIT=256 -D HTTPD_ROOT="/usr/local/apache2.4.39" -D SUEXEC_BIN="/usr/local/apache2.4.39/bin/suexec" -D DEFAULT_PIDLOG="logs/httpd.pid" -D DEFAULT_SCOREBOARD="logs/apache_runtime_status" -D DEFAULT_ERRORLOG="logs/error_log" -D AP_TYPES_CONFIG_FILE="conf/mime.types" -D SERVER_CONFIG_FILE="conf/httpd.conf" [root@youxi1 ~]# ps aux | grep httpd root 39648 0.0 0.2 73080 2400 ? Ss 14:54 0:00 /usr/local/apache2.4.39/bin/httpd -k graceful daemon 39649 0.0 0.4 362044 4212 ? Sl 14:54 0:00 /usr/local/apache2.4.39/bin/httpd -k graceful daemon 39650 0.0 0.4 362044 4212 ? Sl 14:54 0:00 /usr/local/apache2.4.39/bin/httpd -k graceful daemon 39651 0.0 0.4 362044 4212 ? Sl 14:54 0:00 /usr/local/apache2.4.39/bin/httpd -k graceful root 39734 0.0 0.0 112724 992 pts/0 R+ 14:55 0:00 grep --color=auto httpd
event模式調優和worker模式一樣的,不同的是在於它解決了keep-alive長連接的時候占用線程資源被浪費的問題。所以理倫上event模式比worker模式好。
4)總結
生產環境下對於要求更高伸縮性的站點可以選擇使用worker 或 event模式; 需要可靠性或者與舊軟件兼容的站點可以使用 prefork模式。現在網站使用worker模式比較多。worker也比較成熟。event模式從Apache2.4版本才開始有。
(3).Rewirte規則使用
Rewirte主要的功能就是實現URL的跳轉,它的正則表達式是基於Perl語言。可基於服務器級的(httpd.conf)和目錄級的 (.htaccess)兩種方式。如果要想用到rewrite模塊,必須先安裝或加載rewrite模塊。而基於服務器級的方式又分為全局和局部,都是利用RewriteEngine on來打開rewrite功能,配合一些其他的rewrite參數具體設置。
使用命令查看是否安裝了rewrite模塊,如果返回rewrite_module(static)則是編譯安裝時一起安裝的,如果返回rewrite_module(shared)則是DSO方式安裝的(編譯時使用--enable-rewrite也是這個,估計我的判斷標准有問題)。
[root@youxi1 ~]# /usr/local/apache2.4.39/bin/apachectl -M | grep rewrite [root@youxi1 ~]# ls /usr/local/apache2.4.39/modules/mod_rewrite.so /usr/local/apache2.4.39/modules/mod_rewrite.so //說明存在,但沒有啟用
安裝Rewirte模塊兩種方式:1.編譯Apache時使用了--enable-rewrite;2.在安裝完成后使用Apache主目錄下的bin/apxs擴展工具編譯並增加。
1)rewrite規則重寫的標志參數說明(最后的中括號內的參數)
R[=code](force redirect) 強制外部重定向。強制在替代字符串加上http://thishost[:thisport]/前綴重定向到外部的URL.如果code不指定,將用缺省的302 HTTP狀態碼。
F(force URL to be forbidden)禁用URL,返回403HTTP狀態碼。
G(force URL to be gone) 強制URL為GONE,返回410HTTP狀態碼。
P(force proxy) 強制使用代理轉發。
L(last rule) 表明當前規則是最后一條規則,停止分析以后規則的重寫。
N(next round) 重新從第一條規則開始運行重寫過程。
C(chained with next rule) 與下一條規則關聯。如果規則匹配則正常處理,該標志無效,如果不匹配,那么下面所有關聯的規則都跳過。
T=MIME-type(force MIME type) 強制MIME類型。
NS (used only if no internal sub-request) 只用於不是內部子請求。
NC(no case) 不區分大小寫
QSA(query string append) 追加請求字符串。
NE(no URI escaping of output) 不在輸出轉義特殊字符。例如:RewriteRule /foo/(.*) /bar?arg=P1\%3d$1 [R,NE] 將能正確的將/foo/zoo轉換成/bar?arg=P1=zed
PT(pass through to next handler) 傳遞給下一個處理。
S=num(skip next rule(s)) 跳過num條規則。
E=VAR:VAL(set environment variable) 設置環境變量。
2)使用apxs擴展工具安裝rewrite模塊
[root@youxi1 ~]# ls /usr/local/src/httpd-2.4.39/modules/mappers/mod_rewrite.* /usr/local/src/httpd-2.4.39/modules/mappers/mod_rewrite.c /usr/local/src/httpd-2.4.39/modules/mappers/mod_rewrite.dep /usr/local/src/httpd-2.4.39/modules/mappers/mod_rewrite.dsp /usr/local/src/httpd-2.4.39/modules/mappers/mod_rewrite.exp /usr/local/src/httpd-2.4.39/modules/mappers/mod_rewrite.h /usr/local/src/httpd-2.4.39/modules/mappers/mod_rewrite.la /usr/local/src/httpd-2.4.39/modules/mappers/mod_rewrite.lo /usr/local/src/httpd-2.4.39/modules/mappers/mod_rewrite.mak /usr/local/src/httpd-2.4.39/modules/mappers/mod_rewrite.o /usr/local/src/httpd-2.4.39/modules/mappers/mod_rewrite.slo [root@youxi1 ~]# /usr/local/apache2.4.39/bin/apxs -cia /usr/local/src/httpd-2.4.39/modules/mappers/mod_rewrite.c [root@youxi1 ~]# echo $? 0 [root@youxi1 ~]# ls /usr/local/apache2.4.39/modules/mod_rewrite.so /usr/local/apache2.4.39/modules/mod_rewrite.so [root@youxi1 ~]# vim /usr/local/apache2.4.39/conf/httpd.conf LoadModule rewrite_module modules/mod_rewrite.so //確保啟用 [root@youxi1 ~]# /usr/local/apache2.4.39/bin/apachectl -M | grep rewrite rewrite_module (shared) //這個就是已經安裝成功了
3)重寫實例
[root@youxi1 ~]# vim /usr/local/apache2.4.39/conf/httpd.conf LoadModule rewrite_module modules/mod_rewrite.so //啟用rewrite模塊 //也可以使用<IfModule rewrite_module></IfModule>將以下內容包裹 RewriteEngine on //打開rewrite重寫功能 RewriteCond %{HTTP_HOST} !^www.youxi1.com [NC] RewriteCond %{HTTP_HOST} !^192.168.1.6 [NC] RewriteCond %{HTTP_HOST} !^$ RewriteRule ^/(.*) http://www.youxi1.com/$1 [L] [root@youxi1 ~]# /etc/init.d/httpd graceful //重新加載
配置說明:
RewriteCond %{HTTP_HOST} !^www.you.com [NC]表示當客戶端請求的主機前綴不是www.you.com時,[NC]表示忽略大小寫
RewriteCond %{HTTP_HOST} !^192.168.1.6 [NC]表示當客戶端請求的主機前綴不是192.168.1.6時,[NC]表示忽略大小寫
RewriteCond %{HTTP_HOST} !^$表示當客戶端請求的主機不為空時。
RewriteRule ^/(.*) http://www.you.com/$1 [L]表示如果客戶端請求的主機中的前綴符合上述條件(這里匹配的條件是)則直接進行跳轉到http://www.you.com,[L]表示立即停止重寫操作並不再應用其他重寫規則。這里的.表示換行符意外的所有字符,*表示匹配0次或更多次,合起來的.*就是匹配換行符以外的所有字符。小括號()的功能是把內部的所有字符做一個標記,以便后面引用。這里的$1就是調用(.*)。
官方文檔地址:http://httpd.apache.org/docs/current/mod/mod_rewrite.html#rewritecond
做一個測試界面
[root@youxi1 ~]# echo www.youxi1.com > /usr/local/apache2.4.39/htdocs/test.html
然后Windows下修改hosts文件,添加如下兩行
192.168.1.6 bbs.xi1.cn 192.168.1.6 www.youxi1.com
之后使用瀏覽器查看
----------->
----------->
4)防盜鏈
一些小網站為了盈利,通過盜鏈來實現對自己網站內容的豐富,這無疑加大了企業的空間和流量的成本,因此我們需要對Apache進行防盜鏈的配置。
[root@youxi1 ~]# vim /usr/local/apache2.4.39/conf/httpd.conf <IfModule rewrite_module> RewriteEngine on RewriteCond %{HTTP_REFERER} !^http://sunsky.pw/.*$ [NC] RewriteCond %{HTTP_REFERER} !^http://sunsky.pw$ [NC] RewriteCond %{HTTP_REFERER} !^http://www.sunsky.pw/.*$ [NC] RewriteCond %{HTTP_REFERER} !^http://www.sunsky.pw$ [NC] RewriteRule .*\.(gif|jpg|swf)$ http://www.sunsky.pw [R,NC] </IFModule> [root@youxi1 ~]# /etc/init.d/httpd graceful //重新加載
HTTP_REFERER是header的一部分,當瀏覽器向Web服務器發送請求時,會帶上Referer來告訴服務器該網頁從哪個鏈接過來的。
(4).禁止瀏覽目錄
由於開啟目錄瀏覽會讓我們整個目錄下的內容全部都暴露到外面,因此我們必須要禁止目錄瀏覽功能。當然一些目錄開放給客戶做下載的,可以忽略此項優化。
做一個測試環境
[root@youxi1 ~]# mkdir /usr/local/apache2.4.39/htdocs/testdir [root@youxi1 ~]# touch /usr/local/apache2.4.39/htdocs/testdir/file{1,2,3}
修改配置文件禁止訪問目錄
[root@youxi1 ~]# vim /usr/local/apache2.4.39/conf/httpd.conf <Directory "/usr/local/apache2.4.39/htdocs"> ... Options FollowSymLinks //修改,原本是Options Indexes FollowSymLinks ... </Directory>
[root@youxi1 ~]# /etc/init.d/httpd graceful //重新加載
再次查看
(5).禁止php文件被解析
企業的站點有時會提供用戶進行上傳操作,比如讓用戶上傳一個文件或頭像圖片,而用戶上傳文件的存放目錄,我們是不能給php的解析權限的,否則會對Apache服務和系統造成危害。
設置主目錄下的htdocs/data目錄里的php結尾的文件不運行。
[root@youxi1 ~]# vim /usr/local/apache2.4.39/conf/httpd.conf //加到已有的<Directory></Directory>標簽對下面 <Directory "/usr/local/apache2.4.39/htdocs/data" > <Files ~ ".php"> //以.php結尾的文件 Order allow,deny Deny from all </Files> </Directory> [root@youxi1 ~]# /etc/init.d/httpd restart
然后創建測試頁面
[root@youxi1 ~]# mkdir /usr/local/apache2.4.39/htdocs/data [root@youxi1 ~]# vim /usr/local/apache2.4.39/htdocs/data/index.php <?php phpinfo(); ?>
然后使用瀏覽器訪問
(6).使用CDN做網絡加速
簡單地說,就是通過在現有的Internet中增加一層新的網絡架構,將網站的內容發布到最接近用戶的緩存服務器內。通過DNS負載均衡的技術,判斷用戶來源就近訪問cache服務器取得所需的內容,杭州的用戶訪問接近杭州服務器上的內容,北京訪問接近北京服務器上的內容。這樣可以有效減少數據在網絡上傳輸的事件,提高速度。把靜態內容發布到CDN減少了用戶的響應時間20%或更多。
國內有名的CND公司:網宿,藍汛(chinacache),快網
(7).Apache網站架構優化
好的網站架構是網站性能強大關鍵,更是網站安全的關鍵。在生產環境中建議將程序頁面服務器、圖片附件服務器和上傳服務器三者的功能盡量分離。
分離方法:1、分離最佳方式是分別使用獨立的服務器(需要程序支持);2、次選方案在前端負載均衡器通過haproxy/nginx來根據用戶請求的目錄或擴展名來對后端的服務器發出請求。
例如:請求http://www.xxxxxx.cn/a/b.jpg就拋給圖片服務器(CDN最好),這里是根據擴展名.jpg分發
請求http:// /www.xxxxxx.cn /upload/login.php就拋給Apache服務器,這里是根據URL路徑分發。
均不符合上面兩個要求的,默認就都是拋給主web服務器。