Nginx反向代理和緩存服務功能說明和簡單實現 - 運維筆記

 

1、Nginx反向代理功能
Nginx不只能做爲Web Server,還具備反向代理、負載均衡和緩存的功能。下面就簡單說下這些功能:javascript

一、proxy模塊
nginx經過proxy模塊實現將客戶端的請求代理至上游服務器,此時nginx與上游服務器的鏈接是經過http協議進行的。nginx在實現反向代理功能時的最重要指令爲 proxy_pass,它可以並可以根據URI、客戶端參數或其它的處理邏輯將用戶請求調度至上游服務器上(upstream server)。php

1.1  proxy_pass URL;
設置後端服務器的協議和地址;這條指令能夠設置的協議是「http」或者「https」,而地址既可使用域名或者IP地址加端口(可選)的形式來定義:css

proxy_pass http://localhost:8000/uri/;

若是解析一個域名獲得多個地址,全部的地址都會以輪轉的方式被使用。固然也可使用服務器組來定義多個地址。html

若是proxy_pass沒有使用URI,傳送到後端服務器的請求URI通常是客戶端發起的原始URI,若是nginx改變了請求URI,則請求路徑與配置中的路徑的匹配部分將被替換爲指令中定義的URI:若nginx接到的請求的uri是/name/a.html前端

#傳送到後端服務器的URI是/remote/a.html
 location /name/ {
      proxy_pass http://172.16.60.20/remote/;
  }                   
========================================================

#傳送到後端服務器的URI是/name/a.html
location /name/ {
      proxy_pass http://172.16.60.20;
  } 

========================================================
#注意與上面用法的區別,這裏地址末尾帶有斜線,實際上被認爲定義了URI,該「/」會替換「/name/",傳送到後端服務器的URI是/a.html。
location /name/ {

      proxy_pass http://172.16.60.20/;

   }              

若是使用正則表達式定義路徑,則proxy_pass指令不該使用URI。例如:java

location ~ ^/mmb {
  proxy_pass http://www.kevin.com;
    }

 在須要代理的路徑中,使用rewrite指令改變了URI,那麼nginx將使用重寫後的URI處理請求,而忽略proxy_pass指令設置的URI。以下面所示的例子中,傳送給上游服務器的URI爲/index.php?page=<match>。node

location / {
    rewrite /(.*)$ /index.php?page=$1 break;
    proxy_pass http://localhost:8080;
    }

1.2  proxy模塊的其它指令
① proxy_connect_timeout time;
與後端服務器創建鏈接的超時時間。通常不可能大於75秒;ios

② proxy_cookie_domain off;
取消當前配置級別的全部proxy_cookie_domain指令;
若是配置,則格式爲:proxy_cookie_domain domain replacement(替代),即設置"Set-Cookie"響應頭中的domain屬性的替換文本,其值能夠爲一個字符串、正則表達式的模式或一個引用的變量;例如:nginx

  proxy_cookie_domain localhost example.org;

瀏覽器對 Cookie 有不少限制,若是 Cookie 的 Domain 部分與當前頁面的 Domain 不匹配就沒法寫入。因此若是請求 A 域名,服務器 proxy_pass 到 B 域名,而後 B 服務器輸出 Domian=B 的 Cookie,前端的頁面依然停留在 A 域名上,因而瀏覽器就沒法將 Cookie 寫入。web

不只是域名,瀏覽器對 Path 也有限制。咱們常常會 proxy_pass 到目標服務器的某個 Path 下,不把這個 Path 暴露給瀏覽器。這時候若是目標服務器的 Cookie 寫死了 Path 也會出現 Cookie 沒法寫入的問題。

③ proxy_cookie_path off;
格式"proxy_cookie_path path replacement;",即設置"Set-Cookie"響應頭中的path屬性的替換文本,其值能夠爲一個字符串、正則表達式的模式或一個引用的變量;例如:

proxy_cookie_path /two/ /;           

若「Set-Cookie」響應頭含有屬性「path=/two/some/uri/」,那麼該指令會將這個屬性改寫爲「path=/some/uri/」。

④ proxy_hide_header field;
nginx默認不會將"Date"、"Server"、"X-Pad",和"X-Accel-..."響應頭髮送給客戶端。該指令則能夠設置額外隱藏的響應頭,這些響應頭也不會發送給客戶端。相反的,若是但願容許傳遞某些響應頭給客戶端,可使用proxy_pass_header指令。

⑤ proxy_set_header field value;
從新定義或者添加發日後端服務器的請求頭。value能夠包含文本、變量或者它們的組合。例如:

proxy_set_header X-Real-IP $remote_addr;   #給請求頭中添加客戶端IP
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;   

默認狀況下,只有兩個請求頭會被從新定義:
proxy_set_header Host $proxy_host;
proxy_set_header Connection close;

若是某個請求頭的值爲空,那麼這個請求頭將不會傳送給後端服務器:
proxy_set_header Accept-Encoding "";

