nginx通過自定義header屬性來轉發不同的服務


一、背景

因為需要上線灰度發布,只要nginx接收到頭部為:

wx_unionid:123456

 

就會跳轉到另外一個url,比如:

127.0.0.1:8080

 

通過配置nginx 匹配請求頭wx_unionid 來轉發到灰度環境。
核心:客戶端自定義的http header,在nginx的配置文件里能直接讀取到。
條件:header必須用減號“-”分隔單詞,nginx里面會轉換為對應的下划線“_”連接的小寫單詞。

 

二、修改Nginx配置

安裝nginx

apt-get install -y nginx

 

編輯主頁

cd /etc/nginx/sites-enabled
vim home.conf

內容如下:

upstream wx {
    server 127.0.0.1:8080;
}

server {  
    listen 8008;
    server_name localhost;

    root html;
    index index.html;

    charset utf-8;
    underscores_in_headers on;
    location / {
        #測試header轉發 
        if ($http_wx_unionid = "123456") {
            proxy_pass http://wx;
        }  
    }  
} 

參數配置說明

underscores_in_headers on:nginx是支持讀取非nginx標准的用戶自定義header的,但是需要在http或者server下開啟header的下划線支持:
比如我們自定義header為wx_unionid,獲取該header時需要這樣:$http_wx_unionid(一律采用小寫,而且前面多了個http_)


如果需要把自定義header傳遞到下一個nginx:
1.如果是在nginx中自定義采用proxy_set_header X_CUSTOM_HEADER $http_host;
2.如果是在用戶請求時自定義的header,例如curl –head -H “X_CUSTOM_HEADER: foo” http://domain.com/api/test,則需要通過proxy_pass_header X_CUSTOM_HEADER來傳遞

編輯調整頁

vim wx.conf

內容如下:

server {
    listen 8080;
    server_name localhost;

    root /var/www/html;
    index wx.html;

    location / {
        try_files $uri $uri/ =404;
    }
}

 

增加測試頁面

vim /var/www/html/wx.html

內容如下:

<h1>微信小程序測試平台</h1>

 

三、測試結果

加自定義頭部

