Nginx 七層反向代理


 

 

 

 


  Nginx 服務器的反向代理服務是其最常用的重要功能,由反向代理服務也可以衍生出很多與此相關的 Nginx 服務器重要功能,比如后面會介紹的負載均衡。本篇博客我們會先介紹 Nginx 的反向代理,當然在了解反向代理之前,我們需要先知道什么是代理以及什么是正向代理。

1、代理

  在Java設計模式中,代理模式是這樣定義的:給某個對象提供一個代理對象,並由代理對象控制原對象的引用。

  可能大家不太明白這句話,在舉一個現實生活中的例子:比如我們要買一間二手房,雖然我們可以自己去找房源,但是這太花費時間精力了,而且房屋質量檢測以及房屋過戶等一系列手續也都得我們去辦,再說現在這個社會,等我們找到房源,說不定房子都已經漲價了,那么怎么辦呢?最簡單快捷的方法就是找二手房中介公司(為什么?別人那里房源多啊),於是我們就委托中介公司來給我找合適的房子,以及后續的質量檢測過戶等操作,我們只需要選好自己想要的房子,然后交錢就行了。

  代理簡單來說,就是如果我們想做什么,但又不想直接去做,那么這時候就找另外一個人幫我們去做。那么這個例子里面的中介公司就是給我們做代理服務的,我們委托中介公司幫我們找房子。

  Nginx 主要能夠代理如下幾種協議,其中用到的最多的就是做Http代理服務器。

  

 

2、正向代理

  弄清楚什么是代理了,那么什么又是正向代理呢?

  這里我再舉一個例子:大家都知道,現在國內是訪問不了 Google的,那么怎么才能訪問 Google呢?我們又想,美國人不是能訪問 Google嗎(這不廢話,Google就是美國的),如果我們電腦的對外公網 IP 地址能變成美國的 IP 地址,那不就可以訪問 Google了。你很聰明,VPN 就是這樣產生的。我們在訪問 Google 時,先連上 VPN 服務器將我們的 IP 地址變成美國的 IP 地址,然后就可以順利的訪問了。

  這里的 VPN 就是做正向代理的。正向代理服務器位於客戶端和服務器之間,為了向服務器獲取數據,客戶端要向代理服務器發送一個請求,並指定目標服務器,代理服務器將目標服務器返回的數據轉交給客戶端。這里客戶端是要進行一些正向代理的設置的。

  PS:這里介紹一下什么是 VPN,VPN 通俗的講就是一種中轉服務,當我們電腦接入 VPN 后,我們對外 IP 地址就會變成 VPN 服務器的 公網 IP,我們請求或接受任何數據都會通過這個VPN 服務器然后傳入到我們本機。這樣做有什么好處呢?比如 VPN 游戲加速方面的原理,我們要玩網通區的 LOL,但是本機接入的是電信的寬帶,玩網通區的會比較卡,這時候就利用 VPN 將電信網絡變為網通網絡,然后在玩網通區的LOL就不會卡了(注意:VPN 是不能增加帶寬的,不要以為不卡了是因為網速提升了)。

  可能聽到這里大家還是很抽象,沒關系,和下面的反向代理對比理解就簡單了。

 

3、反向代理

  反向代理和正向代理的區別就是:正向代理代理客戶端,反向代理代理服務器。

  反向代理,其實客戶端對代理是無感知的,因為客戶端不需要任何配置就可以訪問,我們只需要將請求發送到反向代理服務器,由反向代理服務器去選擇目標服務器獲取數據后,在返回給客戶端,此時反向代理服務器和目標服務器對外就是一個服務器,暴露的是代理服務器地址,隱藏了真實服務器IP地址。

  下面我們通過兩張圖來對比正向代理和方向代理:

  

 

  

  理解這兩種代理的關鍵在於代理服務器所代理的對象是什么,正向代理代理的是客戶端,我們需要在客戶端進行一些代理的設置。而反向代理代理的是服務器,作為客戶端的我們是無法感知到服務器的真實存在的。

  總結起來還是一句話:正向代理代理客戶端,反向代理代理服務器。

 

Nginx七層反向代理:

環境:

IP 主機名 角色 備注
192.168.200.113 hhxx-01 Nginx代理服務器  
192.168.200.114 hhxx-02 web靜態處理服務器  
192.168.200.115 hhxx-03 web動態處理服務器  
       

 

使用nginx的實現負載均衡和動靜分離

源碼編譯安裝nginx的
一,安裝nginx時必須先安裝相應的編譯工具和相關依賴
[root @hhxx-01~] #yum -y install gcc gcc-c ++ autoconf automake
[root @hhxx-01~] #yum -y install zlib zlib- devel openssl openssl-devel pcre pcre-devel
zlib:和nginx的gzip的提供模塊,需要的zlib庫支持
OpenSSL的:nginx的提供SSL功能
PCRE:支持地址重寫改寫功能