⑥ proxy_pass_request_headers on|off;
是否將http首部發往上游服務器

⑦ proxy_pass_request_body on|off;
是否將http請求報文的包體部分發往上游服務器

⑧ proxy_redirect [default|off|redirect replacement];
修改上游服務器傳來的響應頭中的"Location"和"Refresh"字段。例如:

proxy_redirect http://localhost:8000/two/ http://frontend/one/;       

replacement字符串能夠省略服務器名:
proxy_redirect http://localhost:8000/two/ /;
此時將使用代理服務器的主域名和端口號來替換。若是端口是80,能夠不加。

⑨ proxy_send_timeout time;
在鏈接斷開以前兩次發送至upstream server的寫操做的最大間隔時長;

⑩ proxy_read_timeout time;
在鏈接斷開以前兩次從接收upstream server接收讀操做的最大間隔時長;

1.3  proxy模塊的內置變量
① $proxy_host:
後端服務器的主機名和端口;

② $proxy_port:
後端服務器的端口;

③ $proxy_add_x_forwarded_for
將$remote_addr變量值添加在客戶端「X-Forwarded-For」請求頭的後面,並以逗號分隔。 若是客戶端請求未攜帶「X-Forwarded-For」請求頭,$proxy_add_x_forwarded_for變量值將與$remote_addr變量相同

二、upstream模塊
若是有多個上游服務器,咱們能夠把它們放到一個組中,而且給它們賦予不一樣的權重和類型,進行負載均衡等,這些功能是由upstream模塊實現的。

2.1  配置語法:

upstream name {
      server address [parameters];
      ...
  }

示例:
upstream web {
    server web1.kevin.com       weight=5;
    server web2.kevin.com:8080;
    server unix:/tmp/web3;
    server backup1.kevin.com:8080   backup;
  }

    server {
    location / {
    proxy_pass http://web;
     }
    }

2.2  uptream使用注意:
① 只能用於http上下文

② 各server只能直接使用IP或主機名,不要加協議

2.3  默認狀況下,nginx按加權輪轉的方式將請求代理到各上游服務器。與上游服務器通訊的時候,若是出現錯誤,請求會被傳給下一個服務器,直到全部可用的服務器都被嘗試過。若是全部服務器都返回失敗,客戶端將會獲得最後通訊的那個服務器的(失敗)響應結果。

2.4  地址能夠是域名或者IP地址,端口是可選的(默認是80),或者是指定「unix:」前綴的UNIX域套接字的路徑。若是一個域名解析到多個IP,本質上是定義了多個server。

2.5  server後可定義的參數:
① weight=number
設定服務器的權重,默認是1。

② max_fails=number
設定Nginx與服務器通訊的嘗試失敗的次數。在fail_timeout參數定義的時間段內,若是失敗的次數達到此值,Nginx就認爲服務器不可用。在下一個fail_timeout時間段,服務器不會再被嘗試。失敗的嘗試次數默認是1。設爲0就會中止統計嘗試次數,認爲服務器是一直可用的。

③ fail_timeout=time
默認是10秒,設定統計失敗嘗試次數的時間段。在這段時間中,服務器失敗次數達到指定的嘗試次數,服務器就被認爲不可用。服務器被認爲不可用的時間段。

④ backup
標記爲備用服務器。當主服務器不可用之後,請求會被傳給這些服務器。

⑤ down
標記服務器永久不可用,能夠跟ip_hash指令一塊兒使用

2.6  upstream模塊的其它負載均衡算法(用於upstream上下文):
① ip_hash;
做用同lvs中的sh調度算法,未來自於同一個客戶端的請求始終調度至同一臺後端服務器(除了當服務器不可用的時候)

② least_conn;
將請求發送到活動鏈接數最少的那臺服務器。若是這樣的服務器有多臺,就嘗試按加權輪循來調度

③ sticky cookie name [expires=time] [domain=domain] [httponly] [secure] [path=path];
session綁定,未來自於同一個客戶端的請求始終調度至同一臺後端服務器,從而實現客戶端與後端服務器的session保持。

ip_hash指令沒法實現對內網NAT用戶的均衡,而sticky指令能夠作到;

◆     sticky工做原理
1. 瀏覽器首次發起請求,請求頭未帶cookie。nginx接收請求,發現請求頭沒有cookie,則以輪詢方式將請求代理給後端服務器。
2. 後端服務器處理完請求,將響應頭和內容返回給nginx。
3. nginx生成cookie,返回給客戶端瀏覽器。cookie的值與後端服務器對應,多是明文,也多是md五、sha1等Hash值。
4. 瀏覽器接收請求,並建立cookie。
5. 瀏覽器再次發送請求時,帶上cookie。
6. nginx接收到cookie,直接轉給對應的後端服務器

參數說明:
domain:cookie做用的域名
path:cookie做用的路徑
expires:cookie的過時時長

示例以下:

upstream web {
      server web1.kevin.com;
      server web2.kevin.com;
      sticky cookie srv_id expires=1h domain=.kevin.com path=/;
      }

2.7  health_check [interval=time] [fails=number] [passes=number] [uri=uri] [match=name];
對上游服務器組進行健康狀態檢測,用於location中;

參數說明:
interval=time       #檢測的間隔時長,默認爲5秒
fails=number       #連續檢測失敗多少次即認爲上游服務器不可用,默認爲1次
passes=number  #上游服務器從不可用到可用狀態時須要連續檢測的次數,默認爲1次
uri=uri                 #定義用於健康檢測的URI,默認爲「/」,即默認檢測目標服務器的主頁
match=name      #指定一段配置來看成檢測條件,默認當響應碼爲2XX或3XX時認爲上游服務器是可用的

示例以下:

http {
      server {
        ...
        location / {
            proxy_pass http://backend;
            health_check uri=/.health.html match=welcome;
             }
      }

   match welcome {      #match配置段要位於http上下文
      status 200;
      header Content-Type = text/html;
      body ~ "Welcome to nginx!";
      }
}

三、fastcgi模塊
nginx可以經過fastcgi模塊實現將客戶端的動態文件請求代理至fastcgi server,此時nginx與fastcgi server的通訊是經過fastcgi協議進行的

3.1   fastcgi模塊的經常使用指令
①fastcgi_pass address;
指定fastcgi server的地址和端口,也支持使用unix sock;例如:

fastcgi_pass localhost:9000;
fastcgi_pass 192.168.30.20:9000;
fastcgi_pass unix:/tmp/fastcgi.socket;

②fastcgi_bind address | off;
指定聯繫fpm服務器時使用的地址;

③fastcgi_param parameter value [if_not_empty];
定義傳遞給fastcgi server的參數;參數值能夠是文本、變量或它們的組合,if_not_empty表示不爲空時才傳遞。例如:

fastcgi_param SCRIPT_FILENAME /web/scripts$fastcgi_script_name;

④fastcgi_index name;
默認主頁名;就是當URI中的文件名缺省時,使用此文件名

⑤fastcgi_connect_timeout time;
鏈接fastcgi服務器的超時時長;

⑥fastcgi_send_timeout time;
向fastcgi服務傳輸數據的超時時長;

3.2  一般建議nginx和fastcgi server(如php-fpm)部署在同一臺服務器上,由於兩者若是經過網絡通訊的話會形成額外的性能開銷。

3.3   配置示例

  location ~ \.php$ {
          fastcgi_pass 127.0.0.1:9001;
          fastcgi_index index.php;
          fastcgi_param SCRIPT_FILENAME /web/scripts$fastcgi_script_name;
          include fastcgi_params;
       }

說明:
①參數SCRIPT_FILENAME保存是的腳本文件的絕對路徑;例如,若請求的URI是/test/status.php,那麼向fastcgi server傳遞的腳本文件路徑就是/web/scripts/test/status.php
②nginx有兩個文件fastcgi_params和fastcgi.conf,它們存放着nginx向fastcgi server傳遞的參數,兩者惟一的區別是後者比前者多了一行 SCRIPT_FILENAME 的定義:
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

3.4  經過nginx查看後端php-fpm的運行狀態

# vim /etc/php-fpm.d/www.conf(若php-fpm是編譯安裝,則爲主配置文件)
pm.status_path = fpm_status
ping.path = fpm_ping

# vim /etc/nginx/nginx.conf           
location ~* /(fpm_status|fpm_ping) {
    root           /www/a.com;
    fastcgi_pass   127.0.0.1:9000;
    fastcgi_param  SCRIPT_FILENAME  $fastcgi_script_name;
    include      fastcgi_params;

  }        

2、nginx的緩存功能
nginx作爲反向代理時,可以未來自上游服務器的響應緩存至本地,並在後續的客戶端請求一樣內容時直接從本地構造響應報文。nginx使用磁盤作緩存;

緩存將聽從上游服務器的響應報文首部中關於緩存的設定,如 "Expires"、"Cache-Control: no-cache"、 "Cache-Control: max-age=XXX"、"private"和"no-store" 等,但nginx在緩存時不會考慮響應報文的"Vary"首部。爲了確保私有信息不被緩存,全部關於用戶的私有信息能夠在上游服務器上經過"no-cache" or "max-age=0"來實現,也可在nginx設定proxy_cache_key必須包含用戶特有數據如$cookie_xxx的方式實現,但最後這種方式在公共緩存上使用可能會有風險。所以,在響應報文中含有如下首部或指定標誌的報文將不會被緩存。

Set-Cookie
Cache-Control containing "no-cache", "no-store", "private", or a "max-age" with a non-numeric or 0 value

Expires with a time in the past
X-Accel-Expires: 0

與緩存有關的指令:
① proxy_cache zone | off;
定義一個用於緩存的共享內存區域,其可被多個地方調用;