root@ubuntu:~# curl -v -H 'wx_unionid:123456' 127.0.0.1:8008
* Rebuilt URL to: 127.0.0.1:8008/
*   Trying 127.0.0.1...
* Connected to 127.0.0.1 (127.0.0.1) port 8008 (#0)
> GET / HTTP/1.1
> Host: 127.0.0.1:8008
> User-Agent: curl/7.47.0
> Accept: */*
> wx_unionid:123456
> 
< HTTP/1.1 200 OK
< Server: nginx/1.10.3 (Ubuntu)
< Date: Mon, 29 Jul 2019 07:49:46 GMT
< Content-Type: text/html; charset=utf-8
< Content-Length: 37
< Connection: keep-alive
< Last-Modified: Mon, 29 Jul 2019 06:23:49 GMT
< ETag: "5d3e90f5-25"
< Accept-Ranges: bytes
< 
<h1>微信小程序測試平台</h1>
* Connection #0 to host 127.0.0.1 left intact

 

不加頭部

root@ubuntu:~# curl -v 127.0.0.1:8008
* Rebuilt URL to: 127.0.0.1:8008/
*   Trying 127.0.0.1...
* Connected to 127.0.0.1 (127.0.0.1) port 8008 (#0)
> GET / HTTP/1.1
> Host: 127.0.0.1:8008
> User-Agent: curl/7.47.0
> Accept: */*
> 
< HTTP/1.1 200 OK
< Server: nginx/1.10.3 (Ubuntu)
< Date: Mon, 29 Jul 2019 07:50:13 GMT
< Content-Type: text/html; charset=utf-8
< Content-Length: 612
< Last-Modified: Tue, 31 Jan 2017 15:01:11 GMT
< Connection: keep-alive
< ETag: "5890a6b7-264"
< Accept-Ranges: bytes
< 
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>
* Connection #0 to host 127.0.0.1 left intact

 

四、匹配多條件

現在又多了一個需求,需要對客戶端ip為:192.168.0.45,同時也增加自定義頭部wx_unionid:123456,才會轉發,否則不做轉發。

 

nginx的配置中不支持if條件的邏輯與&& 邏輯或|| 運算 ,而且不支持if的嵌套語法,否則會報下面的錯誤:nginx: [emerg] invalid condition。

我們可以用變量的方式來間接實現。

要實現的語句:

if ($remote_addr ~* "192.168.0.45" && $http_wx_unionid = "123456"){
    proxy_pass http://wx;
}

 

如果按照這樣來配置,就會報nginx: [emerg] invalid condition錯誤。

如下:

nginx: [emerg] invalid condition "$http_wx_unionid" in /etc/nginx/sites-enabled/home.conf:16
nginx: configuration file /etc/nginx/nginx.conf test failed

 

可以這么來實現,如下所示:

upstream wx {
    server 127.0.0.1:8080;
}

server {  
    listen 8008;
    server_name localhost;

    root html;
    index index.html;

    charset utf-8;
    underscores_in_headers on;
    location / {
        #測試header轉發
        # 標志位
        set $flag 0;
        if ($remote_addr ~* "192.168.0.45"){
             # 末尾追加1,此時$flag=01
             set $flag "${flag}1";
        }
        if ($http_wx_unionid = "123456"){
            # 末尾追加1,此時$flag=011
            set $flag "${flag}1";
        }
        # 當為011時,表示條件都匹配
        if ($flag = "011") {
            proxy_pass http://wx;
        }
    }  
} 

 

重新加載配置

nginx -s reload

 

再次使用本機測試,增加頭部

root@ubuntu:~# curl -v -H 'wx_unionid:123456' 127.0.0.1:8008
* Rebuilt URL to: 127.0.0.1:8008/
*   Trying 127.0.0.1...
* Connected to 127.0.0.1 (127.0.0.1) port 8008 (#0)
> GET / HTTP/1.1
> Host: 127.0.0.1:8008
> User-Agent: curl/7.47.0
> Accept: */*
> wx_unionid:123456
> 
< HTTP/1.1 200 OK
< Server: nginx/1.10.3 (Ubuntu)
< Date: Mon, 29 Jul 2019 08:01:30 GMT
< Content-Type: text/html; charset=utf-8
< Content-Length: 612
< Last-Modified: Tue, 31 Jan 2017 15:01:11 GMT
< Connection: keep-alive
< ETag: "5890a6b7-264"
< Accept-Ranges: bytes
< 
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>
* Connection #0 to host 127.0.0.1 left intact

 

登錄到192.168.0.45,增加頭部測試

root@docker-reg:~# curl -v -H 'wx_unionid:123456' 192.168.0.162:8008
* Rebuilt URL to: 192.168.0.162:8008/
*   Trying 192.168.0.162...
* Connected to 192.168.0.162 (192.168.0.162) port 8008 (#0)
> GET / HTTP/1.1
> Host: 192.168.0.162:8008
> User-Agent: curl/7.47.0
> Accept: */*
> wx_unionid:123456
> 
< HTTP/1.1 200 OK
< Server: nginx/1.10.3 (Ubuntu)
< Date: Mon, 29 Jul 2019 08:02:01 GMT
< Content-Type: text/html; charset=utf-8
< Content-Length: 37
< Connection: keep-alive
< Last-Modified: Mon, 29 Jul 2019 06:23:49 GMT
< ETag: "5d3e90f5-25"
< Accept-Ranges: bytes
< 
<h1>微信小程序測試平台</h1>
* Connection #0 to host 192.168.0.162 left intact

 

 

 本文參考鏈接:

https://blog.csdn.net/qq_25934401/article/details/83113520

https://blog.csdn.net/lai0yuan/article/details/80784058

https://blog.csdn.net/woshizhangliang999/article/details/51701327

 



 


免責聲明!

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



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