nginx負載均衡(5種方式)、rewrite重寫規則及多server反代配置梳理

散盡浮華發表於2017-02-14

 

Nginx除了可以用作web伺服器外,他還可以用來做高效能的反向代理伺服器,它能提供穩定高效的負載均衡解決方案。nginx可以用輪詢、IP雜湊、URL雜湊等方式排程後端伺服器,同時也能提供健康檢查功能。目前有眾多公司均已經部署使用nginx實現基於七層的負載均衡功能。

1)Nginx負載均衡
為了實現Nginx的反向代理以及負載均衡功能,應用中需要用到兩個模組,HttpProxyModule和HttpUpstreamModule模組;其中HttpProxyModule模組的作用是將使用者的資料請求轉發到其他伺服器上,HttpUpstreamModule模組是提供負載均衡技術。

Nginx目前提供的負載均衡演算法:
a)ngx_http_upstream_round_robin:加權輪詢,可均分請求,是預設演算法,整合在框架中。
b)ngx_http_upstream_ip_hash_module:IP雜湊,可保持會話。
c)ngx_http_upstream_least_conn_module:最少連線數,可均分連線。
d)ngx_http_upstream_hash_module:一致性雜湊,可減少快取資料的失效。

nginx的upstream負載均衡目前支援的幾種方式:
a)輪詢(預設)
預設選項,當weight不指定時,各伺服器weight相同, 每個請求按時間順序逐一分配到不同的後端伺服器,如果後端伺服器down掉,能自動剔除。

upstream bakend {
server 192.168.1.10;
server 192.168.1.11;
}

b)weight
指定輪詢機率,weight和訪問比率成正比,用於後端伺服器效能不均的情況。如果後端伺服器down掉,能自動剔除。 比如下面配置,則1.11伺服器的訪問量為1.10伺服器的兩倍(後端節點中配置高的伺服器可以適當將weight設定大點)。

upstream bakend {
server 192.168.1.10 weight=1;
server 192.168.1.11 weight=2;
}

c)ip_hash
每個請求按訪問ip的hash結果分配,這樣每個訪客固定訪問一個後端伺服器,可以解決session不能跨伺服器的問題,實現session共享。如果後端伺服器down掉,要手工處理。

upstream resinserver{
ip_hash;
server 192.168.1.10:8080;
server 192.168.1.11:8080;
}
   
============================================================================================================
之前遇到的一個問題:Nginx反向代理兩臺tomcat應用伺服器,發現在nginx的upstream負載配置裡:
1)如果不配置ip_hash負載到後端的兩臺節點上,則訪問後臺頁面,輸入使用者名稱和密碼,點選"登入"則無反應或無法訪問後臺!
2)如果不配置ip_hash負載到後端的任意一臺單節點上(另一臺節點的負載配置註釋掉),則訪問後臺頁面,輸入使用者名稱和密碼,點選"登入"則會成功登入進去!
3)配置ip_hash負載到後端的兩臺節點上,則訪問後臺頁面,輸入使用者名稱和密碼,點選"登入"則會成功登入進去!
    
如下配置,在後面兩臺機器192.168.10.20和192.168.10.21的tomcat埠(8080)都活著的情況下,前面nginx代理層的upstream配置裡,
如果註釋掉了ip_hash,則會造成訪問http://bpm.kevin.com頁面,輸入使用者名稱和密碼後,點選登陸失敗!
如果加上ip_hash,則登陸就ok。
   