② proxy_cache_key string;
設定在存儲及檢索緩存時用於「鍵」的字符串,可使用變量爲$uri其值,但使用不當時有可能會爲同一個內容緩存屢次;另外,將用戶私有信息用於鍵能夠避免將用戶的私有信息返回給其它用戶;

例如:proxy_cache_key "$host$request_uri;

③ proxy_cache_lock on | off;
啓用此項,可在緩存未命令中阻止多個相同的請求同時發往upstream,其生效範圍爲worker級別;

④ proxy_cache_lock_timeout time;
proxy_cache_lock功能的鎖定時長;

⑤ proxy_cache_min_uses number;
某響應報文被緩存以前至少應該被請求的次數;

⑥ proxy_cache_path path [levels=levels] keys_zone=name:size [inactive=time] [max_size=size] [loader_files=number] [loader_sleep=time] [loader_threshold=time] ;
定義一個用記保存緩存響應報文的目錄,及一個保存緩存對象的鍵及響應元數據的共享內存區域(keys_zone=name:size),其可選參數有:
levels:   每級子目錄名稱的長度,有效值爲1或2,每級之間使用冒號分隔,最多爲3級;
inactive:非活動緩存項從緩存中剔除以前的最大緩存時長;
max_size:   緩存空間大小的上限,當須要緩存的對象超出此空間限定時,緩存管理器將基於LRU算法對其進行清理;
loader_files:緩存加載器的每次工做過程最多爲多少個文件加載元數據;
loader_sleep:  緩存加載器的每次迭代工做以後的睡眠時長;
loader_threashold:  緩存加載器的最大睡眠時長;

示例:
proxy_cache_path /data/nginx/cache/one levels=1 keys_zone=one:10m;
proxy_cache_path /data/nginx/cache/two levels=2:2 keys_zone=two:100m;          

⑦ proxy_cache_use_stale error | timeout | invalid_header | updating | http_500 | http_502 | http_503 |http_504 | http_403 | http_404 | off ...;
在沒法聯繫到upstream服務器時的哪一種情形下(如error、timeout或http_500等)讓nginx使用本地緩存的過時的緩存對象直接響應客戶端請求;

⑧ proxy_cache_valid [code ...] time;
用於爲不一樣的響應設定不一樣時長的有效緩存時長

例如:
proxy_cache_valid  200 302  10m;

⑨ proxy_cache_methods GET | HEAD | POST ...;
爲哪些請求方法啓用緩存功能;

⑩ proxy_cache_bypass string;
設定在哪一種情形下,nginx將不從緩存中取數據。

proxy_cache_bypass $cookie_nocache $arg_nocache $arg_comment;
proxy_cache_bypass $http_pragma $http_authorization;

nginx也可將後端fastcgi server的響應結果緩存:

fastcgi_cache
fastcgi_cache_path
fastcgi_cache_valid
...

3、Nginx反向代理簡單實現
負載機:A機器:103.110.186.8/192.168.1.8
後端機器1:B機器:192.168.1.102
後端機器2:C機器:192.168.1.103

需求:
->  訪問A機器的8080端口,反向代理到B機器的8080端口;
->  訪問A機器的8088端口,反向代理到C機器的8088端口;
->  訪問http://103.110.86.8:8090/ios,反向代理到B機器http://192.168.1.102:8090/ios/
->  訪問A機器的80端口,負載均衡到後端的兩臺機器B和C的80端口

操做記錄以下:

=========================================================================================
負載機:A機器上的操做記錄:

1)編譯安裝nginx
[root@opd ~]# yum install -y pcre* openssl* gcc gcc+
[root@opd ~]# cd /opt/src
[root@src ~]# wget http://nginx.org/download/nginx-1.8.0.tar.gz
[root@src ~]# tar -zxvf nginx-1.8.0.tar.gz
[root@src ~]# cd nginx-1.8.0
#添加www用戶,其中-M參數表示不添加用戶家目錄,-s參數表示指定shell類型

[root@nginx-1.8.0 ~]#useradd www -M -s /sbin/nologin
[root@nginx-1.8.0 ~]#vim auto/cc/gcc
#將這句註釋掉 取消Debug編譯模式 大概在179行
#CFLAGS="$CFLAGS -g"

#咱們再配置下nginx編譯參數
[root@nginx-1.8.0 ~]# ./configure --prefix=/opt/nginx --user=www --group=www --with-http_stub_status_module --with-http_ssl_module
[root@nginx-1.8.0 ~]#make
[root@nginx-1.8.0 ~]#make install clean

