nginx的反向代理proxy_pass指令

龍恩0707發表於2018-10-31

1. 首先什麼是代理伺服器?
客戶機傳送請求時,不會直接傳送到目的主機,而是先被代理伺服器收到,代理伺服器收到客服機的請求後,再向目的機發出,目的機就會返回資料給客戶機,在返回給客戶機之前,會被代理伺服器先收到,會存放在代理伺服器的硬碟中。然後代理伺服器會再向客戶機發出,最後客戶機就會收到目的機返回的資料。

2. 代理伺服器的作用有哪些?

1) 可以提高訪問速度
因為目標主機返回的資料會存放在代理伺服器的硬碟中,因此下一次客戶機再次訪問相同的站點資料的時候,會直接從代理伺服器的硬碟中讀取,因此響應速度會更快。

2)防火牆的作用
由於所有的客戶機請求都必須通過代理伺服器訪問遠端站點,因此可在代理伺服器上設限,過濾一些不安全的資訊。

3. 理解什麼是反向代理?

反向代理是指以代理伺服器接收Internet上的連結請求,然後將請求轉發給內部網路上的伺服器,並將從伺服器上得到的結果返回給Internet上請求連線的客戶端。

什麼意思呢?上面的解釋可能有點不好理解,那麼下面我們先來打個比方,比如我的內部伺服器是放在212環境上,那麼開發的介面如下這樣的:
http://192.168.1.212:8136/xxxx 然後埠號是8136,然後直接訪問該介面會返回對應的資料,但是介面一般都是域名訪問的,因此我們需要在nginx上配置一個域名,假如為 xy.xxx.com, 然後當我們在聯調介面的時候,我們使用 http://xy.xxx.com/xxxx 這樣的介面時,它會反向代理到 http://192.168.1.212:8136/xxxx 上來,這樣它會返回內部伺服器的資料給客戶端,客戶端就拿到對應的資料顯示出來了。

3.1 理解proxy_pass指令
該指令是用來設定代理伺服器的地址,可以是主機名稱,IP地址加埠號等形式。基本語法如下所示:

proxy_pass: URL;

因此我們經常會看到如下nginx上的配置:如下程式碼:

server {
  listen 80;
  server_name xy.xxx.com; // 介面的域名
  access_log  /data/www/logs/nginx/access.log main;
  add_header Access-Control-Allow-Origin http://xy.xxx.com; // 允許的域名跨域
  add_header Access-Control-Allow-Credentials true;
  include nginx_xxx.conf;
  location / {
    proxy_pass http://192.168.1.212:8136;
    include nginx_proxy.conf;
  }
  error_page   500 502 503 504  /502.html;
  location = /50x.html {
    root   html;
  }
}

如上程式碼的含義是:監聽80埠號,然後我們定義的介面的域名為 xy.xxx.com, 然後當我們訪問 http://xy.xxx.com/xxxx這樣的介面的時候,它會通過 location / {} 這樣的反向代理到 http://192.168.1.212:8136上來,當然對於我們的host也需要繫結下 192.168.1.212 xy.xxx.com 就可以了。

當然如果代理伺服器是一組伺服器的話,我們可以使用upstream指令配置後端伺服器組。如下程式碼:

upstream proxy_xxx {
  server http://192.168.1.211:8136/xxx;
  server http://192.168.1.212:8136/xxx;
  server http://192.168.1.213:8136/xxx;
}

server {
  listen 80;
  server_name xy.xxx.com; // 介面的域名
  access_log  /data/www/logs/nginx/access.log main;
  add_header Access-Control-Allow-Origin http://xy.xxx.com; // 允許的域名跨域
  add_header Access-Control-Allow-Credentials true;
  include nginx_xxx.conf;
  location / {
    proxy_pass proxy_xxx; // 對應上面的upstream 後面的 proxy_xxx
    include nginx_proxy.conf;
  }
  error_page   500 502 503 504  /502.html;
  location = /50x.html {
    root   html;
  }
}

但是在上面配置各個伺服器中都指明瞭傳輸協議為 http://, 但是如果上面的介面沒有指明協議的話,那麼我們需要在 proxy_pass上加上了,proxy_pass http://proxy_xxx 這樣的,如下配置程式碼:

upstream proxy_xxx {
  server 192.168.1.211:8136/xxx;
  server 192.168.1.212:8136/xxx;
  server 192.168.1.213:8136/xxx;
}