[root@kevin-lb vhosts]# cat bpm.kevin.com.conf
upstream os-8080 {
      ip_hash;
      server 192.168.10.20:8080 max_fails=3 fail_timeout=15s;
      server 192.168.10.21:8080 max_fails=3 fail_timeout=15s;
}
              
  server {
      listen      80;
      server_name bpm.kevin.com;
        
      access_log  /data/nginx/logs/bpm.kevin.com-access.log main;
      error_log  /data/nginx/logs/bpm.kevin.com-error.log;
        
 location / {
         proxy_pass http://os-8080;
         proxy_redirect  http://os-8080/ http://bpm.kevin.com/;
         proxy_set_header X-Real-IP $remote_addr;
         proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
}
   
=================原因分析============================================
當後端節點是動態應用伺服器的話,前面的nginx負載層要用ip_hash做session共享,否則nginx負載預設是輪詢策略(每個請求按時間順序逐一分配到不同的後端伺服器),
就是說當你開啟登入介面,輸入使用者名稱和密碼,這時候請求是到後端的A機器上;當你點選"登入",按照輪詢策略,此時請求就到了後端的B機器上。
所以會出現登入無反應的現象。
====================================================================
   
再看下面一例
[root@kevin-lb vhosts]# cat portal.kevin.com.conf
server {
    listen 80;
    server_name  portal.kevin.com;
    access_log  /data/nginx/logs/portal.kevin.com-access.log main;
    error_log  /data/nginx/logs/portal.kevin.com-error.log;
    root  /data/web/webroot;
     index index.html;
 
    location / {
        if ($arg_response_for) {
          add_header X-Response-For $arg_response_for;
        }
 
        try_files $uri $uri/ /index.html;
    }
    location ~ /prod {
        rewrite /prod/(.*)$ /$1 break;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_pass http://10.0.54.20:9040;
    }
 
    location /portal-pc/captcha/login {
        proxy_pass http://10.0.54.20:9040;
    }
    location /portal-pc/captcha/mobile {
        proxy_pass http://10.0.54.20:9040;
    }
 
    location /portal-pc/login {
        rewrite .* /?response_for=unlogined break;
    }
 
    location /portal-pc/user/center {
        rewrite .* /?response_for=logined break;
    }
 
    location /msdp-file {
        proxy_pass http://10.0.54.20:9020/msdp-file;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
    location /upload {
        proxy_pass http://10.0.54.20:9020/upload;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}
 
[root@kevin-lb vhosts]# ll -d /data/web/webroot
drwxr-xr-x 4 www www 12288 7月  12 21:06 /data/web/webroot
[root@kevin-lb vhosts]# ll /data/web/webroot/index.html
-rw-r--r-- 1 www www 1348 7月  12 21:06 /data/web/webroot/index.html

如nginx反向代理後端兩臺apache應用,涉及到網站後臺登入。如果不使用ip_hash實現session共享,則會出現:
1)使用域名登入後臺,輸入使用者名稱和密碼,第一次點選"登入"沒有反應,閃一下,第二次點選"登入"才會登入到後臺。
2)使用後端apache自己的ip登入後臺,輸入使用者名稱和密碼,點選"登入"可以成功登入到後臺。
3)這就是因為nginx代理時,沒有配置ip_hash造成的,即沒有達到session共享效果。
輸入使用者名稱和密碼的session資訊儲存到appche01機器上,點選"登入"操作後卻是去apache02機器上拿session。
此時apache02上沒有這個session,所以第一次會出現閃一下沒有登入到後臺的現象。
第二次點選"登入"後就輪到去apache01機器上拿session,此時正好apache01機器上有這個session,故第二次就能登入到後臺了。
因此,在nginx的代理配置中啟用ip_hash,就可以實現session共享,則就不會出現上面這種現象了。

nginx代理配置中幾個引數說明

proxy_redirect off;                                            # 代理是否支援重定向
proxy_set_header X-Real-IP $remote_addr;                # 遠端真實ip地址
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;   # 反向代理之後轉發之前的ip地址
proxy_set_header Host $http_host;                    # http請求的主機域名
proxy_set_header X-NginX-Proxy true;                  # nginx代理

d)fair(第三方外掛)
按後端伺服器的響應時間來分配請求,響應時間短的優先分配。

upstream resinserver{
server 192.168.1.10:8080;
server 192.168.1.11:8080;
fair;
}

