高性能Web服務器Nginx

高性能Web服務器Nginx及相關新技術的應用實踐
 
什麼是Nginx?
•          Nginx (「engine x」) 是俄羅斯人Igor Sysoev(塞索耶夫)編寫的一款高性能的 HTTP 和反向代理服務器。

•          Nginx 已經在俄羅斯最大的門戶網站── Rambler Media(
www.rambler.ru
)上運行了4年時間,同時俄羅斯超過20%的虛擬主機平臺採用Nginx做爲反向代理服務器。

•          在國內,已經有新浪播客、搜狐通行證、網易新聞、網易博客、金山逍遙網、金山愛詞霸、校內網、YUPOO相冊、豆瓣、迅雷看看等多家網站、頻道使用 Nginx 服務器
Nginx的優勢①
•          一、高併發鏈接:官方測試可以支撐5萬併發鏈接,在實際生產環境中跑到2~3萬併發鏈接數。
•          二、內存消耗少:在3萬併發鏈接下,開啓的10個Nginx 進程才消耗150M內存(15M*10=150M)。
•          三、配置文件很是簡單:風格跟程序同樣通俗易懂。
•          四、成本低廉:Nginx爲開源軟件,能夠無償使用。而購買F5 BIG-IP、NetScaler等硬件負載均衡交換機則須要十多萬至幾十萬人民幣。
Nginx的優勢②
•          五、支持Rewrite重寫規則:可以根據域名、URL的不一樣,將 HTTP 請求分到不一樣的後端服務器羣組。
•          六、內置的健康檢查功能:若是 Nginx Proxy 後端的某臺 Web 服務器宕機了,不會影響前端訪問。
•          七、節省帶寬:支持 GZIP 壓縮,能夠添加瀏覽器本地緩存的 Header 頭。
•          八、穩定性高:用於反向代理,宕機的機率微乎其微。
單臺Nginx支撐了高達2.8萬的活動併發鏈接數
  
Nginx的主要應用類別
•          一、使用 Nginx 結合FastCGI運行 PHP、JSP 、Perl等程序

•          二、使用 Nginx 做反向代理、負載均衡、規則過濾

•          三、使用 Nginx 運行靜態HTML頁、圖片

