Nginx 作為web server 的優化要點

Nginx既可作為web server,也可作為反向proxy,這裡先討論作為web server的一般性優化要點。

常用優化要點

nginx使用的是固定數量的workers, 每個worker都處理進入的請求。最佳實踐是每個CPU內核配置一個worker.

如何知道您的系統有幾個CPU?

  • $grep^processor/proc/cpuinfo|wc-l

對於一個四核處理器,配置文件類似:

# One worker per CPU-core.

  • worker_processes4;
  • events{
  • worker_connections8096;
  • multi_accepton;
  • useepoll;
  • }
  • worker_rlimit_nofile40000;
  • http{
  • sendfileon;
  • tcp_nopushon;
  • tcp_nodelayon;
  • keepalive_timeout15;
  • #Yourcontenthere..
  • }

這裡我們提高瞭worker_connections 設置,定義瞭每個worker進程能處理多少連接。

服務器的最大連接數量是:

  • worker_processes*worker_connections(=32384本例中)

這裡啟用瞭multi_accept,該配置項使nginx能盡快接收盡可能多的請求,減少客戶端的連接初始化時間。

最後,本例中使用瞭epoll的事件模型,這也是最佳實踐建議。

壓縮

很多用戶會啟用 gzip壓縮模塊,使得返回客戶端的內容更簡短,傳輸更快。

但是壓縮會消耗用戶服務器資源,通過監控CPU使用率(可采用開源Hyperic),如果過高,可以考慮禁用壓縮。

通常隻壓縮大文件,避免壓縮那些壓縮效果不好的文件,例如圖片,可執行文件等二進制文件。

用戶可參考下面配置:

  • gzipon;
  • gzip_varyon;
  • gzip_min_length10240;
  • gzip_proxiedexpiredno-cacheno-storeprivateauth;
  • gzip_typestext/plaintext/csstext/xmltext/javascriptapplication/x-javascriptapplication/xml;
  • gzip_disable”MSIE[1-6]\.”;

上面配置,隻對文件大於10k的文本文件進行壓縮。

客戶端緩存

如果客戶端(一般是瀏覽器)認為已經保存瞭要下載的最新內容,就不會向nginx服務器再發請求。

這需要做一些緩存設置。最簡單的辦法是將所有的圖片,js等靜態內容設置一個固定的時間長度:

  • location~*\.(jpg|jpeg|gif|png|css|js|ico|xml)${
  • access_logoff;
  • log_not_foundoff;
  • expires30d;
  • }

這裡我們也禁用瞭媒體文件的日志,將一些文件後綴文件的過期時間設置為30天。

文件句柄緩存

如果需要處理大量靜態文件,需要保持這些文件句柄為打開狀態,避免後續再次打開。

下面示例,既可放在nginx配置的 server 部分,也可放在主 http 塊中。:

  • open_file_cache max=2000inactive=20s;
  • open_file_cache_valid60s;
  • open_file_cache_min_uses5;
  • open_file_cache_errorsoff;

這裡設置服務器最大緩存2000個打開的文件句柄,關閉20秒內無請求的文件句柄,句柄的有效時間是60秒,並且隻有訪問次數超過5次的才會被緩存。這樣隻緩存頻繁訪問的文件,降低文件系統的訪問。

優化PHP

很多站點使用瞭PHP,例如drupal, wordpress。

由於nginx沒有自己的mod_php,推薦的方式是使用 PHP-FPM,需要將請求轉發,例如:

  • #executeall.phpfilesviaphp-fpm
  • location~.php${
  • #connecttoaunixdomain-socket:
  • fastcgi_passunix:/var/run/php5-fpm.sock;
  • fastcgi_indexindex.php;
  • fastcgi_paramSCRIPT_FILENAME $document_root$fastcgi_script_name;
  • fastcgi_paramSCRIPT_NAME$fastcgi_script_name;
  • fastcgi_buffer_size128k;
  • fastcgi_buffers25616k;
  • fastcgi_busy_buffers_size256k;
  • fastcgi_temp_file_write_size256k;
  • #ThisfileispresentonDebiansystems..
  • includefastcgi_params;
  • }

註意這裡使用瞭 Unix domain-socket 連接 FPM, 所以需要修改/etc/php5/fpm/pool.d/www.conf如下:

  • listen=/var/run/php5-fpm.sock

這保證FPM監聽一個domain socket,而不是默認的( “listen=127.0.0.1:9000”).

默認的PHP-FPM將啟動一些專用的worker,每個運行一個PHP實例。如果內存足夠,可以增加worker數量來提升並發吞吐量。

編輯文件/etc/php5/fpm/pool.d/www.conf,改變數量,例如:

  • ;setafixednumberofphpworkers
  • pm=static
  • ;startup12phpprocesses
  • pm.max_children=12

該值需要根據實際環境調整。調整的依據是使用監控工具所采集的數據。

最後可配置PHP-FPM自動重啟。如果出現問題,例如下面的配置是,在1分鐘內十個子進程死掉,就重啟,允許進程有十秒失去控制。

下面是/etc/php5/fpm/php-fpm.conf 中的全局配置:

  • emergency_restart_threshold10
  • emergency_restart_interval
  • 1m process_control_timeout10s

檢驗

優化配置的效果需要實踐檢驗,建議部署一個監控工具,監控的內容應包括:

Nginx:開源版提供的監控指標,僅有如下6個:

Connections,Accepts,Handled,Requests,Writing,Waiting

從操作系統的角度:應包括Nginx進程的CPU使用率,內存占用,整體CPU使用率,交換區使用率等指標。

如果是在虛擬機上運行,還應關註 操作系統的 ST( Steal Time)指標,判斷是否有超賣,過載等現象;

這裡推薦一個免費開源工具, Hyperic