e)url_hash(第三方外掛)
按訪問url的hash結果來分配請求,使每個url定向到同一個後端伺服器,後端伺服器為快取伺服器時比較有效。 在upstream中加入hash語句,hash_method是使用的hash演算法。

upstream resinserver{
server 192.168.1.10:8080;
server 192.168.1.11:8080;
hash $request_uri;
hash_method crc32;
}

裝置的狀態:
down            表示單前的server暫時不參與負載
weight          權重,預設為1。 weight越大,負載的權重就越大。
max_fails      允許請求失敗的次數預設為1。當超過最大次數時,返回proxy_next_upstream 模組定義的錯誤
fail_timeout   max_fails次失敗後,暫停的時間。
backup          備用伺服器, 其它所有的非backup機器down或者忙的時候,請求backup機器。所以這臺機器壓力會最輕。

下面是負載均衡實現原理拓撲圖(多層負載)

Nginx反向代理模組配置方法示例說明:

location ~* \.(mp3|mp4)$ {        //匹配URL以MP3或者MP4結尾的請求
    proxy_pass http://localhost:8080        //轉發到本機8080埠
}

location / {                                    //匹配任意URL
    proxy_pass http://localhost:8081  //轉發到本機8081埠
        proxy_set_header    X-Forwarded-For    $remote_addr    //保留使用者真實IP
}

location指令可以直接匹配字串,也可以進行正規表示式匹配
~表示區分大小寫,~*表示不區分大小寫匹配,=表示精確匹配
proxy_pass指令可以根據location匹配的情況建立前後端的代理對映關係
X-Forwarded-For用於實現定義資料包頭,記錄使用者真實IP

Nginx負載均衡模組配置方法示例說明:

upstream backend {
ip_hash;
server web1.test.com weight 1;
server web2.test.com weight 2;
server web3.test.com ;
}

server {
listen 80;
server_name web.test.com;
location / {
proxy_pass http://backend;
}
}

upstream定義後端伺服器集合,backend是伺服器組名
proxy-pass和fastcgi_pass將請求轉發給一組伺服器
ip_hash可以根據使用者ip地址的hash值分配固定的後端伺服器

2)Nginx負載均衡案例解析
伺服器名稱                  網路配置
nginx.test.com           eth0:111.122.155.133
                               eth1:192.168.1.2
web1.test.com           eht0:192.168.1.3
web2.test.com           eth0:192.168.1.4
web3.test.com           eth0:192.168.1.5

3臺web機器配置:

