nginx map配置根據請求頭不一樣分配流量到不一樣後端服務

正文

最近在作一個需求開發:根據請求後的不一樣,nginx將請求分發到不一樣的後端服務;須要修改kubernetes的ingress-nginx-controller的源碼,調試的時候遇到了挺多問題,寫出來,有須要的老鐵能夠參考。具體方案就不說了,只說一下nginx配置這一塊。前端

首先貼出組件版本:ingress-nginx-controller的版本爲0.9-beta.18,能夠在github上找到開源的項目源碼:java

nginx map配置根據請求頭不一樣分配流量到不一樣後端服務nginx版本爲:nginx version: nginx/1.13.7python

map配置的一個報錯:

nginx.conf文件部分以下:nginx

http {
    
    include /etc/nginx/conf.d/server-map.d/*-map.conf;
    include /etc/nginx/conf.d/*-upstream.conf;
    include /etc/nginx/conf.d/server-map.d/*-server.conf;

    ....

    map_hash_bucket_size 64;

    ....
}複製代碼

在/etc/nginx/conf.d/server-map.d/目錄下的flow-ppp-map.conf:git

map $http_x_group_env $svc_upstream {
    default zxl-test-splitflow-old-version;
    ~*old zxl-test-splitflow-old-version;
    ~*new zxl-test-splitflow-new-version;
}複製代碼

flow-ppp-server.confgithub

server {
    listen 8998;
    server_name aa.hc.harmonycloud.cn;
    location /testdemo/test {
        proxy_pass http://$svc_upstream;
    }
}複製代碼

ingressgroup-upstream.conf面試

upstream zxl-test-splitflow-old-version {
    server 10.168.173.29:8080 max_fails=0 fail_timeout=0;
}

upstream zxl-test-splitflow-new-version {
    server 10.168.177.171:8080 max_fails=0 fail_timeout=0;
}複製代碼

當nginx -tc /etc/nginx/nginx.conf測試配置正確與否時報錯以下:正則表達式

Error: exit status 1
nginx: [emerg] "map_hash_bucket_size" directive is duplicate in /etc/nginx/nginx.conf:60
nginx: configuration file c test failed複製代碼

在這裏插入圖片描述

解決:

這是由於首次調用map時會隱式設置maphashbucketsize,即在nginx中map後寫maphashbucketsize至關於設置了兩次maphashbucket_size,如:spring

http {
    ...
    map $status $_status {
        default 42;
    }
    map_hash_bucket_size 64;
    ...
}複製代碼

所以能夠在map以前設置它,以下所示。編程

http {
    map_hash_bucket_size 64;
    ...
    map $status $_status {
        default 42;
    }
    ...
}複製代碼

因此include map配置也應該放到設置maphashbucket_size以後:

http {
    ...

    map_hash_bucket_size 64;

    ...
    
    include /etc/nginx/conf.d/server-map.d/*-map.conf;
    include /etc/nginx/conf.d/*-upstream.conf;
    include /etc/nginx/conf.d/server-map.d/*-server.conf;
}複製代碼

map配置說明:

經過上面的include三個配置文件,最終對nginx生效的配置應該是這樣的:

http {
    ...

    map_hash_bucket_size 64;

    ...
    
    map $http_x_group_env $svc_upstream {
        default zxl-test-splitflow-old-version;
        ~*old zxl-test-splitflow-old-version;
        ~*new zxl-test-splitflow-new-version;
    }
    
    
    upstream zxl-test-splitflow-old-version {
        server 10.168.173.29:8080 max_fails=0 fail_timeout=0;
    }

    upstream zxl-test-splitflow-new-version {
        server 10.168.177.171:8080 max_fails=0 fail_timeout=0;
    }
    
    server {
        listen 8998;
        server_name aa.hc.harmonycloud.cn;
        location /testdemo/test {
            proxy_pass http://$svc_upstream;
        }
    }
}複製代碼

當在電腦上hosts文件裏配置了aa.hc.harmonycloud.cn域名解析後,訪問http://aa.hc.harmonycloud.cn:8998/testdemo/test時(即server的servername和listen、location的配置),nginx將會把請求轉發到http://$svcupstream,這個$svc_upstream具體是什麼,就是經過map配置來賦值的。這裏map配置以下:

map $http_x_group_env $svc_upstream {
        default zxl-test-splitflow-old-version;
        ~*old zxl-test-splitflow-old-version;
        ~*new zxl-test-splitflow-new-version;
}複製代碼

其中$httpxgroupenv能夠是nginx內置變量,也能夠是自定義的header的key、請求參數名;$svcupstream即爲自定義變量名。這裏的配置含義爲:當請求頭裏的x-group-env的值old時,$svcupstream被賦值爲zxl-test-splitflow-old-version;當請求頭裏的x-group-env的值new時,$svcupstream被賦值爲zxl-test-splitflow-new-version;默認賦值爲zxl-test-splitflow-old-version;(其中正則表達式若是以 「~」 開頭,表示這個正則表達式對大小寫敏感。以 「~*」開頭,表示這個正則表達式對大小寫不敏感)。而zxl-test-splitflow-new-version和zxl-test-splitflow-old-version表示兩個upstream名稱。

所以nginx將會把請求轉發到http://$svcupstream,這裏的$svcupstream會被替換爲upstream的名稱,最終將獲得upstream中的後端服務IP和Port。

注意:若是咱們自定義header爲X-Real-IP,經過第二個nginx獲取該header時須要這樣:$httpxrealip; (一概採用小寫,並且前面多了個http,且中間用_替換)

測試

當請求頭裏加x-group-env爲new時,訪問後端打印出的是I am new version在這裏插入圖片描述

當請求頭裏加x-group-env爲old時,訪問後端打印出的是I am old version在這裏插入圖片描述

最終經過請求頭不一樣實現了將流量分配到不一樣的後端服務。

將請求頭的key變爲X-Group-Env,value變爲OLD或者NEW也不要緊:在這裏插入圖片描述

在這裏插入圖片描述

本公衆號免費提供csdn下載服務,海量IT學習資源,若是你準備入IT坑,勵志成爲優秀的程序猿,那麼這些資源很適合你,包括但不限於java、go、python、springcloud、elk、嵌入式 、大數據、面試資料、前端 等資源。同時咱們組建了一個技術交流羣,裏面有不少大佬,會不定時分享技術文章,若是你想來一塊兒學習提升,能夠公衆號後臺回覆【2】,免費邀請加技術交流羣互相學習提升,會不按期分享編程IT相關資源。

掃碼關注,精彩內容第一時間推給你

image

相關文章
相關標籤/搜索