(連云港工貿(mào)高等職業(yè)技術(shù)學校,江蘇連云港市,222061) 李 兵
常見Web服務器在為用戶提供服務時,一般有如下三種方式可選擇:多進程方式、多線程方式和異步方式。實際運用中,最大并發(fā)數(shù)與硬件性能和內(nèi)存、CPU數(shù)量都有很大關(guān)系的。CPU越多性能越高,可分配的內(nèi)存越多性能也就越高。提高Web服務器的并發(fā)連接處理能力有幾個基本條件:①基于線程;②基于事件的模型;③基于磁盤的異步I/O;④支持mmap 內(nèi)存映射。由于Nginx 能支持以上的各種特性,充分利用它具有event基于事件機制的特性,可以很好的解決高連接并發(fā)的難題。
Nginx 采用模塊化、事件驅(qū)動、異步、單線程及非阻塞的架構(gòu),并大量采用了多路復用及事件通知機制。Nginx 會按需同時運行多個進程:一個主進程master 和幾個工作進程worker,如果配置了緩存還會有緩存加載器進程cache loader 和緩存管理器進程cache manager 等。在Nginx 中,連接請求由為數(shù)不多的幾個僅包含一個線程的進程worker 以高效的run-loop 回環(huán)機制進行處理,而每個worker 可以并行處理數(shù)千個的并發(fā)連接及請求。所有進程均僅含一個線程,并主要通過“共享內(nèi)存”的機制實現(xiàn)進程與進程之間的通信。Nginx的代碼是由一個核心和一系列模塊組成,核心主要用于提供Web Server 的基本功能,以及Web 和Mail 反向代理的功能。Nginx的系列模塊提供了core內(nèi)核、event事件、HTTP服務、mail郵件、misc雜項五種類別,每一類模塊根據(jù)需要又有多種具體模塊。10 000 非活動的HTTP keep-alive 連接僅需要 2~3M 內(nèi)存,實現(xiàn)最小化的數(shù)據(jù)拷貝操作。
指定工作進程數(shù)量并綁定進程。一般為了提高CPU的使用率,可以設定系統(tǒng)進程為可用的CPU總邏輯核數(shù)的2 倍,增強worker 進程與CPU 的親和力;使用worker_cpu-affinity 指令通過調(diào)用函數(shù)將worker 進程綁定到指定CPU 上。默認配置為worker_processes auto 或 1,修改為 4。四核 CPU 綁定進程為worker_cpu - affinity 0001 0010 0100 1000。定義進程可以同時處理的文件數(shù)量。執(zhí)行命令worker_rlimit_nofile 65535,可以將worker 進程數(shù)量從默認值提高到65535。
使用epoll機制。它通過在Linux內(nèi)核中申請一個簡易的文件系統(tǒng)。把原先的調(diào)用分成了3 個部分:建立一個epoll對象、向epoll對象中添加套接字、收集發(fā)生的事件連接。epoll 沒有限止的fd 只與系統(tǒng)資源有關(guān),是Linux高效網(wǎng)絡的基礎(chǔ),因此能夠高效支持百萬級別的句柄監(jiān)聽。合理設置每個worker進程所能處理的連接數(shù),通過worker_connections 和worker_processes 指令直接相乘能夠計算出最大客戶端連接數(shù)量。實現(xiàn)方法為向配置文件中寫入語句:worker_connections 10240;該數(shù)值默認為1024。
合理配置keepalive_timeout。用于設定客戶端的連接超時,使TCP連接能保持一定時間也就是多少秒,大于這個時間過后,服務器會關(guān)閉連接,工作中建議配置為75S:keepalive_timeout 75,以避免連接重建。關(guān)閉Nginx日志訪問。用戶訪問的日志通常會寫入日志文件中,用于系統(tǒng)分析和日志審計等工作,會提高系統(tǒng)負載,關(guān)閉日志寫入能提高系統(tǒng)性能。需要將配置文件中的默認值access_log/var/log/Nginx/access.log修改為access_log off。
Linux 對于每個用戶,系統(tǒng)會限制用戶的最大進程數(shù)。為提高性能,可以根據(jù)設備資源情況,設置各Linux 用戶的值,查看用戶打開最大進程數(shù)可以執(zhí)行命令ulimit–u,從結(jié)果中得到的max user processes 的值就是系統(tǒng)限制最多可以運行的進程數(shù)量,它默認是/proc/sys/kernel/threads-max 的值除以2,即系統(tǒng)線程數(shù)的一半。執(zhí)行命令ulimit–u 65535,用于修改最大進程數(shù)值。
如果全局的kernel.pid_max=1024,那么即使將用戶的max user processes 的值設定為655356,用戶能打開的最大進程數(shù)還是1024,無法達到65535。執(zhí)行命令:echo65535>/proc/sys/kernel/pid_max,修改這個值才算是正確修改。此方法只是臨時生效,如果在/etc/sysctl.conf配置文件中添加kernel.pid_max=65535,才會使得機器重啟也會永久生效。
PHP 配置中默認一次性開啟5 個PHPCGI 進程,將 pm.max_children 數(shù)值改為64,表示開啟64 個php-cgi 進程。另外需要將每個進程在重置之前能夠執(zhí)行的最多請求數(shù)默認值500 改為65535:pm.max_requests=65535。
Nginx 在經(jīng)過優(yōu)化以后,能夠支持高達30 000并發(fā)連接數(shù)的響應,并且消耗更少的資源,很好地解決了C10K 問題。根據(jù)本文的性能優(yōu)化對比測試,Nginx可以承受30 000以上的PHP(FastCGI)并發(fā)連接數(shù),大約相當于同等環(huán)境下Apache 的10 倍。一般來說,4GB內(nèi)存的服務器使用Apache一般能處理3 000 個并發(fā)連接,當并發(fā)連接數(shù)達到25 00 時,服務器內(nèi)存和Swap空間用滿而系統(tǒng)幾乎崩潰,訪問延遲,而使用Nginx 優(yōu)化技術(shù)的服務器在30 000 并發(fā)連接下,開啟8個Nginx進程消耗120M內(nèi)存(每個進程約消耗15MB),開啟的64 個php-cgi 進程消耗1 280M 內(nèi)存(每個php-cgi 進程約消耗20M),加上系統(tǒng)自身消耗的內(nèi)存,總共消耗不到2GB內(nèi)存。在大流量情況下訪問Nginx 服務器的PHP 程序,速度仍然很快,網(wǎng)頁及程序執(zhí)行的時延也都在可控范圍內(nèi)。