server {
  listen 80;
  server_name xy.xxx.com; // 介面的域名
  access_log  /data/www/logs/nginx/access.log main;
  add_header Access-Control-Allow-Origin http://xy.xxx.com; // 允許的域名跨域
  add_header Access-Control-Allow-Credentials true;
  include nginx_xxx.conf;
  location / {
    proxy_pass http://proxy_xxx; // 對應上面的upstream 後面的 proxy_xxx
    include nginx_proxy.conf;
  }
  error_page   500 502 503 504  /502.html;
  location = /50x.html {
    root   html;
  }
}

注意點:

1. 當我們配置是如下配置:

server {
  listen 80;
  server_name xy.xxx.com; // 介面的域名
  access_log  /data/www/logs/nginx/access.log main;
  add_header Access-Control-Allow-Origin http://xy.xxx.com; // 允許的域名跨域
  add_header Access-Control-Allow-Credentials true;
  include nginx_xxx.conf;
  location / {
    proxy_pass http://192.168.1.212:8136;
    include nginx_proxy.conf;
  }
  error_page   500 502 503 504  /502.html;
  location = /50x.html {
    root   html;
  }
}

當使用者使用介面 http://xy.xxx.com/xxx 的時候,nginx會自動指向內部伺服器 http://192.168.1.212:8136/xxx的。這個我們能理解的。

2. 當我們的nginx的配置是如下的:

server {
  listen 80;
  server_name xy.xxx.com; // 介面的域名
  access_log  /data/www/logs/nginx/access.log main;
  add_header Access-Control-Allow-Origin http://xy.xxx.com; // 允許的域名跨域
  add_header Access-Control-Allow-Credentials true;
  include nginx_xxx.conf;
  location / {
    proxy_pass http://192.168.1.212:8136/yyy;
    include nginx_proxy.conf;
  }
  error_page   500 502 503 504  /502.html;
  location = /50x.html {
    root   html;
  }
}

注意上面的 proxy_pass http://192.168.1.212:8136/yyy; 如果客戶端還是以 http://xy.xxx.com/xxx 訪問介面的時候,那麼nginx伺服器就會將請求地址指向與 http://192.168.1.212:8136/yyy了,而不是http://192.168.1.212:8136/xxx了。

因此如果我們在正常配置中,我們可以選擇第一種配置,直接指向域名,然後反向代理到 ip地址+埠號即可。

3. 理解 proxy_pass http://192.168.1.212 和 proxy_pass http://192.168.1.212/的區別;

上面的兩者的區別是 proxy_pass 指令的URL變數末尾新增了斜槓 '/', 下面我們再來看下nginx的配置,如下程式碼:

server {
  listen 80;
  server_name xy.xxx.com; // 介面的域名
  access_log  /data/www/logs/nginx/access.log main;
  add_header Access-Control-Allow-Origin http://xy.xxx.com; // 允許的域名跨域
  add_header Access-Control-Allow-Credentials true;
  include nginx_xxx.conf;
  location / {
    #配置1 proxy_pass http://192.168.1.212:8136;
    #配置2 proxy_pass http://192.168.1.212:8136/;
    include nginx_proxy.conf;
  }
  error_page   500 502 503 504  /502.html;
  location = /50x.html {
    root   html;
  }
}

在如上配置中,location塊使用了 '/' 作為uri變數的值來匹配的,因此上面的配置1和配置2效果是相同的,比如客戶端的介面請求是:
http://xy.xxx.com/xxx的時候,不管使用配置1還是配置2,都會指向內部伺服器 http://192.168.1.212:8936/xxx.

但是現在我們把程式碼改成如下配置,那就不一樣了:

server {
  listen 80;
  server_name xy.xxx.com; // 介面的域名
  access_log  /data/www/logs/nginx/access.log main;
  add_header Access-Control-Allow-Origin http://xy.xxx.com; // 允許的域名跨域
  add_header Access-Control-Allow-Credentials true;
  include nginx_xxx.conf;
  location /bus/ {
    #配置1 proxy_pass http://192.168.1.212:8136;
    #配置2 proxy_pass http://192.168.1.212:8136/;
    include nginx_proxy.conf;
  }
  error_page   500 502 503 504  /502.html;
  location = /50x.html {
    root   html;
  }
}

注意:上面的 location /bus/ , location塊使用了 /bus/ 作為uri變數的值來匹配,比如我們現在客戶端請求 http://xy.xxx.com/bus/xxx的時候,如果使用配置1的話,那麼它會指向內部伺服器的地址為:http://192.168.1.212:8136/bus/xxx, 那如果我們使用配置2的話,那麼它會指向內部伺服器的地址為:
http://192.168.1.212:8136/xxx, 這樣的。因此這就是加上 反斜槓的區別了。

相關文章