在web1 web2 web3上安裝httpd並配置網路卡。操作步驟如下:(下面是web1的操作,web2和web3的操作步驟類似。注意修改紅色部分的引數
# vim /etc/sysconfig/network-scripts/ifcfg-eth0

DEVICE=eth0
BOOTPROTO=static
IPADDR=192.168.1.3
NETMASK=255.255.255.0
GATEWAY=192.168.1.2
ONBOOT=yes
TYPE=Ethernet

接著執行下面命令:

# service network restart
# yum install -y httpd
# iptables -F
# iptables -X
# service iptables save
# setenforce 0
# sed -i s/enforcing/disabled/g /etc/sysconfig/selinux
# echo "web1 192.168.1.3" > /var/www/html/index.html
# service httpd restart
# chkconfig httpd on

nginx代理伺服器配置

# vim /etc/sysconfig/network-scripts/ifcfg-eth0

DEVICE=eth0
BOOTPROTO=static
IPADDR=111.122.155.133
NETMASK=255.255.255.0
GATEWAY=111.122.155.0
ONBOOT=yes
TYPE=Ethernet

# vim /etc/sysconfig/network-scripts/ifcfg-eth1

DEVICE=eth1
BOOTPROTO=static
IPADDR=192.168.1.2
NETMASK=255.255.255.0
GATEWAY=192.168.1.1
ONBOOT=yes
TYPE=Ethernet

接著執行下面命令:

# service network restart
# iptables -F
# iptables -X
# service iptables save
# setenforce 0
# sed -i s/enforcing/disabled/g /etc/sysconfig/selinux

# wget http://nginx.org/download/nginx-1.6.3.tar.gz
# tar zxf nginx-1.6.3.tar.gz -C /usr/src/
# yum install gcc pcre pcre-devel openssl openssl-devel gd gd-devel perl perl-ExtUtils-Embed
# cd /usr/src/nginx-1.6.3/
# ./configure --prefix=/usr/local/nginx --with-ipv6 --with-http_ssl_module --with-http_realip_module --with-http_addition_module --with-http_dav_module --with-http_gzip_static_module --with-http_perl_module --with-mail_ssl_module
# make && make install

接著修改nginx配置檔案
# vim /usr/local/nginx/conf/nginx.conf

user    nobody;
worker_processes    1;
error_log    logs/error.log    notice;
pid    logs/nginx.pid;

events    {
worker_connections    5024;
}

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" ';
sendfile    on;
tcp_nopush    on;
server_tokens    off;
keepalive_timeout    65;
keepalive_requests    100;

gzip    on;                                    //開啟壓縮
gzip_min_length    1000;                //小於1000B內容不壓縮
gzip_buffers    16    32k;                //壓縮快取的個數和容量
gzip_types    text/plain    application/xml;        //指定壓縮檔案型別
gzip_comp_level    2;                    //壓縮級別為2,數字越大壓縮效果越好

client_body_buffer_size    128k;                        //允許客戶端請求快取大小
client_max_body_size    100m;                            //允許請求的最大檔案容量
large-client_header_buffers    4    8k;                //
proxy_buffering    on;                                          //開啟代理緩衝功能
proxy_buffer_size    8k;                                        //第一部分響應資料的快取大小
proxy_buffers    8    128k;                                    //響應資料的快取個數和容量
proxy_cache_path    /usr/local/nginx/cache    levels=1:2    keys_zone=one:100m    inactive=1d    max_size=2G;   

//設定快取目錄,levels設定快取個數,keys_zone定義快取名字和容量,inactive定義快取存活時間,max_size定義硬碟的快取容量
proxy_connect_timeout    60s;            //與後端伺服器建立TCP連線握手超時時間
upstream servers {

//ip_hash;ip_hash確保相同客戶端ip使用相同的後端伺服器,不適用就預設輪詢
server    192.168.1.3:80    max_fails=3    fail_timeout=30s    weight=2;
server    192.168.1.4:80    max_fails=3    fail_timeout=30s    weight=2;
server    192.168.1.5:80    max_fails=3    fail_timeout=30s    weight=2;
}

server {
    listen    80;
    server_name    web.test.com;
    access_log    logs/host.access.log    main;
    location / {

proxy_pass http://servers;
proxy_cache one;
proxy_set_header X-Forwarded-For $remote_addr;
    }

}}

配置完成執行:

# echo "/usr/local/nginx/sbin/nginx" >> /etc/rc.local

最後瀏覽器訪問http://192.168.1.2 或者http://111.122.155.133 重新整理將分別得到不同的web頁面資訊

3)Nginx rewrite規則
nginx的rewrite語法格式和apache非常相似,rewrite regex replacement [flag],其中flag可以被設定為last結束當前指令並重新搜尋location匹配、break結束當前rewrite指令、redirect臨時重定向302、permanent永久重定向301。

rewrite地址重寫及return應用的語法解析:
根據瀏覽器標識,訪問資源重定向到指定檔案目錄,下面用IE瀏覽器示例:

if ($http_user_agent ~ MSIE ) {
   rewrite ^(.*)$ /msie/$1 break;
}

將移動客戶端的請求重定向到其他伺服器:

if    ($http_user_agent ~* '(iphone|ipod)' )  {
      rewrite    ^.+    http://mobile.site.com$uri;
}

使用者使用POST方式請求資料時候,返回405:

if ($request_method = POST ) {
   return 405;
}

訪問admin時候重定向到admin目錄:

location /php_admin {
     rewrite ^/php_admin/.*$ /admin permanent;
}

-------------------------------------------下面詳細說下nginx的rewrite重寫指令用法-------------------------------------------
nginx通過ngx_http_rewrite_module模組支援url重寫、支援if條件判斷,但不支援else。
該模組需要PCRE支援,因此應在編譯nginx時指定PCRE原始碼目錄, nginx安裝方法。

1)Nginx Rewrite 基本標記 (flags)

last       基本上都用這個Flag。相當於Apache裡的[L]標記,表示完成rewrite,不再匹配後面的規則
break      中止 Rewirte,不再繼續匹配
redirect   返回臨時重定向的HTTP狀態302
permanent  返回永久重定向的HTTP狀態301。原有的url支援正則,重寫的url不支援正則

2)正規表示式匹配,其中:

* ~ 為區分大小寫匹配
* ~* 為不區分大小寫匹配
* !~和!~* 分別為區分大小寫不匹配及不區分大小寫不匹配

3)檔案及目錄匹配,其中:

* -f 和!-f 用來判斷是否存在檔案
* -d 和!-d 用來判斷是否存在目錄
* -e 和!-e 用來判斷是否存在檔案或目錄
* -x 和!-x 用來判斷檔案是否可執行

4)Nginx的一些可用的全域性變數,可用做條件判斷:

$args
$content_length
$content_type
$document_root
$document_uri
$host
$http_user_agent
$http_cookie
$limit_rate
$request_body_file
$request_method
$remote_addr
$remote_port
$remote_user
$request_filename
$request_uri
$query_string
$scheme
$server_protocol
$server_addr
$server_name
$server_port
$uri

nginx的rewrite指令執行順序:

1)執行server塊的rewrite指令(這裡的塊指的是server關鍵字後{}包圍的區域,其它xx塊類似)
2)執行location匹配
3)執行選定的location中的rewrite指令
如果其中某步URI被重寫,則重新迴圈執行1-3,直到找到真實存在的檔案
如果迴圈超過10次,則返回500 Internal Server Error錯誤

break指令
語法:break;
預設值:無
作用域:server,location,if

停止執行當前虛擬主機的後續rewrite指令集。
break指令例項:

 if ($slow) {
     limit_rate 10k;
     break;
 }

if指令
語法:if(condition){...}
預設值:無
作用域:server,location
對給定的條件condition進行判斷。如果為真,大括號內的rewrite指令將被執行。
if條件(conditon)可以是如下任何內容:

1)一個變數名;false如果這個變數是空字串或者以0開始的字串;
2)使用= ,!= 比較的一個變數和字串
3)是用~, ~*與正規表示式匹配的變數,如果這個正規表示式中包含},;則整個表示式需要用" 或' 包圍
4)使用-f ,!-f 檢查一個檔案是否存在
5)使用-d, !-d 檢查一個目錄是否存在
6)使用-e ,!-e 檢查一個檔案、目錄、符號連結是否存在
7)使用-x , !-x 檢查一個檔案是否可執行

if指令例項:

if ($http_user_agent ~ MSIE) {
     rewrite ^(.*)$ /msie/$1 break;
 }

 if ($http_cookie ~* "id=([^;]+)(?:;|$)") {
     set $id $1;
 }

 if ($request_method = POST) {
     return 405;
 }

 if ($slow) {
     limit_rate 10k;
 }

 if ($invalid_referer) {
     return 403;
 }

return指令

語法:
return code;
return code URL;
return URL;

預設值:無
作用域:server,location,if

停止處理並返回指定狀態碼(code)給客戶端。
非標準狀態碼444,表示關閉連線且不給客戶端發響應頭。
從0.8.42版本起,return 支援響應URL重定向(對於301,302,303,307),或者文字響應(對於其他狀態碼).
對於文字或者URL重定向可以包含變數

rewrite指令

語法:rewrite regex replacement [flag];
預設值:無
作用域:server,location,if
如果一個URI匹配指定的正規表示式regex,URI就按照replacement重寫。
rewrite按配置檔案中出現的順序執行。flags標誌可以停止繼續處理。
如果replacement以"http://"或"https://"開始,將不再繼續處理,這個重定向將返回給客戶端。

flag可以是如下引數:
last     停止處理後續rewrite指令集,然後對當前重寫的新URI在rewrite指令集上重新查詢。
break    停止處理後續rewrite指令集,並不在重新查詢,但是當前location內剩餘非rewrite語句和location外的非rewrite語句可以執行。
redirect 如果replacement不是以http:// 或https://開始,返回302臨時重定向
permant  返回301永久重定向

最終完整的重定向URL包括請求scheme(http://,https://等),請求的server_name_in_redirect和port_in_redirec三部分 ,說白了也就是http協議、域名、埠三部分組成。

rewrite例項說明:

server {
     ...
     rewrite ^(/download/.*)/media/(.*)\..*$ $1/mp3/$2.mp3 last;
     rewrite ^(/download/.*)/audio/(.*)\..*$ $1/mp3/$2.ra last;
     return 403;
     ...
 }

如果這些rewrite放到 “/download/” location如下所示, 那麼應使用break而不是last , 使用last將迴圈10次匹配,然後返回500錯誤:

location /download/ {
     rewrite ^(/download/.*)/media/(.*)\..*$ $1/mp3/$2.mp3 break;
     rewrite ^(/download/.*)/audio/(.*)\..*$ $1/mp3/$2.ra break;
     return 403;
 }

對於重寫後的URL(replacement)包含原請求的請求引數,原URL的?後的內容。如果不想帶原請求的引數 ,
可以在replacement後加一個問號。如下,我們加了一個自定義的引數user=$1,然後在結尾處放了一個問號?,
把原請的引數去掉。

rewrite ^/users/(.*)$ /show?user=$1? last;

如果正則表達regex式中包含 “}” 或 “;”, 那麼整個表示式需要用雙引號或單引號包圍.

rewrite_log指令

語法:rewrite_log on|off;
預設值:rewrite_log off;
作用域:http,server,location,if
開啟或關閉以notice級別列印rewrite處理日誌到error log檔案。

nginx開啟rewrite log的配置:

rewrite_log on;
error_log logs/xxx.error.log notice;

1)開啟rewrite on
2)把error log的級別調整到notice

set指令

語法:set variable value;
預設值:none
作用域:server,location,if
定義一個變數並賦值,值可以是文字,變數或者文字變數混合體。

uninitialized_variable_warn指令

語法:uninitialized_variable_warn on | off;
預設值:uninitialized_variable_warn on
作用域:http,server,location,if

控制是否輸出為初始化的變數到日誌

根據檔案型別expires

# Add expires header for static content
location ~*  \.(js|css|jpg|jpeg|gif|png|swf)$ {
if (-f $request_filename) {
   root /data/www/wwwroot/bbs;
   expires 1d;
   break;
}
}


# serve static files
location ~  ^/(images|JavaScript|js|css|flash|media|static)/ {
   root /data/www/wwwroot/down;
   expires 30d;
}

----------------------------------------Nginx多Server反向代理配置----------------------------------------
Nginx強大的正規表示式支援可以使server_name的配置變得很靈活。比如說想要做多使用者部落格,那麼每個使用者都會擁有自己的二級域名,這樣的話,可以靈活利用server_name配置也是很容易就實現的。

server_name的匹配順序
Nginx中的server_name指令主要用於配置基於名稱虛擬主機,server_name指令在接到請求後的匹配順序分別為:

1)準確的server_name匹配,例如:
server { 
listen 80; 
server_name ssdr.info www.ssdr.info; 
... 
} 

2)以*萬用字元開始的字串:
server { 
listen 80; 
server_name *.ssdr.info; 
... 
} 

3)以*萬用字元結束的字串:
server { 
listen 80; 
server_name www.*; 
... 
} 

4)匹配正規表示式:
server { 
listen 80; 
server_name ~^(?.+)\.howtocn\.org$; 
... 
} 

Nginx將按照上面1),2),3),4)的順序對server name進行匹配,只要有一項匹配以後就會停止搜尋,所以在使用這個指令的時候一定要分清楚它的匹配順序(類似於location指令)。
server_name指令一項很實用的功能便是可以在使用正規表示式的捕獲功能,這樣可以儘量精簡配置檔案,畢竟太長的配置檔案日常維護也很不方便。

下面是2個具體的應用:

1)在一個server塊中配置多個站點:

server 
{ 
listen 80; 
server_name ~^(www\.)?(.+)$; 
index index.php index.html; 
root /data/wwwsite/$2; 
} 

站點的主目錄應該類似於這樣的結構:
/data/wwwsite/ssdr.info 
/data/wwwsite/linuxtone.org 
/data/wwwsite/baidu.com 
/data/wwwsite/google.com 

這樣就可以只使用一個server塊來完成多個站點的配置。

2)在一個server塊中為一個站點配置多個二級域名 。
實際網站目錄結構中通常會為站點的二級域名獨立建立一個目錄,同樣可以使用正則的捕獲來實現在一個server塊中配置多個二級域名:

server 
{ 
listen 80; 
server_name ~^(.+)?\.howtocn\.org$; 
index index.html; 
if ($host = ssdr.info){ 
rewrite ^ http://www.ssdr.info permanent; 
} 
root /data/wwwsite/ssdr.info/$1/; 
} 

站點的目錄結構應該如下:
/data/wwwsite/ssdr.info/www/ 
/data/wwwsite/ssdr.info/nginx/ 

這樣訪問www.ssdr.info時root目錄為/data/wwwsite/ssdr.info/www/,nginx.ssdr.info時為/data/wwwsite/ssdr.info/nginx/,以此類推。
後面if語句的作用是將ssdr.info的方位重定向到www.ssdr.info,這樣既解決了網站的主目錄訪問,又可以增加seo中對www.ssdr.info的域名權重。

多個正規表示式
如果你在server_name中用了正則,而下面的location欄位又使用了正則匹配,這樣將無法使用$1,$2這樣的引用,解決方法是通過set指令將其賦值給一個命名的變數:

server 
{ 
listen 80; 
server_name ~^(.+)?\.howtocn\.org$; 
set $www_root $1; 
root /data/wwwsite/ssdr.info/$www_root/; 
location ~ .*\.php?$ { 
fastcgi_pass 127.0.0.1:9000; 
fastcgi_index index.php; 
fastcgi_param SCRIPT_FILENAME /data/wwwsite/ssdr.info/$fastcgi_script_name; 
include fastcgi_params; 
} 
} 

Nginx不同域名反向代理到另一臺伺服器 proxy_pass和$host
想讓一個VPS專門做另一個VPS的前端,後端VPS每新增一個域名,前端VPS就要同時新增一個域名來反向代理,作為前端的VPS如果一個一個的新增後端VPS的域名,那麼這個事情特別麻煩,能不能讓其自動反向代理後端VPS呢,用到proxy_pass和$host就可以輕鬆實現。
以下例子為了省事,以lnmp為安裝環境進行設定,修改前端VPS的nginx.conf檔案,修改成以下內容:

server { 
listen 80; 
server_name $host; 
location / { 
proxy_pass http://www.31.gd/; 
proxy_set_header Host $host; 
proxy_redirect off; 
proxy_set_header X-Real-IP $remote_addr; 
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 
proxy_connect_timeout 60; 
proxy_read_timeout 600; 
proxy_send_timeout 600; 
} 

接著修改其他部分

location /.(php|php5)?$ 
{ 
fastcgi_pass unix:/tmp/php-cgi.sock; 
fastcgi_index index.php; 
include fcgi.conf; 
} 
location /status { 
stub_status on; 
access_log off; 
} 
location /.(gif|jpg|jpeg|png|bmp|swf)$ 
{ 
expires 30d; 
} 
location /.(js|css)?$ 
{ 
expires 12h; 
} 

這樣就可以實現了前端VPS可以反向代理任意域名到後端VPS,只要將域名解析到前端VPS,後端VPS進行域名繫結,那麼就可以直接訪問到了。

一臺nginx帶多個域名多個tomcat情況的配置
多個域名,其中2個域名需支援泛域名解析:
1)www.abc.com
2)www.bcd.com
3)*.efg.com
4)*.hij.com
其中1),2),3)為一臺tomcat,4)為獨立tomcat。前端一臺nginx,通過配置多個虛擬主機來實現該部署。
進入/usr/local/nginx/conf/vhost目錄,所有虛擬主機的配置檔案都在該目錄下存放。