•          四、Nginx與其餘新技術的結合應用
Nginx在金山逍遙網中的應用案例
金山逍遙網(xoyo.com)是金山遊戲官方網站,爲金山軟件旗下的各款遊戲提供新聞資訊、客戶服務、在線充值、視聽互動、在線活動、博客、相冊、論壇、玩家社區等內容建設和在線服務支持。
金山逍遙網
Nginx七層負載均衡的應用
Nginx承擔每一個機房Web負載均衡服務
簡單的Nginx負載均衡配置①
…… 
upstream bbs_server_pool {
   server   192.168.1.15:80 weight=1 max_fails=2 fail_timeout=30s;
   server   192.168.1.16:80 weight=1 max_fails=2 fail_timeout=30s;
   server   192.168.1.17:80 weight=1 max_fails=2 fail_timeout=30s;
   server   192.168.1.18:80 weight=1 max_fails=2 fail_timeout=30s;

……

在nginx.conf配置文件中,用upstream指令定義一組反向代理/負載均衡後端服務器池。
…… 
server{
   listen 80;
   server_name  bbs.yourdomain.com *.bbs.yourdomain.com;
   location /
   {
         proxy_pass http://bbs_server_pool;
         proxy_set_header Host  $host;
         proxy_set_header X-Forwarded-For  $remote_addr;
   }
   access_log off;
}
……
•          proxy_pass http://bbs_server_pool; 用於指定反向代理的服務器池。
•           proxy_set_header Host  $host; 當後端Web服務器上也配置有多個虛擬主機時,須要用該Header來區分反向代理哪一個主機名。
•          proxy_set_header X-Forwarded-For  $remote_addr; 若是後端Web服務器上的程序須要獲取用戶IP,請從該Header頭獲取
Nginx負載均衡的雙機熱備
一般狀況下的負載均衡HA高可用
優勢:實現了雙機熱備、故障自動轉移。
缺點:備機服務器處於閒置狀態,浪費了硬件資源。
逍遙網Nginx負載均衡雙機互備
正常狀況下,兩臺Nginx負載均衡服務器所有處於活動狀態,對外提供服務。
服務器①綁定IP別名
•          /sbin/ifconfig eth0:ha1 61.1.1.2 broadcast 61.1.1.255 netmask 255.255.255.0 up
•          /sbin/route add -host 61.1.1.2 dev eth0:ha1
•          /sbin/arping -I eth0 -c 3 -s 61.1.1.2 61.1.1.1

•          在服務器①的外網網卡eth0上,綁定了一個虛擬IP 61.1.1.2,綁定完成後發送arping包給網關。
服務器②綁定IP別名
•          /sbin/ifconfig eth0:ha2 61.1.1.3 broadcast 61.1.1.255 netmask 255.255.255.0 up
•          /sbin/route add -host 61.1.1.3 dev eth0:ha2
•          /sbin/arping -I eth0 -c 3 -s 61.1.1.3 61.1.1.1

•          在服務器②的外網網卡eth0上,綁定了一個虛擬IP 61.1.1.3,綁定完成後發送arping包給網關。
新的Nginx雙機互備(發生故障時)
自動接管公網虛擬IP,實現故障轉移
服務器①去除IP別名
•          /sbin/ifconfig eth0:ha1 61.1.1.2 broadcast 61.1.1.255 netmask 255.255.255.0 down

•          經過兩臺服務器之間的互相檢測機制,當服務器①上的檢測程序發現自身的Nginx沒法訪問時,中止綁定虛擬IP 61.1.1.2
服務器②接管原服務器①的虛擬IP
•          /sbin/ifconfig eth0:ha1 61.1.1.2 broadcast 61.1.1.255 netmask 255.255.255.0 up
•          /sbin/route add -host 61.1.1.2 dev eth0:ha1
•          /sbin/arping -I eth0 -c 3 -s 61.1.1.2 61.1.1.1

•          給網關發送Arping包,保證了網關上IP、MAC地址對應關係可以立刻更改,可以作到強行接管虛擬IP。
Nginx負載均衡URL分發
硬件、軟件七層負載均衡對比:NetScaler與Nginx
根據不一樣的URL轉發到不一樣服務器
server{
   listen       80;
   server_name  abc.domain.com;

   location ~ ^/admincp.php
   {
         proxy_pass http://192.168.1.11;
         proxy_set_header Host  $host;
         proxy_set_header X-Forwarded-For  $remote_addr;
   }

   location /
   {
         proxy_pass http://php_server_pool;
         proxy_set_header Host  $host;
         proxy_set_header X-Forwarded-For  $remote_addr;
   }
}
Web相關文件的實時自動同步
少許文件的多服務器自動同步
•          使用Linux 2.6內核的inotify監控Linux文件系統事件。
•          利用開源的lsync監聽某一目錄,若是目錄內文件發生增、刪、改,利用Rsync協議自動同步到多臺服務器。
http://code.google.com/p/lsyncd/
•          lsyncd /data0/htdocs/hu.xoyo.com/data/ 192.168.5.1::hu_data/ 192.168.5.2::hu_data/ 192.168.5.3::hu_data/ 
大量文件的多服務器自動同步
•          使用Linux 2.6內核的inotify監控Linux文件系統事件。
•          修改可監控的最大目錄數量
      echo 50000000 > /proc/sys/fs/inotify/max_user_watches
•          金山逍遙網開發的sersync文件自動同步程序,適合大量文件的自動同步,並能夠在文件同步完成後,自動調用CDN緩存刷新接口,刷新發生修改、刪除的文件的訪問URL。
Nginx的Web緩存服務
Nginx的緩存功能
•          Nginx從0.7.48版本開始,支持了相似Squid的緩存功能;
•          緩存把URL及相關組合看成Key,用md5編碼哈希後保存;
•          Nginx的Web緩存服務只能爲指定URL或狀態碼設置過時時間,不支持相似Squid的PURGE指令,手動清除指定緩存頁面;
•          採用MMAP實現,設置的緩存區大小不能超過物理內存+SWAP的值。
反向代理中的Nginx.conf緩存配置①
……
#設置Web緩存區名稱爲cache_one,緩存空間大小爲2000MB,1天清理一次緩存,單個文件超過5m不緩存。
proxy_cache_path  /data0/proxy_cache_path  levels=1:2   keys_zone=cache_one:2000m inactive=1d max_size=5m;

#注:proxy_temp_path和proxy_cache_path指定的路徑必須在同一分區
proxy_temp_path /data0/proxy_temp_path;

upstream my_server_pool {
   server   192.168.1.2:80 weight=1 max_fails=2 fail_timeout=30s;
   server   192.168.1.3:80 weight=1 max_fails=2 fail_timeout=30s;
}
……
server
{
   listen       80;
   server_name  my.domain.com;
   location /
   {
        proxy_set_header Host  $host;
        proxy_set_header X-Forwarded-For  $remote_addr;
        proxy_pass http://my_server_pool;
   }
   location ~ .*\.(gif|jpg|jpeg|png|bmp|swf|js|css)$
   {
        #對圖片、JS、CSS進行緩存,使用Web緩存區cache_one
        proxy_cache cache_one;
              
#對不一樣HTTP狀態碼緩存設置不一樣的緩存時間
        proxy_cache_valid  200 10m;
        proxy_cache_valid  304 3m;
        proxy_cache_valid  301 302 1h;
        proxy_cache_valid  any 1m;
              
        #設置Web緩存的Key值,Nginx根據Key值md5哈希存儲緩存,這裏根據「域名、URI、客戶端請求Header頭中的If-Modified-Since信息」組合成Key。
        proxy_cache_key $host$request_uri$http_if_modified_since;
              
        #反向代理,訪問後端內容源服務器
        proxy_set_header Host  $host;
        proxy_set_header X-Forwarded-For  $remote_addr;
        proxy_pass http://my_server_pool;
   }
   access_log  off;
}
Nginx緩存功能的優勢
•          對於修改實時性要求不高的圖片、Flash、CSS樣式文件、JavaScript文件,能夠在Nginx反向代理(負載均衡)服務器上設置緩存,不用每次請求都轉發到後端Web服務器,加快了響應速度。
•          減小了Nginx與後端Web服務器的鏈接數,提升了Nginx處理性能。
Nginx的Rewrite重寫規則
Nginx Rewrite規則相關指令
Nginx Rewrite規則相關指令有if、rewrite、set、return、break等,其中rewrite是最關鍵的指令。一個簡單的Nginx Rewrite規則語法以下:
rewrite  ^/b/(.*)\.html  /play.php?video=$1 break;

若是加上if語句,示例以下:
if (!-f $request_filename)
{
     rewrite ^/img/(.*)$ /site/$host/images/$1 last;
}
Nginx與Apache的Rewrite規則實例對比①
簡單的Nginx和Apache 重寫規則區別不大,基本上可以徹底兼容。例如:
Apache Rewrite 規則:
RewriteRule  ^/(mianshi|xianjing)/$ /zl/index.php?name=$1 [L]
RewriteRule  ^/ceshi/$ /zl/ceshi.php [L]
RewriteRule  ^/(mianshi)_([a-zA-Z]+)/$ /zl/index.php?name=$1_$2 [L]
RewriteRule  ^/pingce([0-9]*)/$ /zl/pingce.php?id=$1 [L]

Nginx Rewrite 規則:
rewrite  ^/(mianshi|xianjing)/$ /zl/index.php?name=$1 last;
rewrite  ^/ceshi/$ /zl/ceshi.php last;
rewrite  ^/(mianshi)_([a-zA-Z]+)/$ /zl/index.php?name=$1_$2 last;
rewrite  ^/pingce([0-9]*)/$ /zl/pingce.php?id=$1 last;

由以上示例能夠看出,Apache的Rewrite規則改成Nginx的Rewrite規則,其實很簡單:Apache的RewriteRule指令換成Nginx的rewrite指令,Apache的[L]標記換成Nginx的last標記,中間的內容不變。

若是Apache的Rewrite規則改成Nginx的Rewrite規則後,使用nginx -t命令檢查發現nginx.conf配置文件有語法錯誤,那麼能夠嘗試給條件加上引號。例如一下的Nginx Rewrite規則會報語法錯誤:

rewrite  ^/([0-9]{5}).html$ /x.jsp?id=$1  last;

加上引號就正確了:
rewrite  "^/([0-9]{5}).html$" /x.jsp?id=$1  last;
Apache與Nginx的Rewrite規則在URL跳轉時有細微的區別:

Apache Rewrite 規則:
RewriteRule  ^/html/tagindex/([a-zA-Z]+)/.*$ /$1/ [R=301,L]

Nginx Rewrite 規則:
rewrite  ^/html/tagindex/([a-zA-Z]+)/.*$ http://$host/$1/  permanent;

以上示例中,咱們注意到,Nginx Rewrite 規則的置換串中增長了「http://$host」,這是在Nginx中要求的。
另外,Apache與Nginx的Rewrite規則在變量名稱方面也有區別,例如:

Apache Rewrite 規則:
RewriteRule  ^/user/login/$ /user/login.php?login=1&forward=http://%{HTTP_HOST}  [L]

Nginx Rewrite 規則:
rewrite  ^/user/login/$ /user/login.php?login=1&forward=http://$host   last;
Apache與Nginx Rewrite 規則的一些功能相同或相似的指令、標記對應關係:

Apache的RewriteCond指令對應Nginx的if指令;
Apache的RewriteRule指令對應Nginx的rewrite指令;
Apache的[R]標記對應Nginx的redirect標記;
Apache的[P]標記對應Nginx的last標記;
Apache的[R,L]標記對應Nginx的redirect標記;
Apache的[P,L]標記對應Nginx的last標記;
Apache的[PT,L]標記對應Nginx的last標記;
Nginx與Apache的多條件Rewrite示例①
容許指定的域名訪問本站,其餘域名一概跳轉到http://www.aaa.com

Apache Rewrite 規則:
RewriteCond %{HTTP_HOST}    ^(.*?)\.domain\.com$
RewriteCond %{HTTP_HOST}    !^qita\.domain\.com$
RewriteCond %{DOCUMENT_ROOT}/market/%1/index.htm -f
RewriteRule ^/wu/$ /market/%1/index.htm [L]

Nginx的if指令不支持嵌套,也不支持AND、OR等多條件匹配,相比於Apache的RewriteCond,顯得麻煩一些,可是,咱們能夠經過下一頁的Nginx配置寫法來實現這個示例:
Nginx Rewrite 規則:
if ($host ~* ^(.*?)\.domain\.com$)
{
       set $var_wupin_city $1;
       set $var_wupin '1';
}
if ($host ~* ^qita\.domain\.com$)
{
       set $var_wupin '0';
}
if (!-f $document_root/market/$var_wupin_city/index.htm)
{
       set $var_wupin '0';
}
if ($var_wupin ~ '1')
{
       rewrite ^/wu/$ /market/$var_wupin_city/index.htm last;
}php

相關文章
相關標籤/搜索