2)配置nginx
[root@nginx-1.8.0 ~]# cd /opt/nginx/conf
[root@nginx-1.8.0 conf]# vim nginx.conf         //這個能夠做爲nginx安裝後的配置規範
http {
    include       mime.types;
    default_type  application/octet-stream;
    charset utf-8;
  
    log_format  main  '$http_x_forwarded_for $remote_addr $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_cookie" $host $request_time';
    sendfile       on;
    tcp_nopush     on;
    tcp_nodelay    on;
    keepalive_timeout  65;
  
  
    fastcgi_connect_timeout 3000;
    fastcgi_send_timeout 3000;
    fastcgi_read_timeout 3000;
    fastcgi_buffer_size 256k;
    fastcgi_buffers 8 256k;
    fastcgi_busy_buffers_size 256k;
    fastcgi_temp_file_write_size 256k;
    fastcgi_intercept_errors on;
   
      
    client_header_timeout 600s;
    client_body_timeout 600s;
   
    client_max_body_size 100m;            
    client_body_buffer_size 256k;          
   
    gzip  on;
    gzip_min_length  1k;
    gzip_buffers     4 16k;
    gzip_http_version 1.1;
    gzip_comp_level 9;
    gzip_types       text/plain application/x-javascript text/css application/xml text/javascript application/x-httpd-php;
    gzip_vary on;
   
  
    include vhosts/*.conf;
}

[root@nginx-1.8.0 conf]# ulimit -n 65535
[root@nginx-1.8.0 conf]# mkdir vhosts
[root@nginx-1.8.0 conf]# cd vhosts

配置反向代理和負載均衡
[root@nginx-1.8.0 vhosts]# vim 8080.conf
server {
    listen 8080;
    server_name localhost;
    index index.html index.php index.htm;
    root /var/www/html;
  
    access_log  /usr/local/nginx/logs/8080-access.log main;
    error_log  /usr/local/nginx/logs/8080-error.log;
 
location / {
    proxy_pass http://192.168.1.102:8080;
    proxy_redirect off ;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header REMOTE-HOST $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_connect_timeout 300;             #跟後端服務器鏈接超時時間,發起握手等候響應時間
    proxy_send_timeout 300;                #後端服務器回傳時間,就是在規定時間內後端服務器必須傳完全部數據
    proxy_read_timeout 600;                #鏈接成功後等待後端服務器的響應時間,已經進入後端的排隊之中等候處理
    proxy_buffer_size 256k;                #代理請求緩衝區,會保存用戶的頭信息以供nginx進行處理
    proxy_buffers 4 256k;                  #同上,告訴nginx保存單個用幾個buffer最大用多少空間
    proxy_busy_buffers_size 256k;          #若是系統很忙時候能夠申請最大的proxy_buffers
    proxy_temp_file_write_size 256k;       #proxy緩存臨時文件的大小
    proxy_next_upstream error timeout invalid_header http_500 http_503 http_404;
    proxy_max_temp_file_size 128m;
}
}

[root@nginx-1.8.0 vhosts]# cat 8088.conf
server {
    listen 8088;
    server_name localhost;
    index index.html index.php index.htm;
    root /var/www/html;
  
    access_log  /usr/local/nginx/logs/8088-access.log main;
    error_log  /usr/local/nginx/logs/8088-error.log;
 
location / {
    proxy_pass http://192.168.1.103:8088;
    proxy_redirect off ;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header REMOTE-HOST $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_connect_timeout 300;            
    proxy_send_timeout 300;              
    proxy_read_timeout 600;              
    proxy_buffer_size 256k;               
    proxy_buffers 4 256k;                 
    proxy_busy_buffers_size 256k;        
    proxy_temp_file_write_size 256k;      
    proxy_next_upstream error timeout invalid_header http_500 http_503 http_404;
    proxy_max_temp_file_size 128m;
}
}


》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》
下面這個匹配path的代理設置須要注意幾點:
首先必定要保證目標B機器,也就是192.168.1.102的8090端口站點目錄下有這個匹配path的目錄ios存在!!
也就是要保證A機器本機能順利訪問到目標B機器的8090端口的ios路徑,即:
[root@nginx-1.8.0 vhosts]# curl http://192.168.1.102:8090/ios/ #必定要保證這個能從A機器訪問成功!

下面幾種配置都是能夠的:

第一種:
[root@nginx-1.8.0 vhosts]# cat 8090.conf
server {
    listen 8090;
    server_name localhost;
    index index.html index.php index.htm;
    root /var/www/html;
  
    access_log  /usr/local/nginx/logs/8090-access.log main;
    error_log  /usr/local/nginx/logs/8090-error.log;
 
    location /ios/ {                            #這種狀況,這裏必定要匹配的是/ios/,不能是/ios
    proxy_pass http://192.168.1.102:8090;       #必定要保證192.168.1.102機器8090端口站點目錄下有ios目錄!不然訪問會報錯404!
    proxy_redirect off ;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header REMOTE-HOST $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_connect_timeout 300;            
    proxy_send_timeout 300;              
    proxy_read_timeout 600;              
    proxy_buffer_size 256k;               
    proxy_buffers 4 256k;                 
    proxy_busy_buffers_size 256k;        
    proxy_temp_file_write_size 256k;      
    proxy_next_upstream error timeout invalid_header http_500 http_503 http_404;
    proxy_max_temp_file_size 128m;
}
}

第二種:
[root@nginx-1.8.0 vhosts]# cat 8090.conf
server {
    listen 8090;
    server_name localhost;
    index index.html index.php index.htm;
    root /var/www/html;
  
    access_log  /usr/local/nginx/logs/8090-access.log main;
    error_log  /usr/local/nginx/logs/8090-error.log;
 
    location /ios/ {
    proxy_pass http://192.168.1.102:8090/ios/;
    proxy_redirect off ;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header REMOTE-HOST $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_connect_timeout 300;            
    proxy_send_timeout 300;              
    proxy_read_timeout 600;              
    proxy_buffer_size 256k;               
    proxy_buffers 4 256k;                 
    proxy_busy_buffers_size 256k;        
    proxy_temp_file_write_size 256k;      
    proxy_next_upstream error timeout invalid_header http_500 http_503 http_404;
    proxy_max_temp_file_size 128m;
}
}

第三種:
[root@nginx-1.8.0 vhosts]# cat 8090.conf
server {
    listen 8090;
    server_name localhost;
    index index.html index.php index.htm;
    root /var/www/html;
  
    access_log  /usr/local/nginx/logs/8090-access.log main;
    error_log  /usr/local/nginx/logs/8090-error.log;
 
    location /ios {
    proxy_pass http://192.168.1.102:8090/ios/;         這種狀況,這裏必定要匹配的是/ios/,不能是/ios
    proxy_redirect off ;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header REMOTE-HOST $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_connect_timeout 300;            
    proxy_send_timeout 300;              
    proxy_read_timeout 600;              
    proxy_buffer_size 256k;               
    proxy_buffers 4 256k;                 
    proxy_busy_buffers_size 256k;        
    proxy_temp_file_write_size 256k;      
    proxy_next_upstream error timeout invalid_header http_500 http_503 http_404;
    proxy_max_temp_file_size 128m;
}
}

以上三種配置方法都保證了訪問http://103.110.86.8:8090/ios會自動變爲http://103.10.86.8:8090/ios/,並代理到http://192.168.1.102:8090/ios/的結果

[root@nginx-1.8.0 vhosts]# cat LB.conf
upstream lb {
    server 192.168.1.102:80 max_fails=3 fail_timeout=30s;   #max_fails = 3 爲容許失敗的次數,默認值爲1
    server 192.168.1.103:80 max_fails=3 fail_timeout=30s;   #fail_timeout = 30s 當max_fails次失敗後,暫停將請求分發到該後端服務器的時間
}
 
server {
    listen 80;
    server_name localhost;
    index index.html index.php index.htm;
    root /var/www/html;
  
    access_log  /usr/local/nginx/logs/80-access.log main;
    error_log  /usr/local/nginx/logs/80-error.log;
 
    location / {
    proxy_pass http://lb;
    proxy_redirect off ;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header REMOTE-HOST $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_connect_timeout 300;            
    proxy_send_timeout 300;              
    proxy_read_timeout 600;              
    proxy_buffer_size 256k;               
    proxy_buffers 4 256k;                 
    proxy_busy_buffers_size 256k;        
    proxy_temp_file_write_size 256k;      
    proxy_next_upstream error timeout invalid_header http_500 http_503 http_404;
    proxy_max_temp_file_size 128m;
}
}

啓動nginx
[root@nginx-1.8.0 vhosts]# /opt/nginx/sbin/nginx -t 
nginx: the configuration file /opt/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /opt/nginx/conf/nginx.conf test is successful

[root@host-192-168-1-102 vhosts]# /opt/nginx/sbin/nginx 

=====================================================================================
後端機:B機器上的操做記錄:

1)編譯安裝nginx
[root@B ~]# yum install -y pcre* openssl* gcc gcc+
[root@B ~]# cd /opt/src
[root@B ~]# wget http://nginx.org/download/nginx-1.8.0.tar.gz
[root@B ~]# tar -zxvf nginx-1.8.0.tar.gz
[root@B ~]# cd nginx-1.8.0
#添加www用戶,其中-M參數表示不添加用戶家目錄,-s參數表示指定shell類型

[root@nginx-1.8.0 ~]#useradd www -M -s /sbin/nologin
[root@nginx-1.8.0 ~]##vim auto/cc/gcc
#將這句註釋掉 取消Debug編譯模式 大概在179行
#CFLAGS="$CFLAGS -g"

#咱們再配置下nginx編譯參數
[root@nginx-1.8.0 ~]# ./configure --prefix=/opt/nginx --user=www --group=www --with-http_stub_status_module --with-http_ssl_module
[root@nginx-1.8.0 ~]#make
[root@nginx-1.8.0 ~]#make install clean

2)配置nginx
[root@nginx-1.8.0 ~]# cd /opt/nginx/conf
注意,把默認的nginx.conf文件中的server區域配置註釋掉,設置vhosts虛擬主機的配置,以下:
[root@nginx-1.8.0 conf]# vim nginx.conf
user  www;
worker_processes  8;
   
events {
    worker_connections  65535;
}
   
http {
    include       mime.types;
    default_type  application/octet-stream;
    charset utf-8;
  
    log_format  main  '$http_x_forwarded_for $remote_addr $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_cookie" $host $request_time';
    sendfile       on;
    tcp_nopush     on;
    tcp_nodelay    on;
    keepalive_timeout  65;
  
  
    fastcgi_connect_timeout 3000;
    fastcgi_send_timeout 3000;
    fastcgi_read_timeout 3000;
    fastcgi_buffer_size 256k;
    fastcgi_buffers 8 256k;
    fastcgi_busy_buffers_size 256k;
    fastcgi_temp_file_write_size 256k;
    fastcgi_intercept_errors on;
   
      
    client_header_timeout 600s;
    client_body_timeout 600s;
   
    client_max_body_size 100m;            
    client_body_buffer_size 256k;          
   
    gzip  on;
    gzip_min_length  1k;
    gzip_buffers     4 16k;
    gzip_http_version 1.1;
    gzip_comp_level 9;
    gzip_types       text/plain application/x-javascript text/css application/xml text/javascript application/x-httpd-php;
    gzip_vary on;
   
  
    include vhosts/*.conf;
}

[root@nginx-1.8.0 conf]# ulimit -n 65535
[root@nginx-1.8.0 conf]# mkdir vhosts
[root@nginx-1.8.0 conf]# cd vhosts

[root@nginx-1.8.0 conf]# vim 8080.conf
server {
    listen 8080;
    server_name localhost;
    index index.html index.php index.htm;
  
    access_log  /usr/local/nginx/logs/8080-access.log main;
    error_log  /usr/local/nginx/logs/8080-error.log;
 
location ~ / {
    root /var/www/html/8080;
    index index.html index.php index.htm;
}
}

[root@nginx-1.8.0 conf]# vim 8090.conf
server {
    listen 8090;
    server_name localhost;
    index index.html index.php index.htm;
  
    access_log  /usr/local/nginx/logs/8090-access.log main;
    error_log  /usr/local/nginx/logs/8090-error.log;
 
location ~ / {
    root /var/www/html/8090;        #針對上面匹配ios的path代理,要保證站點目錄/var/www/html/8080下有ios目錄存在
    index index.html index.php index.htm;
}
}

[root@nginx-1.8.0 conf]# vim 80.conf
server {
   listen 80;
   server_name localhost;
   index index.html index.php index.htm;
  
   access_log  /usr/local/nginx/logs/80-access.log main;
   error_log  /usr/local/nginx/logs/80-error.log;
 
location ~ / {
   root /var/www/html;
   index index.html index.php index.htm;
}
}

啓動nginx
[root@nginx-1.8.0 vhosts]# /opt/nginx/sbin/nginx -t 
nginx: the configuration file /opt/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /opt/nginx/conf/nginx.conf test is successful

[root@host-192-168-1-102 vhosts]# /opt/nginx/sbin/nginx 

==========================================================================================
後端機:C機器上的操做記錄

1)編譯安裝nginx
[root@C ~]# yum install -y pcre* openssl* gcc gcc+
[root@C ~]# cd /opt/src
[root@C ~]# wget http://nginx.org/download/nginx-1.8.0.tar.gz
[root@C ~]# tar -zxvf nginx-1.8.0.tar.gz
[root@C ~]# cd nginx-1.8.0
#添加www用戶,其中-M參數表示不添加用戶家目錄,-s參數表示指定shell類型

[root@nginx-1.8.0 ~]#useradd www -M -s /sbin/nologin
[root@nginx-1.8.0 ~]##vim auto/cc/gcc
#將這句註釋掉 取消Debug編譯模式 大概在179行
#CFLAGS="$CFLAGS -g"

#咱們再配置下nginx編譯參數
[root@nginx-1.8.0 ~]# ./configure --prefix=/opt/nginx --user=www --group=www --with-http_stub_status_module --with-http_ssl_module
[root@nginx-1.8.0 ~]#make
[root@nginx-1.8.0 ~]#make install clean

2)配置nginx
[root@nginx-1.8.0 ~]# cd /opt/nginx/conf
注意,把默認的nginx.conf文件中的server區域配置註釋掉,設置vhosts虛擬主機的配置,以下:
[root@nginx-1.8.0 conf]# vim nginx.conf

user  www;
worker_processes  8;
   
events {
    worker_connections  65535;
}
   
http {
    include       mime.types;
    default_type  application/octet-stream;
    charset utf-8;
  
    log_format  main  '$http_x_forwarded_for $remote_addr $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_cookie" $host $request_time';
    sendfile       on;
    tcp_nopush     on;
    tcp_nodelay    on;
    keepalive_timeout  65;
  
  
    fastcgi_connect_timeout 3000;
    fastcgi_send_timeout 3000;
    fastcgi_read_timeout 3000;
    fastcgi_buffer_size 256k;
    fastcgi_buffers 8 256k;
    fastcgi_busy_buffers_size 256k;
    fastcgi_temp_file_write_size 256k;
    fastcgi_intercept_errors on;
   
      
    client_header_timeout 600s;
    client_body_timeout 600s;
   
    client_max_body_size 100m;            
    client_body_buffer_size 256k;          
   
    gzip  on;
    gzip_min_length  1k;
    gzip_buffers     4 16k;
    gzip_http_version 1.1;
    gzip_comp_level 9;
    gzip_types       text/plain application/x-javascript text/css application/xml text/javascript application/x-httpd-php;
    gzip_vary on;
   
  
    include vhosts/*.conf;
}

[root@nginx-1.8.0 conf]# vim 80.conf
server {
    listen 80;
    server_name localhost;
    index index.html index.php index.htm;
  
    access_log  /usr/local/nginx/logs/80-access.log main;
    error_log  /usr/local/nginx/logs/80-error.log;
 
location ~ / {
    root /var/www/html/;
    index index.html index.php index.htm;
}
}

啓動nginx
[root@nginx-1.8.0 vhosts]# /opt/nginx/sbin/nginx -t 
nginx: the configuration file /opt/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /opt/nginx/conf/nginx.conf test is successful

[root@host-192-168-1-102 vhosts]# /opt/nginx/sbin/nginx 


到此,上面需求中的nginx反向代理和負載均衡就已經配置完成了!
訪問http://103.110.86.8:8080的結果顯示的就是B機器,即http://192.168.1.102:8080的結果
訪問http://103.110.86.8:8088的結果顯示的就是C機器,即http://192.168.1.108:8088的結果
訪問http://103.110.86.8:8090/ios的結果顯示的就是B機器,即http://192.168.1.102:8090/ios/的結果

訪問http://103.110.86.8的請求就會被負載給到後端兩臺機器http://192.168.1.102和http://192.168.1.103

能夠在103.110.86.8本機可使用curl和telnet測試到目標機器是否通順~
[root@nginx-1.8.0 vhosts]# curl http://192.168.1.102:8080
[root@nginx-1.8.0 vhosts]# telnet 192.168.1.102 8080

                                                                                                                                                      
說明一下:上面的nginx反向代理的需求,除了nginx反代配置以外,也可使用iptables的nat轉發實現。
好比:訪問A機器的8080端口,反向代理到B機器的80端口;iptables的nat轉發規則設置以下:

[root@opd ~]# iptables -t nat -A PREROUTING -p tcp -m tcp --dport 8080 -j DNAT --to-destination 192.168.1.102:80 
[root@opd ~]# iptables -t nat -A POSTROUTING -d 192.168.1.102 -p tcp -m tcp --sport 80 -j SNAT --to-source 192.168.1.8
[root@opd ~]# iptables -t filter -A INPUT -p tcp -m state --state NEW -m tcp --dport 8080 -j ACCEPT

[root@opd ~]# service iptables save

**************************************
須要注意的是:
要打開A機器的ip轉發功能:
[root@opd ~]# echo 1 > /proc/sys/net/ipv4/ip_forward
而後後端機器B的route路由最好也設置成192.168.1.8
**************************************

這樣,訪問http://103.110.86.8:8080的結果就是http://192.168.1.102的結果

                                                                                                                                                   
nginx反向代理一例:訪問 http://testwx3.wangshibo.com/apiwx3   反向代理到    https://testwww.wangshibo.com

[root@dev-new-test vhosts]# cat testwx3.wangshibo.com.conf
server {
        listen       80;
 
        server_name  testwx3.wangshibo.com;
        root  /Data/app/xqsj_wx3/dist;
        index index.html;
 
    location /apiwx3/ {
        proxy_pass https://testwww.wangshibo.com/;
    }

如上配置後:
訪問 http://testwx3.wangshibo.com/apiwx3  自動跳轉到  http://testwx3.wangshibo.com/apiwx3/
訪問 http://testwx3.wangshibo.com/apiwx3/$1 的內容和 https://testwww.wangshibo.com/$1 內容一致
好比:
訪問 http://testwx3.wangshibo.com/apiwx3/xqsj.php?r=HouseGroup/create  顯示的內容既是  http://testwww.wangshibo.com/xqsj.php?r=HouseGroup/create 的內容

若是將上面的代理配置改成:

location /apiwx3 {
    proxy_pass https://testwww.wangshibo.com;
}
 
或者
    location /apiwx3/ {
    proxy_pass https://testwww.wangshibo.com/;
}

那麼只能實現:訪問 http://testwx3.wangshibo.com/apiwx3 的結果和 https://testwww.wangshibo.com 一致不能實現:訪問http://testwx3.wangshibo.com/apiwx3/$1的內容和https://testwww.wangshibo.com/$1內容一致

相關文章
相關標籤/搜索