您好,登錄后才能下訂單哦!
小編給大家分享一下nginx正向代理與反向代理的示例分析,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!
就是假設(shè)有一個(gè)內(nèi)網(wǎng)
內(nèi)網(wǎng)有兩臺(tái)機(jī)器,這兩臺(tái)機(jī)器只有 a 可以上網(wǎng)
b 不能上網(wǎng),但是 a 和 b 通過網(wǎng)絡(luò)相連接
這時(shí)如果 b 想訪問外網(wǎng),就可以通過 a 來正向代理訪問外網(wǎng)
正向代理就是在內(nèi)網(wǎng)中模擬目標(biāo)服務(wù)器,把內(nèi)網(wǎng)中其它機(jī)器的請(qǐng)求
轉(zhuǎn)發(fā)給外網(wǎng)中的真正的目標(biāo)服務(wù)器
所以正向代理是接受內(nèi)網(wǎng)其它機(jī)器的請(qǐng)求的
反向代理則是反過來
也是一個(gè)內(nèi)網(wǎng),有幾臺(tái)機(jī)器,只有其中一臺(tái)與外網(wǎng)連接
但是反向代理接受的不是內(nèi)網(wǎng)機(jī)器的訪問請(qǐng)求
反向代理接受的是外網(wǎng)過來的訪問請(qǐng)求
然后把請(qǐng)求轉(zhuǎn)發(fā)到內(nèi)網(wǎng)中的其它機(jī)器上去
外網(wǎng)發(fā)出請(qǐng)求的用戶并不知道反向代理的服務(wù)器把請(qǐng)求轉(zhuǎn)發(fā)給了誰
要在一臺(tái)機(jī)器上設(shè)置正向代理的功能
如圖,編輯一個(gè)nginx配置文件
上圖就是配置文件內(nèi)容
如果配置一臺(tái)服務(wù)器作為正向代理服務(wù)器
那么這個(gè)虛擬主機(jī)配置文件就必須是默認(rèn)虛擬主機(jī)
因?yàn)樗性L問這臺(tái)機(jī)器的網(wǎng)絡(luò)請(qǐng)求應(yīng)該先訪問這個(gè)虛擬主機(jī)才對(duì)
所以這里要設(shè)置 default_server
然后還要把原來的 默認(rèn)虛擬主機(jī) 配置文件名稱修改掉
如圖,把 default.conf 配置文件的名稱修改一下
這樣就取消了原來的默認(rèn)虛擬主機(jī)配置文件了
因?yàn)槟J(rèn)的默認(rèn)虛擬主機(jī)配置文件就是 default.conf
配置文件里面的 resolver 119.29.29.29
意思是配置一個(gè) dns 地址
因?yàn)槭亲稣虼?,接受了?nèi)網(wǎng)請(qǐng)求的域名后
要把請(qǐng)求發(fā)送給真正要訪問的服務(wù)器
但是內(nèi)網(wǎng)發(fā)送的域名是沒有包含 ip 地址的
所以還要把域名發(fā)送給 dns 服務(wù)器解析 ip 地址
拿到 ip地址后才能轉(zhuǎn)發(fā)到要訪問的服務(wù)器上去
所以這里需要配置一個(gè) dns 地址
接受了內(nèi)網(wǎng)域名后,就會(huì)把域名發(fā)送到這個(gè) dns 上去解析
下面的 location 按照?qǐng)D中設(shè)置就可以了
這樣正向代理服務(wù)器接受內(nèi)網(wǎng)機(jī)器請(qǐng)求后
就會(huì)把域名發(fā)到配置的dns上解析,然后訪問真正的服務(wù)器
再把真正服務(wù)器返回的內(nèi)容發(fā)送給發(fā)出請(qǐng)求的內(nèi)網(wǎng)機(jī)器
做一個(gè)反向代理的例子
如圖建立一個(gè)測(cè)試的虛擬主機(jī)配置文件
監(jiān)聽 8080 端口,域名為 www.test.com
根目錄是 /data/wwwroot/test.com
訪問虛擬主機(jī)顯示的首頁文件是 index.html
如圖,創(chuàng)建虛擬主機(jī)的根目錄 /data/wwwroot/test.com
然后使用 echo "test.com_8080" > !$/index.html
創(chuàng)建一個(gè)內(nèi)容為 test.com_8080 的首頁文件
這個(gè)文件在 /data/wwwroot/test.com 目錄里面
如圖,新建一個(gè)反向代理的虛擬主機(jī)配置文件
監(jiān)聽 80 端口,域名為 www.test.com
下面的 location / 里面就是反向代理的配置
當(dāng)訪問這個(gè)虛擬主機(jī)的時(shí)候,就會(huì)把訪問請(qǐng)求發(fā)送給 127.0.0.1:8080
如圖,使用 curl 訪問 127.0.0.1:8080 虛擬主機(jī)
成功返回了 test.com_8080 這說明這個(gè)虛擬主機(jī)能夠被訪問
如圖,再創(chuàng)建一個(gè)虛擬主機(jī)配置文件
跟之前的 test 虛擬主機(jī)差不多
但是這個(gè)虛擬主機(jī)并沒有設(shè)置 域名
location 設(shè)置返回的內(nèi)容是 8080 default 字符串
保存退出,重載 nginx
還要把 test虛擬主機(jī)的 default server 設(shè)置取消掉
那么現(xiàn)在 127.0.0.1:8080 對(duì)應(yīng)兩個(gè)虛擬主機(jī)
一個(gè)是 test 虛擬主機(jī),另外一個(gè)是 8080 default 虛擬主機(jī)
這兩個(gè)虛擬主機(jī)的 ip 端口都是一模一樣的
它們的區(qū)別是 test 虛擬主機(jī)是有域名的
而 8080 default 虛擬主機(jī)是沒有域名的
現(xiàn)在已經(jīng)設(shè)置了 8080 default 為默認(rèn)虛擬主機(jī)
所以如果只訪問 127.0.0.1:8080 的話
訪問的一定是 8080 default 虛擬主機(jī)
如果想訪問 test 虛擬主機(jī),就需要加上 test 虛擬主機(jī)的域名
才能成功訪問 test 虛擬主機(jī)
如圖,可以看到訪問 curl 127.0.0.1:8080/ 返回的結(jié)果是 8080 default
使用 curl -x127.0.0.1:8080 www.test.com
這里帶上了域名,返回的就是 test.com_8080
說明想訪問 test 虛擬主機(jī),ip端口還需要綁定域名才行
如圖,curl 訪問 127.0.0.1:80 域名 www.test.com
返回的是 test.com_8080 說明這個(gè)反向代理成功了
我們?cè)L問的是 80 端口,實(shí)際卻返回了 8080 端口的虛擬主機(jī)的內(nèi)容
如圖,這里把反向代理虛擬主機(jī)里面的 proxy_pass 行下面的都注釋掉
保存退出,重載 nginx
如圖,再使用 curl 訪問 127.0.0.1:80 域名 www.test.com
實(shí)際返回的卻是 8080 default
而我們想訪問的卻是 test 虛擬主機(jī)
如圖,proxy_set_header Host $host;
這一行代碼就是指定訪問的域名
上面設(shè)置了 127.0.0.1:8080
反向代理的時(shí)候就會(huì)指向這個(gè) ip端口
如果不設(shè)置 host 那就只會(huì)訪問 127.0.0.1:8080 的虛擬主機(jī)
如果設(shè)置了 host ,那么就會(huì)指向跟指定的 host 綁定的 127.0.0.1:8080
這里的 $host 是系統(tǒng)變量,實(shí)際的值就是當(dāng)前的虛擬主機(jī)的 server_name
也就是 www.test.com ,server_name 是什么,host的值就是什么
這里設(shè)置了 host 就相當(dāng)于 curl -x127.0.0.1:8080 www.test.com
如果這里不設(shè)置 host 那么就只會(huì)訪問 127.0.0.1:8080
這樣就可以把 域名 跟 ip端口進(jìn)行綁定
如圖,除了寫 ip端口之外,proxy_pass 也可以直接寫域名
這里寫的是 www.123.com:8080/
但是這樣寫的話, nginx 并不知道這個(gè)域名指向哪里
所以還需要在系統(tǒng)里面綁定對(duì)應(yīng)的 ip
例如在 /etc/hosts 文件里面,寫入對(duì)應(yīng)的 域名和 ip 進(jìn)行綁定
這樣nginx 里面的 proxy_pass 的域名系統(tǒng)就會(huì)解析出一個(gè) Ip 地址
然后再訪問這個(gè) ip端口
下面的 proxy_header Host 作用就是設(shè)置一個(gè) 域名
這個(gè)域名會(huì)與上面的 ip端口綁定訪問
如果上面的 ip端口 寫的不是 ip 而是域名
跟下面指定的域名是不沖突的,因?yàn)樯厦鎸懙挠蛎淖饔檬怯脕斫馕鰅p的
下面指定的域名才會(huì)跟上面解析出來的 ip端口進(jìn)行綁定訪問
這個(gè)例子使用的是 $host 這是 nginx全局變量
這個(gè)變量實(shí)際是對(duì)應(yīng)了一個(gè)值的,就是當(dāng)前虛擬主機(jī) server_name 的值
但是一般來說,還是直接寫 ip 端口方便一些
上面就是指定 ip端口
下面指定跟 ip端口綁定的 host 域名
如圖,proxy_pass 指令后面可以跟 url
有三種格式,傳輸協(xié)議+域名+uri (訪問路徑)
傳輸協(xié)議+ip端口+uri
傳輸協(xié)議+socket
這里 unix ,http ,https 都是傳輸協(xié)議的種類
域名+uri 和 ip端口+uri 還有 socket 都是訪問的路徑
socket 一般是某個(gè)程序?qū)S玫脑L問端口
訪問某個(gè)socket就是訪問某個(gè)特定的程序,所以不需要使用路徑
如圖,寫 proxy_pass 的時(shí)候,不同的寫法有不同的結(jié)果
比如 location /aming/
如果訪問的路徑包含 /aming/ 就會(huì)觸發(fā)
這里的proxy_pass 就會(huì)執(zhí)行
但是location 里面的 proxy_pass 不同的寫法會(huì)導(dǎo)致實(shí)際訪問的路徑有差別
雖然因?yàn)樵L問的路徑包含 /aming/ 目錄才執(zhí)行 proxy_pass
但是實(shí)際訪問的路徑不一定包含 /aming/
這個(gè)例子是訪問虛擬主機(jī)內(nèi)的 /aming/a.html 文件
根據(jù) proxy_pass 的不同寫法實(shí)際上會(huì)訪問到不同的路徑去
如果 ip端口 后面沒有接任何目錄符號(hào)
就會(huì)訪問 /aming/a.html,這是我們想要的
如果 ip端口后面接了根目錄符號(hào) /
那么就會(huì)直接訪問根目錄里面的 a.html文件,這顯然不對(duì)
ip端口后面接 /linux/ 那么就會(huì)訪問 /linux/ 里面的 a.html文件
如果 ip端口后面是 /linux 最后沒有跟目錄符號(hào) /
就會(huì)訪問 /linuxa.html
所以如果想正確訪問 /aming/a.html
有兩種寫法,一種是 ip端口后面不要加任何目錄符號(hào) /
第二種是完整的寫成 ip端口/aming/ 這樣寫
根據(jù)上面示例可以發(fā)現(xiàn),ip端口后面不管是什么目錄
實(shí)際訪問路徑就會(huì)變成直接把最終要訪問的文件名稱 a.html
直接添加到 ip端口 后面的目錄上去
所以 ip端口后面不寫任何目錄符號(hào)的話,系統(tǒng)才會(huì)自己添加 /aming/a.html 這個(gè)目錄路徑
一旦有任何目錄符號(hào)存在,就會(huì)直接把 a.html 放在這個(gè)目錄符號(hào)后面
第二種情況是,ip端口+ /linux
實(shí)際結(jié)果是訪問 /linuxa.html
這可能是因?yàn)?linux 后面沒有跟上任何目錄符號(hào) /
所以系統(tǒng)把 linux 認(rèn)為是一個(gè)沒有寫完的文件名稱
然后就直接把 a.html 這個(gè)文件名稱跟 linux 粘貼在一起
這樣就變成了要訪問的文件是 /linuxa.html 的形式
所以不管寫什么路徑,后面一定要跟上目錄符號(hào) /
如圖,proxy_set_header 是設(shè)置被代理的服務(wù)器可以接收到的 header 信息的
比如有三臺(tái)電腦 a b c
a 是我們用來訪問的電腦,我們從 a 發(fā)出訪問請(qǐng)求
b 是反向代理服務(wù)器,b 接收我們發(fā)出的訪問請(qǐng)求
c 是被反向代理的服務(wù)器,也就是我們真正要訪問的服務(wù)器
b 會(huì)把我們的訪問請(qǐng)求轉(zhuǎn)發(fā)給 c
如果不設(shè)置 proxy_set_header 的話,b 轉(zhuǎn)發(fā)請(qǐng)求給 c 的時(shí)候就不會(huì)帶上相應(yīng)的 header 信息
如果設(shè)置了這個(gè)參數(shù),在轉(zhuǎn)發(fā)請(qǐng)求的時(shí)候就會(huì)帶上對(duì)應(yīng)的 header 信息
其中 $remote_addr 和 $proxy_add_x_forwarded_for 這兩個(gè)變量是 nginx 的內(nèi)置變量
$remote_addr 變量里面保存的是 b 反向代理服務(wù)器本身的 ip 地址
$proxy_add_x_forwarded_for 變量里面保存的是 a 客戶端電腦的 ip 地址
如果不設(shè)置這個(gè)變量的話,c 服務(wù)器實(shí)際上是不知道訪問請(qǐng)求的真實(shí)來源地址的
而設(shè)置了這個(gè)變量, c 服務(wù)器就可以知道這個(gè)訪問請(qǐng)求是哪一個(gè)ip地址發(fā)過來的
如圖,編輯 www.test.com 虛擬主機(jī)的配置文件
假設(shè)這個(gè)虛擬主機(jī)是我們要訪問的 c 服務(wù)器
location 里面設(shè)置了兩個(gè)echo 顯示訪問請(qǐng)求的來源地址,和真實(shí)來源地址
$remote_addr 記錄了反向代理服務(wù)器的地址
$proxy_add_x_forwarded_for 記錄了訪問請(qǐng)求的真實(shí)來源地址,也就是客戶端的地址
這樣設(shè)置,訪問這個(gè)虛擬主機(jī)的時(shí)候,就會(huì)顯示這兩個(gè)變量里面保存的值
保存退出,然后重載配置文件
如圖,編輯反向代理服務(wù)器虛擬主機(jī)的配置文件
如圖,可以看到 location 里面
proxy_set_header X-Real-IP 和 proxy_set_header X-Forwarded-For 這兩行是被注釋掉的
先做個(gè)測(cè)試,保存退出重載配置文件
如圖,使用 curl 測(cè)試從 192.168.133.140:80 發(fā)出訪問請(qǐng)求
192.168.133.140 這個(gè) ip 實(shí)際就是 客戶端 ip
因?yàn)樵L問請(qǐng)求就是從這個(gè) ip 發(fā)出來的
但是可以看到,測(cè)試之后,實(shí)際顯示的卻是兩個(gè) 127.0.0.1 的回環(huán)地址
并沒有 192.168.133.140 這個(gè) ip
在這個(gè)測(cè)試?yán)锩?,反向代理服?wù)器 和 真實(shí)服務(wù)器 都在本機(jī)上面
所以真實(shí)服務(wù)器 c 接收的訪問請(qǐng)求來源 ip 就是本機(jī)的回環(huán)地址
反向代理服務(wù) b 發(fā)送請(qǐng)求給 真實(shí)服務(wù)器 c 走的就是 127.0.0.1 的內(nèi)部回環(huán)地址
因?yàn)檫@兩個(gè)服務(wù)器都在本機(jī)上,本機(jī)上的程序之間通訊基本都是走 127.0.0.1 回環(huán)地址的
所以 c 的 $remote_addr 的值就是 127.0.0.1
因?yàn)榉聪虼矸?wù)器 b 沒有設(shè)置 $proxy_add_x_forwarded_for
所以真實(shí)服務(wù)器 c 的接收到的 $proxy_add_x_forwarded_for 變量值就是請(qǐng)求發(fā)送過來的 ip
也就是 127.0.0.1
$proxy_add_x_forwarded_for 這個(gè)變量實(shí)際上是記錄了從客戶端開始
請(qǐng)求總共經(jīng)過了哪些 ip 地址的一個(gè)變量值,多個(gè) ip 地址之間使用逗號(hào)分隔
如果發(fā)送的訪問請(qǐng)求沒有設(shè)置 $proxy_add_x_forwarded_for 這個(gè)變量的話
那么接收方的這個(gè)變量的值就只是訪問請(qǐng)求發(fā)送過來的上一個(gè) ip , 也就是跟 remote_addr 相同
比如訪問請(qǐng)求從 a 到 b 到 c
如果 b 設(shè)置了 $proxy_add_x_forwarded_for 的話
那么這個(gè)變量的格式就是 a_ip, b_ip
也就是記錄了 a 的ip 和 b 的ip
如果中間還經(jīng)過更多的服務(wù)器的話,那么它們的 ip 也會(huì)被記錄下來,使用逗號(hào)分隔
當(dāng)然每一臺(tái)代理服務(wù)器都需要設(shè)置 $proxy_add_x_forwarded_for 這個(gè)變量才行
不然下一臺(tái)代理服務(wù)器的 $proxy_add_x_forwarded_for 這個(gè)變量將不會(huì)記錄到之前經(jīng)過的 ip
只能夠記錄到上一臺(tái)服務(wù)器的 ip
所以在這個(gè)測(cè)試?yán)锩妫驗(yàn)?b 沒有設(shè)置 $proxy_add_x_forwarded_for
所以 c 服務(wù)的 $proxy_add_x_forwarded_for 變量的值等于 $remote_addr 的值
如圖,第二次測(cè)試,編輯反向代理服務(wù)器 b 的配置文件
把 location 里面的 X-Real-IP 和 X-Forwarded-For 兩行注釋去掉
保存退出重載配置文件
如圖,再次測(cè)試
可以看到返回的結(jié)果,第一行 remote_addr 的值是 127.0.0.1
這是 代理服務(wù)器 b 的 ip
第二行 $proxy_add_x_forwarded_for 的值是兩個(gè) ip
curl 命令里面,訪問請(qǐng)求是從 192.168.133.140 發(fā)出的
也就是說,客戶端 a 的 ip 就是 192.168.133.140
b 的 ip 就是 127.0.0.1
$proxy_add_x_forwarded_for 記錄的是到達(dá) c 的訪問請(qǐng)求經(jīng)過了哪些 ip
訪問請(qǐng)求是從 a 到 b 再從 b 到 c 的
所以 $proxy_add_x_forwarded_for 變量 記錄了 a 的 ip 和 b 的 ip
因?yàn)樵L問請(qǐng)求在到達(dá) c 之前經(jīng)過了這兩個(gè) ip 地址
所以以后做反向代理的時(shí)候,這幾行變量都要設(shè)置
后面的真實(shí)服務(wù)器才能夠獲取到訪問請(qǐng)求的真實(shí) ip 地址
如圖,redirect 應(yīng)用的場(chǎng)景不多,主要有三種寫法
功能是修改被代理的服務(wù)器返回的 location 和 refresh 頭域信息
第一種寫法,redirect 是返回的頭域信息
replacement 是要修改的信息
redirect 會(huì)被修改為 replacement
第二種寫法是 default 就是默認(rèn)設(shè)置的意思
第三種 off 意思就是關(guān)閉 redirect功能
如圖,做一個(gè)測(cè)試,編輯代理服務(wù)器的配置文件
要測(cè)試成功有幾個(gè)條件要達(dá)成
首先,location 后面只能是根目錄 / 不能是加別的
第二個(gè)條件是proxy_pass后面的 url 后面不能加 / 符號(hào)
正常來說是要 / 結(jié)尾的,但是這里不能用 / 結(jié)尾
然后訪問的目錄必須真實(shí)存在,如果不存在可以創(chuàng)建一個(gè)
然后再目錄里面也可以創(chuàng)建一個(gè) index.html 文件,里面編輯一些字符串內(nèi)容
保存退出重載一下配置文件
如圖,編輯被代理服務(wù)器的配置文件
寫成如圖所示的這種簡單格式
保存退出重載配置文件
如圖,curl 測(cè)試訪問的時(shí)候,如果 aming 后面加了 / 結(jié)尾,那么就會(huì)訪問到 index.html 文件
但是我們要訪問的是目錄本身,并不是里面的某個(gè)文件
所以 crul 的時(shí)候,訪問的地址結(jié)尾不能加上 / 符號(hào)
這樣就可以訪問到 aming 目錄了
可以看到,返回的代碼是 301 表示永久重定向
下面的 location 后面的字段,是帶端口8080 的訪問路徑
如圖,編輯被代理服務(wù)器的配置文件
添加 access_log /tmp/456.log
這樣就開啟了服務(wù)器的訪問日志,檢查訪問日志可以更清晰的了解訪問過程
保存退出重載
如圖,重新 curl 測(cè)試一次,這次測(cè)試 aming 結(jié)尾是帶 / 符號(hào)的
cat 查看 /tmp/456.log 訪問日志
發(fā)現(xiàn)日志信息沒有 host 和 端口 等信息
這種情況可以修改 nginx.conf 配置文件里面的 format 配置
如圖,配置文件里面 log_format main 這三行本來是被注釋掉的
現(xiàn)在把注釋去掉,讓這幾行產(chǎn)生作用,這個(gè)就是日志返回信息的格式設(shè)置
如圖,在最后面添加兩個(gè)nginx變量 $host $server_port 這兩個(gè)變量
然后保存退出重載一下,這樣訪問日志顯示的信息里面,就會(huì)加上這兩個(gè)變量的信息了
如圖,編輯代理服務(wù)器配置文件,同樣添加 access_log 配置
日志地址就是 /tmp/proxy.log
后面加上 main 因?yàn)?nginx.conf 里面配置的格式是用 main 命名的
這里加上main 表示使用 main 命名的格式來顯示日志信息
如圖,同樣被代理服務(wù)器里面的 access_log
后面也需要加上 main表示使用 main 的格式顯示日志信息
保存退出重載一下
如圖,curl 測(cè)試一下,這次測(cè)試是用 / 符號(hào)結(jié)尾的
查看 456.log 后端服務(wù)器的日志,可以看到,訪問的是 8080 端口
查看 proxy.log 代理服務(wù)器日志,可以看到,訪問的是 80 端口
網(wǎng)絡(luò)代碼都是 200 這樣是正常的
如圖,這次訪問 aming 結(jié)尾不帶 / 符號(hào)
可以看到返回的是 301
查看 proxy.log 返回的也是 301
如圖,重新測(cè)試一下,再查看兩個(gè)日志
看到 301 再到 200 的日志信息
總之確定了我們?cè)L問 80 端口,跳轉(zhuǎn)到了 8080 端口
但是客戶端是訪問不到 8080 端口的
如圖,解決這個(gè)問題可以使用 proxy_redirect
這里是 http://$host:8080/ /;
這樣寫可以把本來返回的 8080 端口信息給去掉
保存退出重載
如圖,重新測(cè)試
可以看到,返回的是 301
然后 location 后面的地址里面,也沒有 8080 端口的信息存在了
proxy_buffering 是緩沖的意思
緩沖就是在內(nèi)存里面劃一塊區(qū)域,在里面寫數(shù)據(jù)
寫到一定量的時(shí)候,才會(huì)把緩沖里面的數(shù)據(jù)寫進(jìn)硬盤中
這樣做的話,就可以大大減少硬盤的讀寫頻率
如果不做緩沖,每產(chǎn)生一次數(shù)據(jù)都要讀寫一次硬盤,對(duì)于硬盤的負(fù)擔(dān)就會(huì)很大
假設(shè)有三個(gè)對(duì)象,客戶端 a 代理服務(wù)器 b 被代理服務(wù)器 c
a 發(fā)出請(qǐng)求,b 接收請(qǐng)求,轉(zhuǎn)發(fā)給 c
c 返回?cái)?shù)據(jù)給 b ,然后 b 再把數(shù)據(jù)發(fā)給 a
這是一般的運(yùn)作情況,但是如果 a 發(fā)出許多訪問請(qǐng)求
或者有很多個(gè)客戶端發(fā)出訪問請(qǐng)求
那么對(duì)于代理服務(wù)器 b 和 被代理服務(wù)器 c 來說
每個(gè)請(qǐng)求都要按照這個(gè)流程處理一次,負(fù)擔(dān)就會(huì)很重
proxy_buffering 就是在 代理服務(wù)器 b 的內(nèi)存里面設(shè)置一個(gè)或多個(gè)緩沖區(qū)域
當(dāng)緩沖區(qū)域數(shù)據(jù)量滿了的時(shí)候,才把數(shù)據(jù)轉(zhuǎn)發(fā)給相應(yīng)的客戶端
這樣代理服務(wù)器 b 的數(shù)據(jù)轉(zhuǎn)發(fā)次數(shù)就大大減少了,負(fù)擔(dān)就下降了
當(dāng) proxy_buffering 開啟的時(shí)候,由 proxy_busy_buffer_size 來決定何時(shí)把數(shù)據(jù)發(fā)送給 a
在這個(gè)過程中,如果 buffer 區(qū)域被寫滿,有數(shù)據(jù)溢出
多出來的數(shù)據(jù)會(huì)被寫入到 temp_file 也就是一個(gè)臨時(shí)文件中去,這個(gè)文件會(huì)存儲(chǔ)在硬盤上
如果 proxy_buffering 關(guān)閉的話,c 反饋的數(shù)據(jù)就直接由 b 轉(zhuǎn)發(fā)給 a
而不會(huì)有別的操作發(fā)生
如圖,不管 proxy_buffering 是 on 還是 off 的狀態(tài)
proxy_buffer_size 這個(gè)選項(xiàng)都是生效的,這個(gè)參數(shù)是用來設(shè)置一個(gè) buffer
這個(gè) buffer 存儲(chǔ)了服務(wù)器反饋的 header 信息
如果設(shè)置不夠大,存儲(chǔ)不了 header 信息的話,會(huì)出現(xiàn) 502 錯(cuò)誤碼
所以建議設(shè)置為 4k
如圖, proxy_buffers 是定義每個(gè)請(qǐng)求的 緩沖區(qū)個(gè)數(shù) 和 每個(gè)緩沖區(qū)的具體大小
這里定義了 8 4k 意思就是有 8個(gè)緩沖區(qū),每個(gè)緩沖區(qū)的大小為 4k
那么總緩沖區(qū)的大小就是 8*4 = 32 k
假設(shè)有一萬個(gè)請(qǐng)求,那么緩沖區(qū)就是 8 * 10000 個(gè)緩沖區(qū)了
因?yàn)檫@個(gè)設(shè)置是針對(duì)每個(gè)請(qǐng)求來的,而不是總共只有 8 個(gè)緩沖區(qū)
proxy_busy_buffer_size 定義的是達(dá)到多少數(shù)據(jù)量,就把數(shù)據(jù)傳輸給客戶端
這里定義的是 16k ,那么當(dāng) b 的屬于這個(gè)請(qǐng)求的緩沖區(qū)接收到 16k 的數(shù)據(jù)量的時(shí)候
就會(huì)把數(shù)據(jù)轉(zhuǎn)發(fā)給 a
這里緩沖區(qū)有 8 個(gè),總共 32k 的大小,緩沖區(qū)一般來說處于兩種狀態(tài)
一個(gè)是接收數(shù)據(jù),一個(gè)是發(fā)送數(shù)據(jù),并不能同時(shí)接收數(shù)據(jù)和發(fā)送數(shù)據(jù)
proxy_busy_buffer_size 定義的就是 發(fā)送數(shù)據(jù)的緩沖區(qū)的大小
所以 proxy_busy_buffer_size 的大小要比緩沖區(qū)的總大小要小才行
接收的數(shù)據(jù)達(dá)到 proxy_busy_buffer_size 設(shè)置的數(shù)據(jù)量的時(shí)候
這些緩沖區(qū)就進(jìn)入發(fā)送數(shù)據(jù)的狀態(tài),剩下的緩沖區(qū)則是接收數(shù)據(jù)的狀態(tài)
如果請(qǐng)求反饋的數(shù)據(jù)總量小于 proxy_busy_buffer_size 設(shè)置的值
那么 b 接收完成就會(huì)直接轉(zhuǎn)發(fā)為 a
如果請(qǐng)求反饋的數(shù)據(jù)總量大于 proxy_busy_buffer_size 設(shè)置的值
那么當(dāng)緩沖區(qū)接收的數(shù)據(jù)量達(dá)到 proxy_busy_buffer_size設(shè)置的值的時(shí)候
就會(huì)把這部分的數(shù)據(jù)先發(fā)送給 a
如圖,proxy_temp_path 定義的是臨時(shí)文件存放目錄
舉例,a 發(fā)出請(qǐng)求,b代理服務(wù)器分配給 a 這個(gè)請(qǐng)求的 緩沖區(qū) 總大小為 32k
但是 c 服務(wù)對(duì)這個(gè)請(qǐng)求反饋的數(shù)據(jù)量為 100 MB 這么大,遠(yuǎn)遠(yuǎn)超過緩沖區(qū)的大小
這種情況下, b 接收 c 的數(shù)據(jù)的過程中就會(huì)有很多數(shù)據(jù)溢出緩沖區(qū)
這些溢出的數(shù)據(jù)會(huì)被先保存到 b 的硬盤上的臨時(shí)文件里面去
proxy_temp_path 定義的就是這個(gè)臨時(shí)文件存放的路徑,還有子目錄層級(jí)
這里定義的路徑是 /usr/local/nginx/proxy_temp 這是一個(gè)目錄名稱
臨時(shí)文件就會(huì)存放到這個(gè)目錄里面去
后面的數(shù)字 1 2 表示子目錄層級(jí)
前面的目錄路徑是由我們自己定義的,子目錄是系統(tǒng)自動(dòng)創(chuàng)建的
創(chuàng)建多少個(gè)子目錄層級(jí),可以通過后面的數(shù)字設(shè)置
比如 只寫一個(gè) 1 就表示子目錄只有一層,子目錄的名稱為 0-9 的命名方式
根據(jù)定義,proxy_temp_path 支持三級(jí)子目錄,也就是可以寫 3 個(gè)數(shù)字
比如寫 1 子目錄數(shù)量和命名方式 就是 0- 9 共10個(gè)
如果寫 2 就是 00-99 共100個(gè),如果寫 3 就是 000-999 共1000個(gè)子目錄
子目錄名稱也是根據(jù)這些數(shù)字來命名的
如果寫 1 3 就表示子目錄分兩層,第一層是 0-9 10個(gè)子目錄
第二層是 000-999 1000個(gè)子目錄,也可以反過來寫 3 1
這樣第一層就是 1000 個(gè)子目錄,每個(gè)目錄下面第二層又有 10 個(gè)子目錄
proxy_max_temp_file_size 定義的是 臨時(shí)文件的總大小
比如這里設(shè)置為 100M 說明每個(gè)臨時(shí)文件最大為 100M
臨時(shí)文件的數(shù)據(jù)如果傳輸完成,就會(huì)自動(dòng)刪除
proxy_temp_file_write_size 定義的是同時(shí)寫入臨時(shí)文件數(shù)據(jù)量的總大小
這里定義一個(gè)值比如 8k 或者 16k
如果同時(shí)寫入的數(shù)據(jù)量低于這個(gè)值,那么就增加同時(shí)寫入的數(shù)據(jù)量
如果高于這個(gè)值,那么就減少同時(shí)寫入的數(shù)據(jù)量
因?yàn)橥瑫r(shí)寫入的數(shù)據(jù)量太高,對(duì)于硬盤 IO 負(fù)擔(dān)太大,而太小則沒有充分用到硬盤的性能
所以設(shè)置一個(gè)值,既不會(huì)太快,也不會(huì)太慢,充分使用到硬盤的性能,又不會(huì)負(fù)擔(dān)過重
如圖,這是一個(gè)使用 proxy_buffering 的例子
首先是設(shè)置為 on 的狀態(tài),也就是打開 buffer 功能
頭文件存儲(chǔ)的 buffer區(qū)域大小為 4k
然后是其它數(shù)據(jù)的 buffer 區(qū)域?yàn)?2 個(gè),每個(gè)大小為 4k
然后是 busy_buffers 的數(shù)據(jù)量為 4k
buffer 接收的數(shù)據(jù)量達(dá)到 4k 時(shí)就會(huì)發(fā)送數(shù)據(jù)
然后是臨時(shí)文件存放的路徑定義,定義了兩層子目錄
分別是 1 2 也就是 第一層有 0-9 10個(gè)子目錄
然后每個(gè)子目錄下面 第二層有 00-99 100個(gè)子目錄
然后是每個(gè)臨時(shí)文件的大小為 20M
然后是臨時(shí)文件同時(shí)寫入的數(shù)據(jù)量定義為 8k
如圖,要使用 proxy_cache 首先要打開 proxy_buffering 功能
proxy_cache 就是緩存功能
客戶端 a 發(fā)出請(qǐng)求,如果 a 請(qǐng)求的數(shù)據(jù)已經(jīng)保存到 代理服務(wù)器 b 的緩存里面的話
那么 b 會(huì)把相關(guān)數(shù)據(jù)直接發(fā)送給 a 而不會(huì)去向 服務(wù)器 c 請(qǐng)求數(shù)據(jù)
如果不開啟緩存功能,那么 a 的每一次請(qǐng)求,代理服務(wù)器 b 都會(huì)向 服務(wù)器 c 請(qǐng)求獲取一次數(shù)據(jù)
如果 a 兩次請(qǐng)求的數(shù)據(jù)是一樣的,也會(huì)向 服務(wù)器 c 請(qǐng)求兩次數(shù)據(jù)
開啟緩存功能的話,第一次請(qǐng)求的數(shù)據(jù)已經(jīng)被保存到 緩存里面了,第二次如果請(qǐng)求同樣的數(shù)據(jù)
b 就會(huì)直接從緩存里面獲取,而不會(huì)去向 c 獲取數(shù)據(jù),這樣就減輕了 服務(wù)器 c 的負(fù)擔(dān)
總結(jié),緩沖可以減輕 代理服務(wù)器b 的負(fù)擔(dān),緩存可以減輕 被代理服務(wù)器 c 的負(fù)擔(dān)
如圖,proxy_cache 功能的開啟與關(guān)閉
proxy_cache off 意思就是關(guān)閉緩存功能
proxy_cache zone 就是開啟緩存區(qū),zone 就是緩存區(qū)的名稱
緩存區(qū)名稱是可以任意命名的,可以是 zone 也可以是 123 等任意名稱
這里寫一個(gè)緩存區(qū)名稱就表示了開啟一個(gè)以這個(gè)名稱命名的緩存區(qū)
從 nginx 0.7.66 版本開始,開啟 proxy_cache 之后
還會(huì)檢測(cè)被代理服務(wù)器的 http 響應(yīng)頭中的 Cache-Control ,Expire 頭域
如果 cache-control 的值為 no-cache 時(shí),那么這個(gè)請(qǐng)求的數(shù)據(jù)是不會(huì)被緩存的
如圖,curl -I 一個(gè)網(wǎng)站請(qǐng)求數(shù)據(jù)
可以看到,返回的頭文件信息,Cache-Control 后面的值里面
存在 no-cache ,表示這個(gè)請(qǐng)求返回的數(shù)據(jù)是不會(huì)被緩存的
如圖,proxy_cache_bypass 這個(gè)參數(shù)是設(shè)置某種情況下
請(qǐng)求的數(shù)據(jù)不從 cache 中獲取,而是直接從后端服務(wù)器中獲取
這個(gè)參數(shù)后面的 string 一般為 nginx 的一些變量
比如 proxy_cache_bypass $cookie_nocache $arg_nocache $arg_comment;
這樣設(shè)置就表示,這三個(gè)變量的值,任意一個(gè)不為 0 或 空 的情況下
響應(yīng)數(shù)據(jù)就不會(huì)從 cache 中獲取,而是直接從后端服務(wù)器獲取
暫時(shí)很少用到,了解一下即可
如圖,proxy_no_cache 跟上面的參數(shù)用法相似
主要是設(shè)置某種情況下,獲取的數(shù)據(jù)不進(jìn)行緩存
示例 proxy_no_cache $cookie_nocache $arg_nocache $arg_comment;
這樣設(shè)置就表示,當(dāng)后面這三個(gè)變量任意一項(xiàng)的值不為 0 或者 空 的時(shí)候
獲取的數(shù)據(jù)都不進(jìn)行緩存
如圖,這個(gè)參數(shù)格式跟上面的參數(shù)差不多,一般不需要設(shè)置,保持默認(rèn)就可以了
如圖,proxy_cache_path 是設(shè)置緩存區(qū)具體配置的參數(shù)
緩存除了內(nèi)存中的空間外,還可以在硬盤中劃出一塊空間來做緩存
path 就是指定一個(gè)目錄路徑作為緩存路徑,緩存會(huì)存放到這里面
levels=1:2 這個(gè)表示目錄層級(jí),第一個(gè)數(shù)字設(shè)置的是第一層
第二個(gè)數(shù)字設(shè)置的是第二層
1 表示 0-9 a-f 總共16個(gè)字符,每個(gè)目錄由單個(gè)字符組成,一共16個(gè)目錄
2 表示 0-9 a-f 總共16個(gè)字符,但是每個(gè)目錄由兩個(gè)字符組成,00,01,04,2f 之類的,有兩百多種組合
總之這個(gè)參數(shù)是設(shè)置子目錄層級(jí),第一個(gè)數(shù)字表示第一層
第二個(gè)數(shù)字表示第二層
keys_zone 是設(shè)置內(nèi)存zone 的名稱和大小
keys_zone=my_zone:10m 就表示zone的名稱叫做 my_zone
然后 zone 的大小是 10MB
inactive 是設(shè)置多長時(shí)間后,把緩存刪除
比如圖中設(shè)置為 300s 意思就是,如果數(shù)據(jù)在 300秒內(nèi)沒有被訪問過
那么這個(gè)數(shù)據(jù)就會(huì)從緩存中刪除
max_size 是設(shè)置硬盤中的緩存最多可以存儲(chǔ)多少數(shù)據(jù)
比如這里設(shè)置為 5g ,上面設(shè)置的目錄 /data/nginx_cache/
這個(gè)硬盤上的目錄,最多可以存放 5g 的數(shù)據(jù),如果超過這個(gè)量
系統(tǒng)就會(huì)先把訪問量最少的數(shù)據(jù)刪除,再放新的數(shù)據(jù)進(jìn)去
proxy_cache_path 這行代碼不能寫在 配置文件的 server 括號(hào)內(nèi)
要寫在 http 括號(hào)里面
舉例說明,首先編輯 nginx.conf 配置文件
如圖,在 server 的外面添加 proxy_cache_path 代碼
如圖,
因?yàn)橹付ǖ木彺婺夸?/data/nginx_cache/ 不存在,所以這里要?jiǎng)?chuàng)建一下
如圖,編譯一個(gè)虛擬主機(jī)的配置文件,在location 里面添加 proxy_cache my_zone;
這樣這個(gè)虛擬主機(jī)接收請(qǐng)求的時(shí)候,就會(huì)使用 my_zone 這個(gè)緩存空間了
而 my_zone 緩存空間的具體定義已經(jīng)在 nginx.conf 配置文件里面作了定義
nginx.conf 里面的配置內(nèi)容對(duì)所有虛擬主機(jī)都是有效的
所以在 nginx.conf 里面定義了 my_zone 的話
那么在所有虛擬主機(jī)配置文件里面使用 proxy_cache my_zone
這些虛擬主機(jī)就都可以使用到 my_zone 這個(gè)緩存空間
然后保存退出重載配置文件就可以生效了
平時(shí)使用,只需要添加這樣兩行代碼就成功配置好緩存了
如圖,還有一個(gè)問題就是,nginx 服務(wù)本身的權(quán)限是 nobody
剛才的目錄是使用 root 權(quán)限創(chuàng)建的
所以這里要把 緩存目錄 的所有者所屬組修改成 nobody
這樣nginx 服務(wù)操作這個(gè)目錄的時(shí)候就不會(huì)有權(quán)限問題了
如圖,查看 /data/nginx_cache/ 目錄內(nèi)容
可以看到 0-9 a-f 的第一級(jí)目錄
進(jìn)入 0 目錄內(nèi)查看,可以看到由兩位數(shù)構(gòu)成的 第二級(jí)目錄
總結(jié),緩存空間配置主要就是定義 proxy_cache_path
可以在 nignx.conf 里面定義,這樣任何虛擬主機(jī)都可以使用到
定義好 proxy_cache_path 后,在需要使用緩存的虛擬主機(jī) server內(nèi)
配置 proxy_cache zone_name
zone_name 就是 proxy_cache_path 里面定義好的緩存空間名稱
這樣對(duì)應(yīng)的虛擬主機(jī)就可以使用這個(gè)緩存空間了
以上是“nginx正向代理與反向代理的示例分析”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對(duì)大家有所幫助,如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。