配置支援泛域名

# 
# A virtual host using mix of IP-, name-, and port-based configuration 
# 
server { 
listen       81; 
server_name  *.efg.com; 
location / { 
proxy_pass http://localhost:8080; 
proxy_set_header   Host    $host; 
proxy_set_header   X-Real-IP   $remote_addr; 
proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for; 
} 
} 
# 
# A virtual host using mix of IP-, name-, and port-based configuration 
# 
server { 
listen       81; 
server_name  *.hij.com; 
location / { 
proxy_pass http://localhost:8081; 
proxy_set_header   Host    $host; 
proxy_set_header   X-Real-IP   $remote_addr; 
proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for; 
} 
} 

Nginx 多域名配置
nginx繫結多個域名可又把多個域名規則寫一個配置檔案裡,也可又分別建立多個域名配置檔案,我一般為了管理方便,每個域名建一個檔案,有些同類域名也可又寫在一個總的配置檔案裡。

1)每個域名一個檔案的寫法
首先開啟nginx域名配置檔案存放目錄:/usr/local/nginx/conf/vhost ,如要繫結域名www.wangshibo.com 則在此目錄建一個檔案:www.wangshibo.com.conf 然後在此檔案中寫規則,如:
server 
{ 
listen       80; 
server_name www.wangshibo.com;             #繫結域名 
index index.htm index.html index.php;      #預設檔案 
root /home/www/wangshibo.com;               #網站根目錄 
include location.conf;                            #呼叫其他規則,也可去除 
} 

2)一個檔案多個域名的寫法
一個檔案新增多個域名的規則也是一樣,只要把上面單個域名重複寫下來就ok了,如:
server 
{ 
listen       80; 
server_name www.wangshibo.com;             #繫結域名 
index index.htm index.html index.php;      #預設檔案 
root /home/www/wangshibo.com;               #網站根目錄 
include location.conf;                            #呼叫其他規則,也可去除 
} 
server 
{ 
listen       80; 
server_name msn.wangshibo.com;             #繫結域名 
index index.htm index.html index.php;      #預設檔案 
root /home/www/msn.wangshibo.com;        #網站根目錄 
include location.conf;                            #呼叫其他規則,也可去除 
} 

3)不帶www的域名加301跳轉
如果不帶www的域名要加301跳轉,那也是和繫結域名一樣,先繫結不帶www的域名,只是不用寫網站目錄,而是進行301跳轉,如:
server 
{ 
listen 80; 
server_name wangshibo.com; 
rewrite ^/(.*) http://www.wangshibo.com/$1 permanent; 
} 

4)新增404網頁
新增404網頁,都可又直接在裡面新增,如:
server 
{ 
listen       80; 
server_name www.wangshibo.com;             #繫結域名 
index index.htm index.html index.php;      #預設檔案 
root /home/www/wangshibo.com;               #網站根目錄 
include location.conf;                            #呼叫其他規則,也可去除 
error_page 404  /404.html; 
} 
最後還有一個方法需要注意,可能有需要禁止IP直接訪問80埠或者禁止非本站的域名繫結我們的IP,這樣的話應該
如下處理,放到最前一個server上面即可:
server{ 
listen   80 default; 
server_name      _; 
return 403; 
} 

相關文章