#解壓Nginx的源碼包

[root @hhxx-01~] # tar  xf  nginx-1.12.2.tar.gz  -C  /usr/local/src /

[root @hhxx-01~] # cd /usr/local/src/nginx-1.12.2 /

[root@hhxx-01 ~]# ./configure --prefix=/usr/local/nginx --user=nginx --group=nginx --with-http_dav_module --with-http_stub_status_module --with-http_addition_module --with-http_sub_module --with-http_flv_module --with-http_mp4_module --with-stream && make && make install

#寫入到開機自動運行

[root @hhxx-01 nginx-1.12.2] # echo '/usr/local/nginx/sbin/nginx'>> /etc/rc.local

[root@hhxx-01 ~]# ln -s /usr/local/nginx/sbin/nginx /usr/local/sbin/

[root@hhxx-01 ~]# cd /usr/local/nginx/conf/
[root@hhxx-01 conf]# vim nginx.conf

user  nginx nginx;
worker_processes  1;

#error_log  logs/error.log;
#error_log  logs/error.log  notice;
error_log  logs/error.log  info;

pid        logs/nginx.pid;


events {
    use epoll;
    worker_connections  10240;
}


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  0;
    keepalive_timeout  65;

    #gzip  on;

    server {
        listen       80;
        server_name  localhost;

        charset utf-8;

        access_log  logs/host.access.log  main;

        location / {
            root   html;
            index  index.html index.htm;
        
#定義靜態動態轉發地址
if ($request_uri ~* \.html$) {                   #這段放在location里面
proxy_pass http://htmlservers;
}
if ($request_uri ~* \.php$) {
proxy_pass http://phpservers;
}
proxy_pass http://picservers;
}
}
#定義負載均衡集群組                          #這段要放在server外面,采用默認輪詢的方式
upstream htmlservers {
   server 192.168.200.114:80;
   server 192.168.200.115:80;
}
upstream phpservers {
   server 192.168.200.114:80;
   server 192.168.200.115:80;
}
upstream picservers {
   server 192.168.200.114:80;
   server 192.168.200.115:80;
}
}

[root@hhxx-01 conf]# nginx -t
[root@hhxx-01 conf]# nginx
[root@hhxx-01 conf]# killall -HUP nginx
[root@hhxx-01 conf]# netstat -lnpt | grep 80
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 15531/nginx: master

 

 

配置后端服務器:hhxx-02
#安裝Apache和PHP服務

[root @hhxx-02~] #yum install httpd php -y

#寫一個靜態測試頁面

[root @hhxx-02~] #echo "Hello,I' m No.192.168.200.114" > /var/www/html/index.html

#寫一個PHP探針頁面

[root@hhxx-02 ~]# cat <<END > /var/www/html/test.php
> <?PHP
> phpinfo():
> ?>
> 192.168.200.114 靜態頁面
> END

使用RZ命令上傳一張JPG格式的圖片改名為test.jpg放在。

[root@hhxx-02 ~]# cd /var/www/html/
[root@hhxx-02 html]# ls
2.jpg       index.html     test.php

#啟動Apache的服務

[root @hhxx-03 html] #systemctl start httpd



配置后端服務器:hhxx-02
#安裝Apache和PHP服務

[root @hhxx-02~] #yum install httpd php -y

#寫一個靜態測試頁面

[root @hhxx-02~] #echo "Hello,I' m No.192.168.200.114" > /var/www/html/index.html

#寫一個PHP探針頁面

[root@hhxx-02 ~]# cat <<END > /var/www/html/test.php
> <?PHP
> phpinfo():
> ?>
> 192.168.200.115 靜態頁面
> END

使用RZ命令上傳一張JPG格式的圖片改名為test.jpg放在。

[root@hhxx-02 ~]# cd /var/www/html/
[root@hhxx-02 html]# ls
2.jpg       index.html     test.php

#啟動Apache的服務

[root @hhxx-03 html] #systemctl start httpd

 

 

測試:

 

 

 

 

 

 

 

 

 

 

5、Nginx 反向代理相關指令介紹

①、listen

  該指令用於配置網絡監聽。主要有如下三種配置語法結構:

  一、配置監聽的IP地址

listen address[:port] [default_server] [setfib=number] [backlog=number] [rcvbuf=size] [sndbuf=size] [deferred]
    [accept_filter=filter] [bind] [ssl];

  二、配置監聽端口

listen port[default_server] [setfib=number] [backlog=number] [rcvbuf=size] [sndbuf=size] [accept_filter=filter] 
    [deferred] [bind] [ipv6only=on|off] [ssl];

 三、配置 UNIX Domain Socket

listen unix:path [default_server]  [backlog=number] [rcvbuf=size] [sndbuf=size] [accept_filter=filter] 
    [deferred] [bind] [ssl];

  上面的配置看似比較復雜,其實使用起來是比較簡單的:

1 listen *:80 | *:8080 #監聽所有80端口和8080端口
2 listen  IP_address:port   #監聽指定的地址和端口號
3 listen  IP_address     #監聽指定ip地址所有端口
4 listen port     #監聽該端口的所有IP連接

  下面分別解釋每個選項的具體含義:

  1、address:IP地址,如果是 IPV6地址,需要使用中括號[] 括起來,比如[fe80::1]等。

  2、port:端口號,如果只定義了IP地址,沒有定義端口號,那么就使用80端口。

  3、path:socket文件路徑,如 var/run/nginx.sock等。

  4、default_server:標識符,將此虛擬主機設置為 address:port 的默認主機。(在 nginx-0.8.21 之前使用的是 default 指令)

  5、 setfib=number:Nginx-0.8.44 中使用這個變量監聽 socket 關聯路由表,目前只對 FreeBSD 起作用,不常用。

  6、backlog=number:設置監聽函數listen()最多允許多少網絡連接同時處於掛起狀態,在 FreeBSD 中默認為 -1,其他平台默認為511.

  7、rcvbuf=size:設置監聽socket接收緩存區大小。

  8、sndbuf=size:設置監聽socket發送緩存區大小。

  9、deferred:標識符,將accept()設置為Deferred模式。

  10、accept_filter=filter:設置監聽端口對所有請求進行過濾,被過濾的內容不能被接收和處理,本指令只在 FreeBSD 和 NetBSD 5.0+ 平台下有效。filter 可以設置為 dataready 或 httpready 。

  11、bind:標識符,使用獨立的bind() 處理此address:port,一般情況下,對於端口相同而IP地址不同的多個連接,Nginx 服務器將只使用一個監聽指令,並使用 bind() 處理端口相同的所有連接。

  12、ssl:標識符,設置會話連接使用 SSL模式進行,此標識符和Nginx服務器提供的 HTTPS 服務有關。

②、server_name

  該指令用於虛擬主機的配置。通常分為以下兩種:

  1、基於名稱的虛擬主機配置

  語法格式如下:

server_name   name ...;

  一、對於name 來說,可以只有一個名稱,也可以有多個名稱,中間用空格隔開。而每個名字由兩段或者三段組成,每段之間用“.”隔開。

server_name 123.com www.123.com

  二、可以使用通配符“*”,但通配符只能用在由三段字符組成的首段或者尾端,或者由兩端字符組成的尾端。

server_name *.123.com www.123.*

  三、還可以使用正則表達式,用“~”作為正則表達式字符串的開始標記。

server_name ~^www\d+\.123\.com$;

  該表達式“~”表示匹配正則表達式,以www開頭(“^”表示開頭),緊跟着一個0~9之間的數字,在緊跟“.123.co”,最后跟着“m”($表示結尾)

  以上匹配的順序優先級如下:

1 ①、准確匹配 server_name
2 ②、通配符在開始時匹配 server_name 成功
3 ③、通配符在結尾時匹配 server_name 成功
4 ④、正則表達式匹配 server_name 成功

  2、基於 IP 地址的虛擬主機配置

  語法結構和基於域名匹配一樣,而且不需要考慮通配符和正則表達式的問題。

server_name 192.168.1.1

③、location

  該指令用於匹配 URL。

  語法如下:

1 location [ = | ~ | ~* | ^~] uri {
2 
3 }

  1、= :用於不含正則表達式的 uri 前,要求請求字符串與 uri 嚴格匹配,如果匹配成功,就停止繼續向下搜索並立即處理該請求。

  2、~:用於表示 uri 包含正則表達式,並且區分大小寫。

  3、~*:用於表示 uri 包含正則表達式,並且不區分大小寫。

  4、^~:用於不含正則表達式的 uri 前,要求 Nginx 服務器找到標識 uri 和請求字符串匹配度最高的 location 后,立即使用此 location 處理請求,而不再使用 location 塊中的正則 uri 和請求字符串做匹配。

  注意:如果 uri 包含正則表達式,則必須要有 ~ 或者 ~* 標識。

④、proxy_pass

  該指令用於設置被代理服務器的地址。可以是主機名稱、IP地址加端口號的形式。

  語法結構如下:

proxy_pass URL;

  URL 為被代理服務器的地址,可以包含傳輸協議、主機名稱或IP地址加端口號,URI等。

proxy_pass  http://www.123.com/uri;

⑤、index

  該指令用於設置網站的默認首頁。

  語法為:

index  filename ...;

  后面的文件名稱可以有多個,中間用空格隔開。

index  index.html index.jsp;

  通常該指令有兩個作用:第一個是用戶在請求訪問網站時,請求地址可以不寫首頁名稱;第二個是可以對一個請求,根據請求內容而設置不同的首頁。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM