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

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

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

1. Nginx的性能分析和調優css

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

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

  •         輪詢策略: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.htmlnode

 使用輪詢策略的輔助參數nginx

參數算法

含義編程

fail_timeoutjson

該參數須要和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 就能夠進入監控頁面了,如圖示。

 

從圖中能夠看到當前已經創建的鏈接數、服務器已經接收的請求數、請求的處理狀況等監控信息。

二、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,進入專業的性能分析調優羣進行交流溝通。

相關文章
相關標籤/搜索