Nginx 負載均衡

Windows2012中安裝Nginx並建立爲Windows服務javascript

安裝Nginx

下載windows版nginx (http://nginx.org/en/download.html ),以後解壓到須要放置的位置(D:\xampp\nginx)php

將Nginx設置爲Windows服務

須要藉助"Windows Service Wrapper"小工具,項目地址: https://github.com/kohsuke/winswcss

下載地址: http://repo.jenkins-ci.org/releases/com/sun/winsw/winsw/1.18/winsw-1.18-bin.exehtml

下載該工具後,將其放在 Nginx安裝目錄下,並重命名爲nginx-service.exe,建立配置文件nginx-service.xml(名字要和工具名同樣),java

建立nginx-service.exe.config(爲支持NET 4.0 runtime,默認只支持NET 2.0 runtime)jquery

文件結構以下:linux

nginx-service.xml 內容以下:nginx

<service>
  <id>nginx</id>
  <name>Nginx Service</name>
  <description>High Performance Nginx Service</description>
  <logpath>D:\WorkSpaces\nginx\logs</logpath>
  <log mode="roll-by-size">
    <sizeThreshold>10240</sizeThreshold>
    <keepFiles>8</keepFiles>
  </log>
  <executable>D:\WorkSpaces\nginx\nginx.exe</executable>
  <startarguments>-p D:\WorkSpaces\nginx</startarguments>
  <stopexecutable>D:\WorkSpaces\nginx\nginx.exe</stopexecutable>
  <stoparguments>-p D:\WorkSpaces\nginx -s stop</stoparguments>
</service>

 

nginx-service.exe.config 內容以下:git

 
<configuration>
  <startup>
    <supportedRuntime version="v2.0.50727" />
    <supportedRuntime version="v4.0" />
  </startup>
  <runtime>
    <generatePublisherEvidence enabled="false"/> 
  </runtime>
</configuration>
 

在cmd中運行以下命令安裝windows服務github

D:\WorkSpaces\nginx\nginx-service.exe install

以後就能夠在Windows服務面板中啓動服務了 services.msc

瀏覽器中就能夠正常訪問了

 

 

 

WINDOWS BAT 管理文件

====================================================
@echo off
rem 當前bat的做用

echo ==================begin========================

cls 
SET NGINX_PATH=D:
SET NGINX_DIR=D:\WorkSpaces\nginx\
color 0a 
TITLE Nginx 管理程序控制面板

CLS 

ECHO. 
ECHO. * Nginx 管理程序 * 
ECHO. * 建立2013-10-15 * 
ECHO. 

:MENU 

ECHO. * nginx 進程list * 
tasklist|findstr /i "nginx.exe"

ECHO. 
ECHO. [1] 啓動Nginx 
ECHO. [2] 關閉Nginx 
ECHO. [3] 重啓Nginx 
ECHO. [4] 退 出 
ECHO. 

ECHO.請輸入選擇項目的序號:
set /p ID=
IF "%id%"=="1" GOTO start 
IF "%id%"=="2" GOTO stop 
IF "%id%"=="3" GOTO restart 
IF "%id%"=="4" EXIT
PAUSE 

:start 
call :startNginx
GOTO MENU

:stop 
call :shutdownNginx
GOTO MENU

:restart 
call :shutdownNginx
call :startNginx
GOTO MENU

:shutdownNginx
ECHO. 
ECHO.關閉Nginx...... 
taskkill /F /IM nginx.exe > nul
ECHO.OK,關閉全部nginx 進程
goto :eof

:startNginx
ECHO. 
ECHO.啓動Nginx...... 
IF NOT EXIST "%NGINX_DIR%nginx.exe" ECHO "%NGINX_DIR%nginx.exe"不存在 

%NGINX_PATH% 

cd "%NGINX_DIR%" 

IF EXIST "%NGINX_DIR%nginx.exe" (
echo "start '' nginx.exe"
start "" nginx.exe
)
ECHO.OK
goto :eof

 

 

NGINX 配置

#負載均衡
upstream backend {
    server backend1.example.com weight=5;
    server backend2.example.com:8080;
    server unix:/tmp/backend3;

    server backup1.example.com:8080   backup;
    server 192.168.239.1:8080    max_fails=3 fail_timeout=30s;
    server 192.168.239.129:8080  max_fails=3 fail_timeout=30s;
}

server {
    #對外暴露一個80端口
    listen 80;
    server_name localhost;
    #/表明不管輸入任何地址,都會匹配到該地址(全部的路徑,都會匹配如下的規則)
    location / {
        # 負載均衡到後臺的wen服務器上(tomcat)
        proxy_pass http://backend;
    }
}
 

 

Nginx的代理功能與負載均衡功能是最常被用到的,關於nginx的基本語法常識與配置已在上篇文章中有說明,這篇就開門見山,先描述一些關於代理功能的配置,再說明負載均衡詳細。

Nginx代理服務的配置說明

一、上一篇中咱們在http模塊中有下面的配置,當代理遇到狀態碼爲404時,咱們把404頁面導向百度。

error_page 404 https://www.baidu.com; #錯誤頁

然而這個配置,細心的朋友能夠發現他並無起做用。

若是咱們想讓他起做用,咱們必須配合着下面的配置一塊兒使用

proxy_intercept_errors on;    #若是被代理服務器返回的狀態碼爲400或者大於400,設置的error_page配置起做用。默認爲off。

二、若是咱們的代理只容許接受get,post請求方法的一種

proxy_method get;    #支持客戶端的請求方法。post/get;

三、設置支持的http協議版本

proxy_http_version 1.0 ; #Nginx服務器提供代理服務的http協議版本1.0,1.1,默認設置爲1.0版本

四、若是你的nginx服務器給2臺web服務器作代理,負載均衡算法採用輪詢,那麼當你的一臺機器web程序iis關閉,也就是說web不能訪問,那麼nginx服務器分發請求仍是會給這臺不能訪問的web服務器,若是這裏的響應鏈接時間過長,就會致使客戶端的頁面一直在等待響應,對用戶來講體驗就打打折扣,這裏咱們怎麼避免這樣的狀況發生呢。這裏我配張圖來講明下問題。

 

若是負載均衡中其中web2發生這樣的狀況,nginx首先會去web1請求,可是nginx在配置不當的狀況下會繼續分發請求道web2,而後等待web2響應,直到咱們的響應時間超時,纔會把請求從新分發給web1,這裏的響應時間若是過長,用戶等待的時間就會越長。

下面的配置是解決方案之一。

proxy_connect_timeout 1;   #nginx服務器與被代理的服務器創建鏈接的超時時間,默認60秒
proxy_read_timeout 1; #nginx服務器想被代理服務器組發出read請求後,等待響應的超時間,默認爲60秒。
proxy_send_timeout 1; #nginx服務器想被代理服務器組發出write請求後,等待響應的超時間,默認爲60秒。
proxy_ignore_client_abort on;  #客戶端斷網時,nginx服務器是否終端對被代理服務器的請求。默認爲off。

五、若是使用upstream指令配置啦一組服務器做爲被代理服務器,服務器中的訪問算法遵循配置的負載均衡規則,同時可使用該指令配置在發生哪些異常狀況時,將請求順次交由下一組服務器處理。

proxy_next_upstream timeout;  #反向代理upstream中設置的服務器組,出現故障時,被代理服務器返回的狀態值。error|timeout|invalid_header|http_500|http_502|http_503|http_504|http_404|off

error:創建鏈接或向被代理的服務器發送請求或讀取響應信息時服務器發生錯誤。

timeout:創建鏈接,想被代理服務器發送請求或讀取響應信息時服務器發生超時。

invalid_header:被代理服務器返回的響應頭異常。

off:沒法將請求分發給被代理的服務器。

http_400,....:被代理服務器返回的狀態碼爲400,500,502,等。

六、若是你想經過http獲取客戶的真是ip而不是獲取代理服務器的ip地址,那麼要作以下的設置。

proxy_set_header Host $host; #只要用戶在瀏覽器中訪問的域名綁定了 VIP VIP 下面有RS;則就用$host ;host是訪問URL中的域名和端口  www.taobao.com:80
proxy_set_header X-Real-IP $remote_addr;  #把源IP 【$remote_addr,創建HTTP鏈接header裏面的信息】賦值給X-Real-IP;這樣在代碼中 $X-Real-IP來獲取 源IP
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;#在nginx 做爲代理服務器時,設置的IP列表,會把通過的機器ip,代理機器ip都記錄下來,用 【,】隔開;代碼中用 echo $x-forwarded-for |awk -F, '{print $1}' 來做爲源IP

關於X-Forwarded-For與X-Real-IP的一些相關文章我推薦一位博友的:HTTP 請求頭中的 X-Forwarded-For ,這位博友對http協議有一系列的文章闡述,推薦你們去關注下。

七、下面是個人一個關於代理配置的配置文件部分,僅供參考。

複製代碼
    include       mime.types;   #文件擴展名與文件類型映射表
    default_type  application/octet-stream; #默認文件類型,默認爲text/plain
    #access_log off; #取消服務日誌    
    log_format myFormat ' $remote_addr–$remote_user [$time_local] $request $status $body_bytes_sent $http_referer $http_user_agent $http_x_forwarded_for'; #自定義格式
    access_log log/access.log myFormat;  #combined爲日誌格式的默認值
    sendfile on;   #容許sendfile方式傳輸文件,默認爲off,能夠在http塊,server塊,location塊。
    sendfile_max_chunk 100k;  #每一個進程每次調用傳輸數量不能大於設定的值,默認爲0,即不設上限。
    keepalive_timeout 65;  #鏈接超時時間,默認爲75s,能夠在http,server,location塊。
    proxy_connect_timeout 1;   #nginx服務器與被代理的服務器創建鏈接的超時時間,默認60秒
    proxy_read_timeout 1; #nginx服務器想被代理服務器組發出read請求後,等待響應的超時間,默認爲60秒。
    proxy_send_timeout 1; #nginx服務器想被代理服務器組發出write請求後,等待響應的超時間,默認爲60秒。
    proxy_http_version 1.0 ; #Nginx服務器提供代理服務的http協議版本1.0,1.1,默認設置爲1.0版本。
    #proxy_method get;    #支持客戶端的請求方法。post/get;
    proxy_ignore_client_abort on;  #客戶端斷網時,nginx服務器是否終端對被代理服務器的請求。默認爲off。
    proxy_ignore_headers "Expires" "Set-Cookie";  #Nginx服務器不處理設置的http相應投中的頭域,這裏空格隔開能夠設置多個。
    proxy_intercept_errors on;    #若是被代理服務器返回的狀態碼爲400或者大於400,設置的error_page配置起做用。默認爲off。
    proxy_headers_hash_max_size 1024; #存放http報文頭的哈希表容量上限,默認爲512個字符。
    proxy_headers_hash_bucket_size 128; #nginx服務器申請存放http報文頭的哈希表容量大小。默認爲64個字符。
    proxy_next_upstream timeout;  #反向代理upstream中設置的服務器組,出現故障時,被代理服務器返回的狀態值。error|timeout|invalid_header|http_500|http_502|http_503|http_504|http_404|off
    #proxy_ssl_session_reuse on; 默認爲on,若是咱們在錯誤日誌中發現「SSL3_GET_FINSHED:digest check failed」的狀況時,能夠將該指令設置爲off。
複製代碼

Nginx負載均衡詳解

上一篇中我說啦nginx有哪些中負載均衡算法。這一結我就給若是操做配置的給你們作詳細說明下。

首先給你們說下upstream這個配置的,這個配置是寫一組被代理的服務器地址,而後配置負載均衡的算法。這裏的被代理服務器地址有2中寫法。

 

複製代碼
upstream mysvr { 
      server 192.168.10.121:3333;
      server 192.168.10.122:3333;
    }
 server {
        ....
        location  ~*^.+$ {         
           proxy_pass  http://mysvr;  #請求轉向mysvr 定義的服務器列表         
        } 
複製代碼

 

複製代碼
upstream mysvr { 
      server  http://192.168.10.121:3333;
      server  http://192.168.10.122:3333;
    }
 server {
        ....
        location  ~*^.+$ {         
           proxy_pass  mysvr;  #請求轉向mysvr 定義的服務器列表         
        } 
複製代碼

而後,就來點實戰的東西。

一、熱備:若是你有2臺服務器,當一臺服務器發生事故時,才啓用第二臺服務器給提供服務。服務器處理請求的順序:AAAAAA忽然A掛啦,BBBBBBBBBBBBBB.....

upstream mysvr { 
      server 127.0.0.1:7878; 
      server 192.168.10.121:3333 backup;  #熱備     
    }

二、輪詢:nginx默認就是輪詢其權重都默認爲1,服務器處理請求的順序:ABABABABAB....

upstream mysvr { 
      server 127.0.0.1:7878;
      server 192.168.10.121:3333;       
    }

三、加權輪詢:跟據配置的權重的大小而分發給不一樣服務器不一樣數量的請求。若是不設置,則默認爲1。下面服務器的請求順序爲:ABBABBABBABBABB....

 upstream mysvr { 
      server 127.0.0.1:7878 weight=1;
      server 192.168.10.121:3333 weight=2;
}

四、ip_hash:nginx會讓相同的客戶端ip請求相同的服務器。

upstream mysvr { 
      server 127.0.0.1:7878; 
      server 192.168.10.121:3333;
      ip_hash;
    }

五、若是你對上面4種均衡算法不是很理解,那麼麻煩您去看下我上一篇配的圖片,可能會更加容易理解點。

到這裏你是否是感受nginx的負載均衡配置特別簡單與強大,那麼還沒完,我們繼續哈,這裏扯下蛋。

關於nginx負載均衡配置的幾個狀態參數講解。

  • down,表示當前的server暫時不參與負載均衡。

  • backup,預留的備份機器。當其餘全部的非backup機器出現故障或者忙的時候,纔會請求backup機器,所以這臺機器的壓力最輕。

  • max_fails,容許請求失敗的次數,默認爲1。當超過最大次數時,返回proxy_next_upstream 模塊定義的錯誤。

  • fail_timeout,在經歷了max_fails次失敗後,暫停服務的時間。max_fails能夠和fail_timeout一塊兒使用。

 upstream mysvr { 
      server 127.0.0.1:7878 weight=2 max_fails=2 fail_timeout=2;
      server 192.168.10.121:3333 weight=1 max_fails=2 fail_timeout=1;    
    }

到這裏應該能夠說nginx的內置負載均衡算法已經沒有貨啦。若是你像跟多更深刻的瞭解nginx的負載均衡算法,nginx官方提供一些插件你們能夠了解下。

 

 

 

NGINX 優化【壓縮】

1、Vim打開Nginx配置文件

vim /usr/local/nginx/conf/nginx.conf

2、找到以下一段,進行修改

gzip on;
gzip_min_length 1k;
gzip_buffers 4 16k;
#gzip_http_version 1.0;
gzip_comp_level 2;
gzip_types text/plain application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png;
gzip_vary off;
gzip_disable "MSIE [1-6]\.";

3、解釋一下

第1行:開啓Gzip

第2行:不壓縮臨界值,大於1K的才壓縮,通常不用改

第3行:buffer,就是,嗯,算了不解釋了,不用改

第4行:用了反向代理的話,末端通訊是HTTP/1.0,有需求的應該也不用看我這科普文了;有這句的話註釋了就好了,默認是HTTP/1.1

第5行:壓縮級別,1-10,數字越大壓縮的越好,時間也越長,看心情隨便改吧

第6行:進行壓縮的文件類型,缺啥補啥就好了,JavaScript有兩種寫法,最好都寫上吧,總有人抱怨js文件沒有壓縮,其實多寫一種格式就好了

第7行:跟Squid等緩存服務有關,on的話會在Header裏增長"Vary: Accept-Encoding",我不須要這玩意,本身對照狀況看着辦吧

第8行:IE6對Gzip不怎麼友好,不給它Gzip了

 

4、:wq保存退出,從新加載Nginx

/usr/local/nginx/sbin/nginx -s reload

 

5、用curl測試Gzip是否成功開啓

curl -I -H "Accept-Encoding: gzip, deflate" "http://www.slyar.com/blog/"

HTTP/1.1 200 OK
Server: nginx/1.0.15
Date: Sun, 26 Aug 2012 18:13:09 GMT
Content-Type: text/html; charset=UTF-8
Connection: keep-alive
X-Powered-By: PHP/5.2.17p1
X-Pingback: http://www.slyar.com/blog/xmlrpc.php
Content-Encoding: gzip

頁面成功壓縮

 

curl -I -H "Accept-Encoding: gzip, deflate" "http://www.slyar.com/blog/wp-content/plugins/photonic/include/css/photonic.css"

HTTP/1.1 200 OK
Server: nginx/1.0.15
Date: Sun, 26 Aug 2012 18:21:25 GMT
Content-Type: text/css
Last-Modified: Sun, 26 Aug 2012 15:17:07 GMT
Connection: keep-alive
Expires: Mon, 27 Aug 2012 06:21:25 GMT
Cache-Control: max-age=43200
Content-Encoding: gzip

css文件成功壓縮

curl -I -H "Accept-Encoding: gzip, deflate" "http://www.slyar.com/blog/wp-includes/js/jquery/jquery.js"

HTTP/1.1 200 OK
Server: nginx/1.0.15
Date: Sun, 26 Aug 2012 18:21:38 GMT
Content-Type: application/x-javascript
Last-Modified: Thu, 12 Jul 2012 17:42:45 GMT
Connection: keep-alive
Expires: Mon, 27 Aug 2012 06:21:38 GMT
Cache-Control: max-age=43200
Content-Encoding: gzip

js文件成功壓縮

curl -I -H "Accept-Encoding: gzip, deflate" "http://www.slyar.com/blog/wp-content/uploads/2012/08/2012-08-23_203542.png"

HTTP/1.1 200 OK
Server: nginx/1.0.15
Date: Sun, 26 Aug 2012 18:22:45 GMT
Content-Type: image/png
Last-Modified: Thu, 23 Aug 2012 13:50:53 GMT
Connection: keep-alive
Expires: Tue, 25 Sep 2012 18:22:45 GMT
Cache-Control: max-age=2592000
Content-Encoding: gzip

圖片成功壓縮

curl -I -H "Accept-Encoding: gzip, deflate" "http://www.slyar.com/blog/wp-content/plugins/wp-multicollinks/wp-multicollinks.css"

HTTP/1.1 200 OK
Server: nginx/1.0.15
Date: Sun, 26 Aug 2012 18:23:27 GMT
Content-Type: text/css
Content-Length: 180
Last-Modified: Sat, 02 May 2009 08:46:15 GMT
Connection: keep-alive
Expires: Mon, 27 Aug 2012 06:23:27 GMT
Cache-Control: max-age=43200
Accept-Ranges: bytes

最後來個不到1K的文件,因爲個人閾值是1K,因此沒壓縮

 

NGINX 優化【緩存】

 

#user  nobody;

#工做進程個數:多開幾個能夠減小io帶來的影響,
worker_processes 4;

#worker_cpu_affinity須要結合worker_processes使用,一個worker_processes綁定一個CPU,
#worker_cpu_affinity 01 10 01 10;

#4核CPU,開戶4個進程


#pid        logs/nginx.pid;


events {

    #使用epoll模型提升性能
    #use epoll;

    #單個進程鏈接數(最大鏈接數=鏈接數*進程數)
    worker_connections 65535;
}


http {

    #文件擴展名與文件類型映射表 
    include       mime.types;
    #默認文件類型
    default_type  application/octet-stream;

    #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
    #                  '$status $body_bytes_sent "$http_referer" '
    #                  '"$http_user_agent" "$http_x_forwarded_for"';

    #access_log  logs/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    #長鏈接超時時間,單位是秒 
    keepalive_timeout  65;

    #gzip 是告訴nginx採用gzip壓縮的形式發送數據。這將會減小咱們發送的數據量。
    gzip on;
    gzip_min_length 1k;
    gzip_buffers 4 16k;
    #gzip_http_version 1.0;
    gzip_comp_level 2;
    gzip_types text/plain application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png;
    gzip_vary off;
    gzip_disable "MSIE [1-6]\.";

    #header設置:用戶真實的ip地址轉發給後端服務器
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Real-IP $remote_addr;

    #緩衝
    client_body_buffer_size 512k;
    proxy_connect_timeout 5;
    proxy_read_timeout 60;
    proxy_send_timeout 5;
    proxy_buffer_size 16k;
    proxy_buffers 4 64k;
    proxy_busy_buffers_size 128k;
    proxy_temp_file_write_size 128k;


    ##########################緩存#####################

    #設置緩存臨時目錄,要配合linux的內存目錄/dev/shm使用的話,必須給賦予目錄權限,由於默認root權限
    #proxy_temp_path /dev/shm/demo/proxy_temp_path;
    proxy_temp_path /WorkSpaces/nginx/temp/proxy_temp;

    #設置緩存目錄,並設置Web緩存區名稱爲cache_one,內存緩存空間大小爲128m,7天沒有被訪問的內容自動清除,硬盤緩存空間大小爲5GB。
    #proxy_cache_path /dev/shm/demo/proxy_cache_path levels=1:2 keys_zone=cache_one:128m inactive=7d max_size=5g;
    proxy_cache_path /WorkSpaces/nginx/temp/proxy_cache levels=1:2 keys_zone=cache_one:128m inactive=7d max_size=5g;

    

    #啓用html、jsp...<meta>標籤不緩存的設置
    proxy_ignore_headers X-Accel-Expires Expires Cache-Control Set-Cookie;

    ################################################集羣 ###################################################    

    #動態資源集羣
    upstream www_server  {

    #服務器配置 weight是權重的意思,權重越大,分配的機率越大。
        server 127.0.0.1:8000    weight=1 max_fails=3 fail_timeout=30s;
    server 127.0.0.1:8000    weight=1 max_fails=3 fail_timeout=30s;

    }

    #靜態資源集羣
    upstream static_server { 
        server 127.0.0.1:8000    weight=1 max_fails=3 fail_timeout=30s;
    }

    server {

        #監聽80端口,能夠改爲其餘端口 
        listen       80;

    #nginx服務的域名,經過域名就能夠訪問應用
        server_name  www.wechat520.com;


        #用於清除緩存的url設置
        #假設一個URL爲demo/test.gif,那麼就能夠經過訪問demo/purge/test.gif清除該URL的緩存。
        location ~ /purge(/.*) {

            #設置只容許指定的IP或IP段才能夠清除URL緩存
            allow 127.0.0.1;
            allow 10.74.147.91;

            deny all;
            #proxy_cache_purge cache_one $host$1$is_args$args;
        }


    #反向代理:網頁、視頻、圖片文件從nginx服務器讀取
        location ~ .*\.(gif|jpg|jpeg|png|bmp|swf|ioc|rar|zip|txt|flv|mid|doc|ppt|pdf|xls|mp3|wma)$
        { 

            ##########################緩存#####################
            #使用web緩存區cache_one
            proxy_cache cache_one;

            #對200 304 302狀態碼設置緩存時間5天,其餘的7天
            proxy_cache_valid 200 304 302 5d;
            proxy_cache_valid any 7d;

            #以域名、URI、參數組合成Web緩存的Key值,Nginx根據Key值哈希,存儲緩存內容到二級緩存目錄內
            proxy_cache_key $host$uri$is_args$args;

            #若是後端的服務器返回50二、504、執行超時等錯誤,自動將請求轉發到upstream負載均衡池中的另外一臺服務器,實現故障轉移
            #proxy_next_upstream http_502 http_504 error timeout invalid_header;

            #增長一個header字段方便在瀏覽器查看是否擊中緩存(生產中可註釋)
            add_header X-Cache '$upstream_cache_status from $host';



            #反向代理,靜態的由nginx來處理(不配置默認nginx的html目錄,靜態資源的目錄結構必須和tomcat的web工程一致)
            proxy_pass http://www_server; 

            #瀏覽器中緩存30天
            expires 30d;
        }




    location ~ .*\.(js|css|htm|html)$ {  
            root   /WorkSpaces/nginx/temp/www/cache;  
            proxy_store on;  
            proxy_set_header Accept-Encoding '';  
            proxy_temp_path /WorkSpaces/nginx/temp/www/tmp;  
        expires 360s;
  
            rewrite ^/$ /index.html last;  
            if ( !-f $request_filename ) {  
                proxy_pass http://www_server$request_uri;  
            }  
        }  


        #錯誤提示頁面
        error_page 500 502 503 504 /50x.html;
        location = /50x.html {
            root html;
        }

    }

    #靜態資源服務器
    server{

        listen 80;

        server_name static.wechat520.com;

        #反向代理:網頁、視頻、圖片文件從nginx服務器讀取
        location ~ .*\.(js|css|htm|html|gif|jpg|jpeg|png|bmp|swf|ioc|rar|zip|txt|flv|mid|doc|ppt|pdf|xls|mp3|wma)$
        { 
        #增長一個header字段方便在瀏覽器查看是否擊中緩存(生產中可註釋)
            add_header X-Cache '$upstream_cache_status from $host';

        #反向代理,靜態的由nginx來處理(不配置默認nginx的html目錄,靜態資源的目錄結構必須和tomcat的web工程一致)
            proxy_pass http://static_server; 

            #瀏覽器中緩存30天
            expires 30d;
        } 
    }
}

 

 

 

nginx location正則寫法
一個示例:

location  = / {
  # 精確匹配 / ,主機名後面不能帶任何字符串
  [ configuration A ] 
}

location  / {
  # 由於全部的地址都以 / 開頭,因此這條規則將匹配到全部請求
  # 可是正則和最長字符串會優先匹配
  [ configuration B ] 
}

location /documents/ {
  # 匹配任何以 /documents/ 開頭的地址,匹配符合之後,還要繼續往下搜索
  # 只有後面的正則表達式沒有匹配到時,這一條纔會採用這一條
  [ configuration C ] 
}

location ~ /documents/Abc {
  # 匹配任何以 /documents/ 開頭的地址,匹配符合之後,還要繼續往下搜索
  # 只有後面的正則表達式沒有匹配到時,這一條纔會採用這一條
  [ configuration CC ] 
}

location ^~ /images/ {
  # 匹配任何以 /images/ 開頭的地址,匹配符合之後,中止往下搜索正則,採用這一條。
  [ configuration D ] 
}

location ~* \.(gif|jpg|jpeg)$ {
  # 匹配全部以 gif,jpg或jpeg 結尾的請求
  # 然而,全部請求 /images/ 下的圖片會被 config D 處理,由於 ^~ 到達不了這一條正則
  [ configuration E ] 
}

location /images/ {
  # 字符匹配到 /images/,繼續往下,會發現 ^~ 存在
  [ configuration F ] 
}

location /images/abc {
  # 最長字符匹配到 /images/abc,繼續往下,會發現 ^~ 存在
  # F與G的放置順序是沒有關係的
  [ configuration G ] 
}

location ~ /images/abc/ {
  # 只有去掉 config D 纔有效:先最長匹配 config G 開頭的地址,繼續往下搜索,匹配到這一條正則,採用
    [ configuration H ] 
}

location ~* /js/.*/\.js
已=開頭表示精確匹配
如 A 中只匹配根目錄結尾的請求,後面不能帶任何字符串。
^~ 開頭表示uri以某個常規字符串開頭,不是正則匹配
~ 開頭表示區分大小寫的正則匹配;
~* 開頭表示不區分大小寫的正則匹配
/ 通用匹配, 若是沒有其它匹配,任何請求都會匹配到
順序 no優先級:
(location =) > (location 完整路徑) > (location ^~ 路徑) > (location ~,~* 正則順序) > (location 部分起始路徑) > (/)

上面的匹配結果
按照上面的location寫法,如下的匹配示例成立:

/ -> config A
精確徹底匹配,即便/index.html也匹配不了
/downloads/download.html -> config B
匹配B之後,往下沒有任何匹配,採用B
/images/1.gif -> configuration D
匹配到F,往下匹配到D,中止往下
/images/abc/def -> config D
最長匹配到G,往下匹配D,中止往下
你能夠看到 任何以/images/開頭的都會匹配到D並中止,FG寫在這裏是沒有任何意義的,H是永遠輪不到的,這裏只是爲了說明匹配順序
/documents/document.html -> config C
匹配到C,往下沒有任何匹配,採用C
/documents/1.jpg -> configuration E
匹配到C,往下正則匹配到E
/documents/Abc.jpg -> config CC
最長匹配到C,往下正則順序匹配到CC,不會往下到E
實際使用建議
因此實際使用中,我的以爲至少有三個匹配規則定義,以下:
#直接匹配網站根,經過域名訪問網站首頁比較頻繁,使用這個會加速處理,官網如是說。
#這裏是直接轉發給後端應用服務器了,也能夠是一個靜態首頁
# 第一個必選規則
location = / {
    proxy_pass http://tomcat:8080/index
}
# 第二個必選規則是處理靜態文件請求,這是nginx做爲http服務器的強項
# 有兩種配置模式,目錄匹配或後綴匹配,任選其一或搭配使用
location ^~ /static/ {
    root /webroot/static/;
}
location ~* \.(gif|jpg|jpeg|png|css|js|ico)$ {
    root /webroot/res/;
}
#第三個規則就是通用規則,用來轉發動態請求到後端應用服務器
#非靜態文件請求就默認是動態請求,本身根據實際把握
#畢竟目前的一些框架的流行,帶.php,.jsp後綴的狀況不多了
location / {
    proxy_pass http://tomcat:8080/
}
http://tengine.taobao.org/book/chapter_02.html
http://nginx.org/en/docs/http/ngx_http_rewrite_module.html

Rewrite規則
rewrite功能就是,使用nginx提供的全局變量或本身設置的變量,結合正則表達式和標誌位實現url重寫以及重定向。rewrite只能放在server{},location{},if{}中,而且只能對域名後邊的除去傳遞的參數外的字符串起做用,例如 http://seanlook.com/a/we/index.php?id=1&u=str 只對/a/we/index.php重寫。語法rewrite regex replacement [flag];

若是相對域名或參數字符串起做用,可使用全局變量匹配,也可使用proxy_pass反向代理。

代表看rewrite和location功能有點像,都能實現跳轉,主要區別在於rewrite是在同一域名內更改獲取資源的路徑,而location是對一類路徑作控制訪問或反向代理,能夠proxy_pass到其餘機器。不少狀況下rewrite也會寫在location裏,它們的執行順序是:

執行server塊的rewrite指令
執行location匹配
執行選定的location中的rewrite指令
若是其中某步URI被重寫,則從新循環執行1-3,直到找到真實存在的文件;循環超過10次,則返回500 Internal Server Error錯誤。

flag標誌位
last : 至關於Apache的[L]標記,表示完成rewrite
break : 中止執行當前虛擬主機的後續rewrite指令集
redirect : 返回302臨時重定向,地址欄會顯示跳轉後的地址
permanent : 返回301永久重定向,地址欄會顯示跳轉後的地址
由於301和302不能簡單的只返回狀態碼,還必須有重定向的URL,這就是return指令沒法返回301,302的緣由了。這裏 last 和 break 區別有點難以理解:

last通常寫在server和if中,而break通常使用在location中
last不終止重寫後的url匹配,即新的url會再從server走一遍匹配流程,而break終止重寫後的匹配
break和last都能組織繼續執行後面的rewrite指令
if指令與全局變量
if判斷指令
語法爲if(condition){...},對給定的條件condition進行判斷。若是爲真,大括號內的rewrite指令將被執行,if條件(conditon)能夠是以下任何內容:

當表達式只是一個變量時,若是值爲空或任何以0開頭的字符串都會當作false
直接比較變量和內容時,使用=或!=
~正則表達式匹配,~*不區分大小寫的匹配,!~區分大小寫的不匹配
-f和!-f用來判斷是否存在文件
-d和!-d用來判斷是否存在目錄
-e和!-e用來判斷是否存在文件或目錄
-x和!-x用來判斷文件是否可執行

例如:

if ($http_user_agent ~ MSIE) {
    rewrite ^(.*)$ /msie/$1 break;
} //若是UA包含"MSIE",rewrite請求到/msid/目錄下

if ($http_cookie ~* "id=([^;]+)(?:;|$)") {
    set $id $1;
 } //若是cookie匹配正則,設置變量$id等於正則引用部分

if ($request_method = POST) {
    return 405;
} //若是提交方法爲POST,則返回狀態405(Method not allowed)。return不能返回301,302

if ($slow) {
    limit_rate 10k;
} //限速,$slow能夠經過 set 指令設置

if (!-f $request_filename){
    break;
    proxy_pass  http://127.0.0.1; 
} //若是請求的文件名不存在,則反向代理到localhost 。這裏的break也是中止rewrite檢查

if ($args ~ post=140){
    rewrite ^ http://example.com/ permanent;
} //若是query string中包含"post=140",永久重定向到example.com

location ~* \.(gif|jpg|png|swf|flv)$ {
    valid_referers none blocked www.jefflei.com www.leizhenfang.com;
    if ($invalid_referer) {
        return 404;
    } //防盜鏈
}
全局變量
下面是能夠用做if判斷的全局變量

$args : #這個變量等於請求行中的參數,同$query_string
$content_length : 請求頭中的Content-length字段。
$content_type : 請求頭中的Content-Type字段。
$document_root : 當前請求在root指令中指定的值。
$host : 請求主機頭字段,不然爲服務器名稱。
$http_user_agent : 客戶端agent信息
$http_cookie : 客戶端cookie信息
$limit_rate : 這個變量能夠限制鏈接速率。
$request_method : 客戶端請求的動做,一般爲GET或POST。
$remote_addr : 客戶端的IP地址。
$remote_port : 客戶端的端口。
$remote_user : 已經通過Auth Basic Module驗證的用戶名。
$request_filename : 當前請求的文件路徑,由root或alias指令與URI請求生成。
$scheme : HTTP方法(如http,https)。
$server_protocol : 請求使用的協議,一般是HTTP/1.0或HTTP/1.1。
$server_addr : 服務器地址,在完成一次系統調用後能夠肯定這個值。
$server_name : 服務器名稱。
$server_port : 請求到達服務器的端口號。
$request_uri : 包含請求參數的原始URI,不包含主機名,如:」/foo/bar.php?arg=baz」。
$uri : 不帶請求參數的當前URI,$uri不包含主機名,如」/foo/bar.html」。
$document_uri : 與$uri相同。
例:http://localhost:88/test1/test2/test.php
$host:localhost
$server_port:88
$request_uri:http://localhost:88/test1/test2/test.php
$document_uri:/test1/test2/test.php
$document_root:/var/www/html
$request_filename:/var/www/html/test1/test2/test.php

經常使用正則
. : 匹配除換行符之外的任意字符
? : 重複0次或1次
+ : 重複1次或更屢次
* : 重複0次或更屢次
\d :匹配數字
^ : 匹配字符串的開始
$ : 匹配字符串的介紹
{n} : 重複n次
{n,} : 重複n次或更屢次
[c] : 匹配單個字符c
[a-z] : 匹配a-z小寫字母的任意一個
小括號()之間匹配的內容,能夠在後面經過$1來引用,$2表示的是前面第二個()裏的內容。正則裏面容易讓人困惑的是\轉義特殊字符。

rewrite實例
例1:

http {
    # 定義image日誌格式
    log_format imagelog '[$time_local] ' $image_file ' ' $image_type ' ' $body_bytes_sent ' ' $status;
    # 開啓重寫日誌
    rewrite_log on;

    server {
        root /home/www;

        location / {
                # 重寫規則信息
                error_log logs/rewrite.log notice; 
                # 注意這裏要用‘’單引號引發來,避免{}
                rewrite '^/images/([a-z]{2})/([a-z0-9]{5})/(.*)\.(png|jpg|gif)$' /data?file=$3.$4;
                # 注意不能在上面這條規則後面加上「last」參數,不然下面的set指令不會執行
                set $image_file $3;
                set $image_type $4;
        }

        location /data {
                # 指定針對圖片的日誌格式,來分析圖片類型和大小
                access_log logs/images.log mian;
                root /data/images;
                # 應用前面定義的變量。判斷首先文件在不在,不在再判斷目錄在不在,若是還不在就跳轉到最後一個url裏
                try_files /$arg_file /image404.html;
        }
        location = /image404.html {
                # 圖片不存在返回特定的信息
                return 404 "image not found\n";
        }
}

對形如/images/ef/uh7b3/test.png的請求,重寫到/data?file=test.png,因而匹配到location /data,先看/data/images/test.png文件存不存在,若是存在則正常響應,若是不存在則重寫tryfiles到新的image404 location,直接返回404狀態碼。

例2:

rewrite ^/images/(.*)_(\d+)x(\d+)\.(png|jpg|gif)$ /resizer/$1.$4?width=$2&height=$3? last;
對形如/images/bla_500x400.jpg的文件請求,重寫到/resizer/bla.jpg?width=500&height=400地址,並會繼續嘗試匹配location。

 

這個location

location ~ ^/(.+)\.3gp\.zip$ {
#            access_by_lua_file  "/opt/pro/nginx/lua/zip_access.lua";
    rewrite_by_lua_file "/opt/pro/nginx/lua/zip_access.lua";
        }

匹配 http://192.168.75.80:8092/20160614/mobi/vod/ts01/TVM/video/3gp/TVM/HuNanHD/2016/04/27/80a4b71a-c000-46fa-916b-70d9e2445635/Q350/Q350.3gp.zip?&end=5

\.表明.    其中\是轉義字符。    單獨的.表明 匹配除換行符之外的任意字符   +匹配重複1次或更屢次
相關文章
相關標籤/搜索