OpenResty Nginx 反向代理

2021-08-13 10:53 更新

什么是反向代理

反向代理(Reverse Proxy)方式是指用代理服務(wù)器來(lái)接受 internet 上的連接請(qǐng)求,然后將請(qǐng)求轉(zhuǎn)發(fā)給內(nèi)部網(wǎng)絡(luò)上的服務(wù)器,并將從服務(wù)器上得到的結(jié)果返回給 internet 上請(qǐng)求連接的客戶端,此時(shí)代理服務(wù)器對(duì)外就表現(xiàn)為一個(gè)反向代理服務(wù)器。

舉個(gè)例子,一個(gè)用戶訪問(wèn) http://www.example.com/readme,但是 www.example.com 上并不存在 readme 頁(yè)面,它是偷偷從另外一臺(tái)服務(wù)器上取回來(lái),然后作為自己的內(nèi)容返回給用戶。但是用戶并不知情這個(gè)過(guò)程。對(duì)用戶來(lái)說(shuō),就像是直接從 www.example.com 獲取 readme 頁(yè)面一樣。這里所提到的 www.example.com 這個(gè)域名對(duì)應(yīng)的服務(wù)器就設(shè)置了反向代理功能。

反向代理服務(wù)器,對(duì)于客戶端而言它就像是原始服務(wù)器,并且客戶端不需要進(jìn)行任何特別的設(shè)置??蛻舳讼蚍聪虼淼拿臻g(name-space)中的內(nèi)容發(fā)送普通請(qǐng)求,接著反向代理將判斷向何處(原始服務(wù)器)轉(zhuǎn)交請(qǐng)求,并將獲得的內(nèi)容返回給客戶端,就像這些內(nèi)容原本就是它自己的一樣。如下圖所示:

proxy

反向代理典型應(yīng)用場(chǎng)景

反向代理的典型用途是將防火墻后面的服務(wù)器提供給 Internet 用戶訪問(wèn),加強(qiáng)安全防護(hù)。反向代理還可以為后端的多臺(tái)服務(wù)器提供負(fù)載均衡,或?yàn)楹蠖溯^慢的服務(wù)器提供 緩沖 服務(wù)。另外,反向代理還可以啟用高級(jí) URL 策略和管理技術(shù),從而使處于不同 web 服務(wù)器系統(tǒng)的 web 頁(yè)面同時(shí)存在于同一個(gè) URL 空間下。

Nginx 的其中一個(gè)用途是做 HTTP 反向代理,下面簡(jiǎn)單介紹 Nginx 作為反向代理服務(wù)器的方法。

場(chǎng)景描述:訪問(wèn)本地服務(wù)器上的 README.md 文件 http://localhost/README.md,本地服務(wù)器進(jìn)行反向代理,從 https://github.com/moonbingbing/openresty-best-practices/blob/master/README.md 獲取頁(yè)面內(nèi)容。

nginx.conf 配置示例:

worker_processes 1;

pid logs/nginx.pid;
error_log logs/error.log warn;

events {
    worker_connections 3000;
}

http {
    include mime.types;
    server_tokens off;

    ## 下面配置反向代理的參數(shù)
    server {
        listen    8866;

        ## 1. 用戶訪問(wèn) http://ip:port,則反向代理到 https://github.com
        location / {
            proxy_pass  https://github.com;
            proxy_redirect     off;
            proxy_set_header   Host             $host;
            proxy_set_header   X-Real-IP        $remote_addr;
            proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
        }

        ## 2.用戶訪問(wèn) http://ip:port/README.md,則反向代理到
        ##   https://github.com/.../README.md
        location /README.md {
            proxy_set_header  X-Real-IP  $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_pass https://github.com/moonbingbing/openresty-best-practices/blob/master/README.md;
        }
    }
}

成功啟動(dòng) Nginx 后,我們打開瀏覽器,驗(yàn)證下反向代理的效果。在瀏覽器地址欄中輸入 ?localhost/README.md?,返回的結(jié)果是我們 GitHub 源代碼的 README 頁(yè)面。如下圖:

proxy_example

我們只需要配置一下 ?nginx.conf? 文件,不用寫任何 web 頁(yè)面,就可以偷偷地從別的服務(wù)器上讀取一個(gè)頁(yè)面返回給用戶。

下面我們來(lái)看一下? nginx.conf ?里用到的配置項(xiàng):

(1) location

location 項(xiàng)對(duì)請(qǐng)求 URI 進(jìn)行匹配,location 后面配置了匹配規(guī)則。例如上面的例子中,如果請(qǐng)求的 URI 是 ?localhost/?,則會(huì)匹配 ?location / ?這一項(xiàng);如果請(qǐng)求的 URI 是 ?localhost/README.md?,則會(huì)匹配 ?location /README.md ?這項(xiàng)。

上面這個(gè)例子只是針對(duì)一個(gè)確定的 URI 做了反向代理,有的讀者會(huì)有疑惑:如果對(duì)每個(gè)頁(yè)面都進(jìn)行這樣的配置,那將會(huì)大量重復(fù),能否做 批量 配置呢?此時(shí)需要配合使用 location 的正則匹配功能。具體實(shí)現(xiàn)方法可參考 Nginx 文檔中 關(guān)于 location 的描述。

(2) proxy_pass

proxy_pass 后面跟著一個(gè) URL,用來(lái)將請(qǐng)求反向代理到 URL 參數(shù)指定的服務(wù)器上。例如我們上面例子中的 ?proxy_pass https://github.com?,則將匹配的請(qǐng)求反向代理到 ?https://github.com?。

(3) proxy_set_header

默認(rèn)情況下,反向代理不會(huì)轉(zhuǎn)發(fā)原始請(qǐng)求中的 Host 頭部,如果需要轉(zhuǎn)發(fā),就需要加上這句:?proxy_set_header Host $host;?

除了上面提到的常用配置項(xiàng),還有 ?proxy_redirect?、?proxy_set_body?、?proxy_limit_rate ?等參數(shù),具體用法可以到Nginx 官網(wǎng)查看。

正向代理

既然有反向代理,自然也有正向代理。簡(jiǎn)單來(lái)說(shuō),正向代理就像一個(gè)跳板,例如一個(gè)用戶訪問(wèn)不了某網(wǎng)站(例如 ?www.google.com?),但是他能訪問(wèn)一個(gè)代理服務(wù)器,這個(gè)代理服務(wù)器能訪問(wèn) ?www.google.com?,于是用戶可以先連上代理服務(wù)器,告訴它需要訪問(wèn)的內(nèi)容,代理服務(wù)器去取回來(lái)返回給用戶。例如一些常見的翻墻工具、游戲代理就是利用正向代理的原理工作的,我們需要在這些正向代理工具上配置服務(wù)器的 IP 地址等信息。


以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)