軟件性能測試分析與調優實踐之路-Web中間件的性能分析與調優總結


本文主要闡述軟件性能測試中的一些調優思想和技術,節選自作者新書《軟件性能測試分析與調優實踐之路》部分章節歸納。

在國內互聯網公司中,Web中間件用的最多的就是Apache和Nginx這兩款了,包括很多大型電商網站淘寶、京東、蘇寧易購等,都在使用Nginx或者Apache作為Web中間件。而且很多編程語言在做Web開發時,會將Apache或者Nginx作為其綁定的固定組件,比如php語言做Web開發時,就經常和Apache聯系在一起,使得apche成為了php在Web開發時的一個標配。而Nginx不管是在作為Web靜態資源訪問管理或者作為動態的請求代理性能都是非常的高效,當然Nginx或者Apache在性能分析時,有時候也會存在性能瓶頸或者需要進行調優以支持更高的並發處理能力。

1. Nginx的性能分析和調優

1.1  Nginx的負載均衡策略的選擇

在一般的時候,Web中間件最大的作用就是負責對請求進行分發,也就是我們常說的起到負載均衡的作用,當然負載均衡只是Nginx的作用之一,Nginx常見的負載均衡策略一般包括輪詢、指定權重(weight)、ip_hash、least_conn、fair、url_hash等六種,其中默認執行的策略為輪詢,fair、url_hash屬於第三方策略,這兩種策略不是Nginx自帶支持的策略,需要安裝第三方的插件來輔助支持。在不同的場景下,每一種策略的選擇對系統的整體性能影響都非常大,一般建議根據實際場景和服務器配置來選擇對應的負載均衡策略。

  •         輪詢策略:Nginx的負載均衡是通過配置upstream來實現請求轉發的,在upstream如果沒有指定其他任何的策略時,Nginx會自動執行輪詢轉發策略,upstream中配置每台服務器的權重都一樣,會按照順序依次轉發。如下所示就是一個簡單的upstream配置,由於配置了192.168.1.14和192.168.1.15兩台服務器,所以請求會按照接收到的順序依次輪詢的轉發給192.168.1.14和192.168.1.15兩台服務器進行執行。Nginx能自動感知轉發到的后端服務器是否掛掉,如果掛掉后Nginx會自動將那台掛掉的服務器從upstream中剔除。
upstream applicationServer {

    server 192.168.1.14;

    server 192.168.1.15;

}

使用輪詢策略時,其他非必填的輔助參數如下:(轉載請注明出處:來源於博客園,作者:張永清 https://www.cnblogs.com/laoqing/p/14259788.html

 使用輪詢策略的輔助參數

參數

含義

fail_timeout

該參數需要和max_fails參數結合一起來使用,用於表示在fail_timeout指定的時間內某個server允許重試連接失敗的最大次數

max_fails

在fail_timeout參數設置的時間內最大失敗次數,如果在這個時間內,所有針對該服務器的請求都失敗了,Nginx就判定該服務器掛掉了

down

標記指定的服務器已經掛掉了,Nginx將不會再向標記為down的服務器轉發任何的請求

  •         指定權重(weight):通過在upstream配置中給相應的服務器指定weight權重參數來實現按照權重分發請求,weight參數值的大小和請求轉發比率成正比,一般用於后端應用程序服務器硬件配置差異大而導致承受的訪問壓力不一樣的情況可以使用該配置,配置示例如下:
upstream applicationServer {

    server 192.168.1.14 weight=8;

    server 192.168.1.15 weight=10;

}
  •         ip_hash:每個請求按原始訪問ip的hash結果來進行請求轉發,由於同一個ip的hash值肯定是不變的,這樣每個固定客戶端就會只訪問一個后端應用程序服務器,此種配置一般可以用來解決多個應用程序服務器的session復制和同步的問題,因為同一個ip的請求都轉發到了同一台服務器的應用程序上了,所以也就不會有session不同步的問題了,但是可能會導致后端應用服務器的負載不均的情況,因為這種策略下后端應用服務器收到的請求數肯定是很難一樣多。配置示例如下:
upstream applicationServer {

ip_hash;

    server 192.168.1.14;

    server 192.168.1.15;

}
  •        least_conn:通過在upstream配置中增加least_conn配置后,Nginx在接收到請求后會把請求轉發給連接數較少的后端應用程序服務器,前面講到的輪詢算法是把請求平均的轉發給各個后端使它們的負載大致相同,但是有些請求占用的時間很長會導致其所在的后端負載較高。這種情況下,least_conn這種方式就可以達到更好的負載均衡效果。示例配置如下:
upstream applicationServer {

least_conn;

    server 192.168.1.14;

    server 192.168.1.15;

}
  •        fair:fair屬於第三方策略,即不是Nginx本身自帶的策略,需要安裝對應的第三方插件。fair是按照服務器端的響應時間來分配請求給后端應用程序服務器,響應時間短的優先分配。示例配置如下:
upstream applicationServer {

    server 192.168.1.14;

server 192.168.1.15;

fair;

}
  •       url_hash:url_hash同樣屬於第三方策略,也是需要安裝對應的第三方插件。url_hash是按照訪問的目標url的hash值來分配請求使同一個url的請求轉發到同一個后端應用程序服務器,請求的分發策略和ip_hash有點類似。在做性能調優時主要是適用對緩存命中進行調優,同一個資源(也就是同一個目標url地址)多次請求,可能會到達不同的后端應用程序服務器上會導致不必要的多次下載,使用url_hash后可以使得同一個目標url(也就是同一個資源請求)會到達同一台后端應用程序服務器,這樣可以在服務端進行資源緩存再次收到請求后,就可以直接從緩存中讀取了。示例配置如下:
upstream applicationServer {

    server 192.168.1.14;

server 192.168.1.15;

hash $request_uri;

}

1.2  Nginx進程數的配置優化

nginx服務啟動后會包括兩個重要的進程:

  •        master進程:可以控制Nginx服務的啟動、停止 、重啟、配置文件的重新加載。
  •         worker進程:處理用戶請求信息,將收到的用戶請求轉發到后端應用服務器上。

worker進程的個數可以在配置文件nginx.conf中進行配置,如下所示。

worker_processes  1;  #  Nginx配置文件中worker_processes指令后面的數值代表了Nginx啟動后worker進程的個數。

worker進程的數量一般建議等於CPU的核數或者CPU核數的兩倍。通過執行lscpu命令可以獲取到CPU的核數,如圖所示。

或者通過執行grep processor /proc/cpuinfo|wc –l 命令也可以直接獲取到CPU的核數。

[root@localhost conf]#grep processor /proc/cpuinfo|wc -l

在配置完worker進程的數量后,還建議將每一個worker進程綁定到不同的CPU核上,這樣可以避免出現CPU的爭搶。將worker進程綁定到不同的CPU核時可以通過在nginx.conf中增加worker_cpu_affinity 配置,例如將worker進程分配到4核的CPU上,可以按照如下配置進行配置。

worker_processes    4;

worker_cpu_affinity 0001 0010 0100 1000;

1.3  Nginx事件處理模型的優化

為了性能得到最優處理,Nginx的連接處理機制在不同的操作系統中一般會采用不同的I/O事件模型,在Linux操作系統中一般使用epollI/O多路復用模型,在freebsd操作系統中使用kqueueI/O多路復用模型,在solaris操作系統中使用/dev/pool方式的I/O多路復用模型,在windows操作系統中使用的icop模型。在實際使用Nginx時,我們也是需要根據不同的操作系統來選擇事件處理模型,很多事件模型都只能在對應的操作系統上得到支持。比如我們在Linux操作系統中,可以使用如下配置來使用epoll事件處理模型。

events {
worker_connections  1024;
use epoll;
}

關於I/O多路復用做個說明:在Nginx中可以配置讓一個進程處理多個I/O事件和多個調用請求,這種處理方式就類似Redis中的單線程處理模式一樣,Redis緩存讀寫處理時采用的雖然是單線程,但是性能和效率卻是非常的高,這就是因為Redis采用了異步非阻塞I/O多路復用的策略導致資源的開銷很小,不需要重復的去創建和釋放資源,而是共用一個處理線程。Nginx中也同樣采用異步非阻塞I/O策略,每個worker進程會同時啟動一個固定的線程來利用epoll監聽各種需要處理的事件,當有事件需要處理時會將事件注冊到epoll模型中去進行處理,異步非阻塞I/O策略在處理時線程可以不用因為某個I/O的處理耗時很長而一直導致線程阻塞等待,線程可以不用等待響應,也不必等待響應,而是可以繼續去處理其他的I/O事件。當I/O事件處理完成后,操作系統內核會通知I/O事件已經處理完成,這時線程才會去獲取處理好的結果。

下面表列出了Nginx常用事件處理模型的詳細介紹。

Nginx常用事件處理模型

處理模型

說明

select

各個版本的Linux和Windows操作系統都支持的基本事件驅動模型。select模型處理事件的步驟:

(1)、創建事件的描述符集合,包括讀、寫、異常發送三類事件描述符分別用來收集讀事件的描述符、寫事件的描述符和異常事件的描述符。

(2)、調用select模型底層提供的select函數等待事件發生。

(3)、輪詢所有事件描述符集合中的每一個事件描述符,檢查是否有相應的事件發生,如果有,select模型就進行相關的處理。

poll

Linux操作系統上的基本事件驅動模型,此模型無法在windows操作系統上使用。poll與select的共同點是都是先創建一個關注事件的描述符集合,再去等待這些事件發生,然后再輪詢描述符集合檢查有沒有事件發生,如果有就進行處理。不同點是select庫需要為讀事件、寫事件、異常事件分別創建一個描述符集合,因此在最后輪詢的時候,需要分別輪詢這三個集合。而poll庫只需要創建一個集合,在每個描述符對應的結構上分別設置讀事件、寫事件、異常事件,最后輪詢的時候,可以同時檢查這三種事件是否發生

epoll

epoll庫是Nginx服務器支持的高性能事件驅動模型之一,epoll屬於poll模型的一個變種,和poll主要區別在於epoll不需要使用輪詢的模式去檢查有沒有對應的事件發生,而是交給操作系統內核去負責處理,一旦有某種對應的事件發生時內核會把發生事件的描述符列表通知給進程,這樣就避免了輪詢整個描述符列表。epoll庫在Linux操作系統上是非常高效的,epoll可以同時處理的I/O事件數是操作系統可以打開文件的最大數目,而且epoll庫的I/O效率不隨描述符數目增加而線性下降,因為它只會對操作系統內核反饋的待處理的事件描述符進行操作

rtsig

rtsig模型不是一種經常用到的事件處理模型,rtsig模型在工作時會通過系統內核建立一個rtsig隊列用於存放標記事件發生的信號,每個事件發生時,系統內核就會產生一個信號存放到rtsig隊列中等待Nginx工作進程的處理

kqueue

Kqueue模型也是poll模型的一個變種,和上面介紹的epoll模型的處理方式幾乎一樣,都是通過避免輪詢操作提供效率。該模型支持在BSD系列操作系統(例如FreeBSD 、OpenBSD 、NetBSD 等)上使用

/dev/poll

/dev/poll模型一般用於solaris操作系統或者其他的unix衍生操作系統上,該模型最早是Sun公司在開發Solaris系列平台時提出的用於完成事件驅動機制的方案,它使用了虛擬的/dev/poll設備,開發人員可以將要監視的文件描述符加入這個設備,然后通過調用ioctl()函數來獲取事件通知

eventport

該模型也是Sun公司在開發Solaris系列平台時提出的、用於完成事件驅動機制的方案,它可以有效防止內核崩潰情況的發生,Nginx在此基礎上提供了事件處理支持,但是由於Solaris自身后來的沒落,所以該模型現在也很少使用。

1.4  Nginx客戶端連接數的優化

在高並發的請求調用中,連接數有時候很容易成為性能的一個瓶頸,Nginx中可以通過如下方式來調整Nginx的連接數。

  •        配置Nginx單個進程允許的客戶端最大連接數:可以通過修改Nginx的nginx.conf配置文件中的如下配置:
events        #可以設置Nginx的工作模式以及連接數上限
 {
   worker_connections 1024;
 }
  •          配置Nginx worker進程可以打開的最大文件數:可以通過修改Nginx的nginx.conf配置文件中的如下配置:
worker_processes  2;
worker_rlimit_nofile 2048;   # 設置worker進程可以打開的文件數
  • Linux內核的優化:Linux操作系統的/etc/sysctl.conf配置文件中可以重新配置很多Linux系統的內核參數  

1.5  Nginx中文件傳輸的優化

Nginx中文件傳輸一般需要優化的是如表中所示的幾個參數。

Nginx文件傳輸需要優化的參數

Nginx參數

說明

tcp_nopush

tcp_nopush和tcp_nodelay是互斥的,開啟tcp_nopush后會設置調用tcp_cork方法,讓數據包不會馬上傳送出去,等到數據包累積到最大時,一次性的傳輸出去,這樣有助於解決網絡堵塞,從而提供網絡傳輸的性能,默認為off。設置為on時的配置如下:

tcp_nopush on;

tcp_nodelay

和tcp_nopush的處理方式剛好相反,在開啟了tcp_nodelay后意味着無論數據包是多么的小,都立即發送出去,默認值為on,設置為off時為關閉,配置的方式如下:

tcp_nodelay off;

sendfile

sendfile 一般和tcp_nopush選項搭配在一起使用。Nginx中提供 sendfile 選項用來提高服務器性能,sendfile實際上是 Linux2.0版本以后推出的一個系統調用。在網絡文件傳輸過程中一般是:從硬盤讀寫 → 寫入操作系統內核 buffer → 讀入用戶模式 buffer-> 寫入內核socket buffer →協議棧開始傳輸,在開啟了sendfile后,之前的傳輸步驟就簡化成了:從硬盤讀寫 → 寫入內核 buffer (數據可以快速拷貝到內核 socket buffer) →協議棧開始傳輸,這就是常說的零拷貝方式。開啟sendfile的配置如下:

sendfile on;

nginx gzip壓縮相關參數:

gzip on

gzip_min_length 

gzip_buffers    

gzip_http_version

gzip_comp_level

gzip_types

gzip_vary

gzip_proxied off

gzip on:開啟gzip 壓縮模式

gzip_min_length :設置允許壓縮的頁面最小宇節數,字節數大小 從HTTP請求的header頭部的Content-Length中獲取。默認值是0,表示不管頁面多大都進行壓縮。一般建議設置成gzip_min_length 1K,因為如果小於1K可能會越壓越大。

gzip_buffers:表示壓縮緩沖區大小,例如設置gzip_buffers  4 16k; 表示申請4個單位為16K的內存作為壓縮結果數據流的緩存,默認值是申請與原始數據大小相同的內存空間來存儲gzip壓縮結果。

gzip_http_version:表示壓縮的HTTP協議版本,默認為1.1,常用的瀏覽器幾乎都支持gzip解壓,一般使用默認設置即可。

gzip_comp_level:表示gzip的壓縮比率,該參數用來指定gzip壓縮比,可以設置為1-9之間的數字。1表示壓縮比最小但是壓縮處理速度最快,9表示壓縮比最大並且傳輸速度快,但處理時耗時最長也比較消耗CPU資源。該參數一般建議根據實際場景中傳輸的大部分文件大小來設置,在壓縮處理速度和壓縮比率大小之間做到均衡。

gzip_types:用來設置指定壓縮的類型(就是HTTP協議中的Content-Type屬性中的媒體類型), 支持的常見類型包括 text/plain、application/x-javascript 、text/css、 application/xml、application/json等。

gzip_vary:表示啟用response header頭部屬性“Vary:Accept-Encoding”的壓縮模式。[z1] 

zip_proxied off:默認為off,一般在Nginx作為反向代理的時候啟用,表示對代理的結果數據進行壓縮,zip_proxied可以在后面增加參數來判斷HTTP的header頭部中符合指定條件后才進行數據壓縮。

loff :關閉所有的代理結果數據的壓縮。

lexpired :啟用壓縮,如果header頭部中包含 "Expires" 頭信息。

lno-cache:啟用壓縮,如果header頭部中包含 "Cache-Control:no-cache" 頭信息。

lno-store:啟用壓縮,如果header頭部中包含 "Cache-Control:no-store" 頭信息。

lprivate:啟用壓縮,如果header頭部中包含"Cache-Control:private" 頭信息。

lno_last_modified:啟用壓縮,如果header頭部中不包含 "Last-Modified" 頭信息。

lno_etag:啟用壓縮,如果header頭部中不包含 "ETag" 頭信息。

lauth:啟用壓縮,如果header頭部中包含 "Authorization" 頭信息。

lany:表示總是啟用壓縮,表示會對返回的代理數據都進行壓縮。


 [z1]

nginx.conf配置文件中開啟sendfile參數的方式配置示例如下:

sendfile on ;#默認情況下,sendfile是off。

  

nginx.conf配置文件中開啟tcp_nopush參數的方式配置示例如下:

tcp_nopush on ;#默認情況下tcp_nopush是off

  

nginx.conf配置文件中開啟tcp_nodelay參數的方式配置示例如下:

tcp_nodelay on;#默認情況下tcp_nodelay是on

1.6  Nginx中FastCGI配置的優化

FastCGI是在CGI基礎上的優化升級,CGI是Web服務器與CGI程序間傳輸數據的一種標准,運行在服務器上的CGI程序按照這個協議標准提供了傳輸接口,具體介紹如下。

  •    CGI:CGI是英文common gateway interface的簡寫,翻譯過來就是通用網關接口,這套接口描述了Web服務器與同一計算機上的軟件的通信方式,有了CGI標准后集成了CGI的Web服務器就可以通過CGI接口調用服務器上各種動態語言實現的程序了,這些程序只要通過CGI標准提供對應的調用接口即可。CGI的處理的一般流程如圖所示。

 

  • l         FastCGI:FastCGI是一個傳輸快速可伸縮的用於HTTP服務器和動態腳本語言間通信的接口,它為所有Internet應用程序提供了高性能,而不受Web服務器API的限制。包括Apache、Nginx在內的大多數Web服務都支持FastCGI,同時FastCGI也被許多腳本語言(例如Python、PHP等)所支持。

Nginx本身並不支持對外部動態程序的直接調用或者解析,所有的外部編程語言編寫的程序(比如PythonPHP)必須通過FastCGI接口才能調用。FastCGI相關參數說明如表所示。

FastCGI相關參數說明

Nginx FastCGI相關參數

說明

fastcgi_connect_timeout

用於設置Nginx服務器和后端FastCGI程序連接的超時時間,默認值值為60秒,一般建議不要超過75秒,時間太長會導致高並發調用下建立連接過多而不能及時釋放,建立的連接越多消耗的資源就會越多

fastcgi_send_timeout

用於設置Nginx發送CGI請求到FastCGI程序的超時時間,這個超時時間不是整個請求的超時時間,而是兩個成功請求的之間間隔時間為超時時間,如果這個時間內FastCGI服務沒有收到任何信息連接將被關閉

fastcgi_read_timeout

用於設置Nginx從FastCGI服務器讀取響應信息的超時時間,連接建立成功后 Nginx等待后端FastCGI程序的響應時間,實際上是讀取FastCGI響應成功消息的間隔時間,如果這個時間內Nginx沒有再次從FastCGI讀取到響應消息連接就會被關閉

fastcgi_buffer_size

用於設置Nginx FastCGI的緩沖區的大小,緩沖區大小表示的是讀取從FastCGI程序端收到的第一部分響應信息的緩沖區大小,這里的第一部分通常會包含一個小的響應頭部消息,默認情況下這個參數的大小等價於操作系統的1個內存頁單位的大小,一般是4k或者8k, 在不同的操作系統上默認大小可能不同

fastcgi_buffers

用於設置Nginx用多少和多大的緩沖區讀取從FastCGI程序收到的響應信息,默認值為fastcgi_buffer 8 4k|8k;可以在nginx.conf配置文件的的http、server、location這三個字段中使用。

一般用於指定Web服務器本地需要用多少和多大的緩沖區來緩沖FastCGI的應答請求,比如如果一個fastcgi程序的響應消息大小為12k,那么配置為fastcgi_buffers 6 4k時將分配3個4k的buffer

fastcgi_busy_buffers_size

用於設置服務器很忙時可以使用的fastcgi_buffers大小,一般推薦的大小為fastcgi_buffers*2;默認值為 fastcgi_busy_buffers_size 8k|16k

fastcgi_temp_file_write_size

用於設置FastCGI臨時文件的大小,一般建議可以設置為128~256KB ,默認大小為fastcgi_temp_file_write_size 8k|16k;

fastcgi_cache myboy_nginx

用於設置開啟FastCGI緩存功能並為其指定一個名稱(比如指定為myboy_nginx)。開啟緩存可以有效降低CPU的負載並且可以防止HTTP請求的502錯誤(HTTP服務器端的一個錯誤碼,一般是指上游服務器接收到無效的響應)的發生,而且合理設置該參數可以有效的提高請求的並發數和tps

fastcgi_cache_path

用於設置fastcgi_cache的緩存路徑。

例如可以設置為:fastcgi_cache_path /opt/data/nginx/cache levels = 2:2 keys_zone = nginx_ fastcgi_cache:256m inactive = 2d max_size=80g    use_temp_path=on;fastcgi_cache的緩存路徑可以設置目錄前列層級,比如2:2會生成256*256 個子目錄,keys_zone是設置這個緩存空間的名字以及使用多少物理內存(一般經常被訪問的熱點數據Nginx會直接放入內存以提高訪問速度),nginx_ fastcgi _cache:256m表示緩存空間的名字為nginx_ fastcgi_cache,大小為256m。inactive表示默認失效時間,max_size表示最多用多少硬盤空間來存儲緩存,特別要注意的是fastcgi_cache緩存是先寫在fastcgi_temp_path,等到達一定大小后再移到fastcgi_cache_path下去的,所以這個兩個目錄最好在同一個磁盤分區下以提高I/O讀寫速度, 如果設置use_temp_path=off則 nginx 會將緩存文件直接寫入指定的 cache 文件中

fastcgi_temp_path

用於設置fastcgi_cache的臨時目錄路徑,例如可以設置為fastcgi_temp_path /usr/local/nginx/fastcgi_temp

fastcgi_cache_valid

用於對不同的HTTP 請求響應狀態碼設置緩存的時長。

例如:fastcgi_cache_valid 200 302 lh;

表示將HTTP 請求響應狀態碼為200和302的應答緩存1個小時。

再例如:fastcgi_cache_valid 301 2d;

表示將HTTP 請求響應狀態碼為301的應答緩存2天

fastcgi_cache_min_uses

用於設置同一請求達到幾次之后晌應消息將被緩存。

例如:fastcgi_cache_min_uses 1;1表示一次即被緩存

fastcgi_cache_use_stale

用於設置哪些狀態下使用過期緩存。

例如:fastcgi_cache_use_stale error timeout invalid_header http_500 表示在發生error錯誤、響應超時、HTTP的請求頭無效和HTTP請求返回狀態碼為500時使用過期緩存

fastcgi_cache_key

用於設定fastcgi_cache中的key值。

例如:fastcgi_cache_key  scheme$request_method$host$request_uri

表示以請求的URI作為緩存的key,Nginx會取這個key的md5作為緩存文件,如果設置了緩存的目錄,Nginx會從后往前取對應的位數作為目錄。建議一定要加上$request_method變量一起作為cache key,防止如果先請求的為head 類型(HTTP請求的一種類型,類似於get請求,只不過返回的響應中沒有具體的響應內容,僅用於獲取響應報文的頭部信息),后面的GET請求將返回為空

1.7  Nginx的監控

Nginx自帶了監控模塊,但是需要在Nginx編譯安裝時指定安裝監控模塊,默認情況下是不會安裝該監控模塊的,需要指定的編譯參數為--with-http_stub_status_module。

編譯安裝完成后,Nginx的配置文件nginx.conf中還是不會開啟監控,需要在配置文件中增加如下配置,其中allow 192.168.1.102代表允許訪問監控頁面的ip地址,如圖所示。

location = /nginx_status {
             stub_status on;
             access_log off;
             allow 192.168.1.102;
             deny all;
        }

   

修改完配置文件后,通過執行nginx –s reload來重新加載配置信息,然后通過訪問http://nginx服務器ip地址:端口號/nginx_status 就可以進入監控頁面了,如圖示。

 

從圖中可以看到當前已經建立的連接數、服務器已經接收的請求數、請求的處理情況等監控信息。

2、Apache的性能分析和調優

在Web中間件中除了Nginx外另一個用的最多的中間件就是Apache了,Apache幾乎可以運行在所有的操作系統中,支持HTTP、SSL、Socket、FastCGI、SSO、負載均衡、服務器代理等很多功能模塊,在性能測試分析中如果對Apache使用不當,那么Apache有時候也可能會成為高並發訪問的瓶頸。

2.1  Apache的工作模式選擇和進程數調優

Apache的工作模式主要是指Apache在運行時內存分配、CPU、進程以及線程的使用管理和請求任務的調度等。Apache比較穩定的工作模式有prefork模式、worker模式、event模式,這三種模式也是Apache經常使用的模式。Apache默認使用的是prefork模式,一般可以在編譯安裝Apache時通過參數--with-mpm來指定安裝后使用的工作模式。

可以通過執行httpd –V命令來查看Apache當前使用的工作模式,如圖所示可以看到當前的工作模式為默認的prefork模式。

 

1. prefork模式

prefork是Apache的默認工作模式,采用非線程型的預派生方式來處理請求,在工作時使用多進程,每個進程在同一個固定的時間只單獨處理一個連接,這種方式效率高但由於是多進程的方式所以內存使用比較大。如圖所示,可以看到prefork模式下啟動了多個進程。

 

prefork工作模式在收到請求后的處理過程如圖所示,從圖中可以看到處理過程是單進程和單線程的方式,由於不存在線程安全問題所以這種模式非常適合於沒有線程安全庫,需要避免線程安全性問題的系統。雖然解決了線程安全問題,但是也必然會導致無法處理高並發請求的場景,prefork模式會將請求放進隊列中,一直等到有可用子進程請求才會被處理,也很容易導致請求隊列積壓。

  

prefork工作模式主要的配置參數如表所示。

<IfModule mpm_prefork_module>
    StartServers             8
    MinSpareServers          8
    MaxSpareServers         10
    MaxRequestWorkers      512
    MaxConnectionsPerChild   1000
</IfModule>  

表 prefork工作模式主要的配置參數說明

參數

說明

 StartServers 

啟動的server進程個數,也就是啟動多少個子進程來處理請求,默認值為5

MinSpareServers          

空閑子進程的最小數量,默認值為5,如果當前空閑子進程數少於MinSpareServers ,那么Apache會以最大每秒一個的速度產生新的子進程。一般不建議參數設置的過大,可以根據實際的並發請求量來進行設置

MaxSpareServers         

空閑子進程的最大數量,默認值為10。如果當前有超過MaxSpareServers數量的空閑子進程,那么主進程會殺死多余的子進程

MaxRequestWorkers      

代表服務器在同一時間內可以處理客戶端發送的最大請求數量,默認是256。當超過了MaxRequestWorkers大小限制的請求就會進入等待隊列進行排隊

MaxConnectionsPerChild   

每個子進程在其生命周期內允許接收處理的最大請求數量。如果請求總數已經達到這個數值,子進程將會結束,在有新的請求時就會重新開啟新的子進程。如果設置為0,子進程將永遠不會結束。該值不宜設置的過小,過小的話會容易導致進程頻繁的開啟和關閉,引起CPU的上下文切換過多。當然也建議不要設置為0,非0的情況下由於子進程肯定都存在生命周期,這樣可以防止內存泄漏以及有效的快速釋放不能釋放的資源

2. worker模式

worker模式使用了多進程和多線程相結合的混合模式來處理請求,如圖所示work模式下也是主進程會首先派生出一批子進程,但和prefork模式不同的是work模式下每個子進程會創建多個線程,每個請求會分配給一個不同的線程處理。work模式中處理請求時由於采用了多線程的處理方式,所以高並發下處理能力會更強,但是由於是多線程處理方式,所以這種模式下需要考慮線程安全問題。

轉載請注明出處:來源於博客園,作者:張永清 https://www.cnblogs.com/laoqing/p/14259788.html 

worker工作模式主要的配置參數如表所示。

<IfModule mpm_worker_module>
    StartServers             4
ServerLimit 20
    MinSpareThreads         65
    MaxSpareThreads        256
    ThreadsPerChild         30
    MaxRequestWorkers      410
    MaxConnectionsPerChild   1200
</IfModule>

表 worker工作模式主要的配置參數說明

參數

說明

 StartServers 

Apache服務啟動時初始啟動的子進程數量,在workers模式下默認是3

ServerLimit

系統允許啟動的最大進程數量

MinSpareThreads         

服務器保持啟動的最小線程數

MaxSpareThreads        

服務器保持啟動的最大線程數

ThreadsPerChild         

每個子進程允許啟動的線程數

MaxRequestWorkers /MaxClients 

代表服務器在同一時間內可以處理客戶端發送的最大請求數量

MaxConnectionsPerChild   

和prefork工作模式一樣,代表每個子進程在其生命周期內允許接收處理的最大請求數量。如果請求總數已經達到這個數值,子進程將會結束,在有新的請求時就會重新開啟新的子進程。如果設置為0,子進程將永遠不會結束

 轉載請注明出處:來源於博客園,作者:張永清 https://www.cnblogs.com/laoqing/p/14259788.html

3. event模式

event模式和worker工作模式有點類似,在event工作模式中會有一些專門的線程來承擔管理和分配線程的工作,通過這種方式使event工作模式解決了HTTP請求 keep-alive長連接的時候占用線程資源被浪費的問題,因為會有一些專門的線程用來管理這些keep-alive類型的工作線程,當有真實請求過來的時候,將請求傳遞給服務器端可用的工作線程進行處理,處理完畢后又允許其釋放資源。如圖所示。

  

event工作模式主要的配置參數如下:

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

event工作模式的配置參數幾乎與worker模式是一樣的,因為event模式本身就是對worker模式的一種升級改進。

2.2  Apache的mod選擇和優化

未完待續,更多內容  

備注:作者的原創文章,轉載須注明出處。原創文章歸作者所有,歡迎轉載,但是保留版權。對於轉載了博主的原創文章,不標注出處的,作者將依法追究版權,請尊重作者的成果。

關於軟件性能分析調優,可以加微信號yq597365581或者微信號hqh345932,進入專業的性能分析調優群進行交流溝通。

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM