轉載:http://www.eryajf.net/3103.html
最新瞭解到的姿勢,結合着新接觸Mac電腦,第一次做實驗,學習之後,特別記錄一下。
1,說明。
很多時候,測試環境可能會有好多套環境,這個時候,如果每套都配置一個對應的域名,會非常麻煩,但是很多時候針對這個問題似乎又沒有特別好的方案,新公司新氣象,學到新的思路是在NGINX層面基於cookie來進行不同環境的分流轉發,今天就來做一下這個實驗。
2,環境準備。
因爲在新環境,還沒有個人自用的測試服務器,Mac當中做實驗又不習慣,於是只能通過docker來進行了。
所以需要先安裝docker環境,這個就不在這裏贅述了。
那麼,docker環境準備完畢之後,就可以開始實驗了,所謂,docker在手,天下我有。
3,思路說明。
首先跑兩個NGINX的容器,訪問之後會返回不同的結果,然後前端再添加一層NGINX,代理所有的外部請求,根據cookie的不同,分發到不同的後端容器去。
4,開始操作。
1,先啓兩個後端容器。
準備工作:
$ mkdir -p /Users/liqilong/docker/nginx
$ cd /Users/liqilong/docker/nginx
$ mkdir test1 test2
$ echo test1 > test1/index.html
$ echo test2 > test2/index.html
啓動容器:
$ docker pull daocloud.io/library/nginx:1.15.9-alpine-perl
$ docker run --name test1 -v /Users/liqilong/docker/nginx/test1:/usr/share/nginx/html:ro -d -p 8080:80 daocloud.io/library/nginx:1.15.9-alpine-perl
$ docker run --name test2 -v /Users/liqilong/docker/nginx/test2:/usr/share/nginx/html:ro -d -p 8081:80 daocloud.io/library/nginx:1.15.9-alpine-perl
訪問驗證:
$ ifconfig en0
en0: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
ether 18:65:90:cc:52:a5
inet6 fe80::1cf4:9734:2fa8:8234%en0 prefixlen 64 secured scopeid 0x5
inet 172.16.29.170 netmask 0xfffffc00 broadcast 172.16.31.255
nd6 options=201<PERFORMNUD,DAD>
media: autoselect
status: active
$ curl 172.16.29.170:8080
test1
$ curl 172.16.29.170:8081
test2
2,再啓動一個前端NGINX。
因爲要做一些相對的配置工作,我這裏就用了自己配置的centos鏡像來做了,事實上仍舊可以利用剛剛那個NGINX鏡像來做接下來的實驗。
$ docker pull registry.cn-hangzhou.aliyuncs.com/eryajf/centos:7.4
$ docker run -itd --name eryajf registry.cn-hangzhou.aliyuncs.com/eryajf/centos:7.4
接下來的操作就是進入此容器內部進行了。
$ docker exec -it eryajf sh
sh-4.2# yum localinstall http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm
sh-4.2# yum -y install nginx
添加如下NGINX配置:
cat >> /etc/nginx/conf.d/test.conf << EOF
upstream test01 { #此處可以單獨寫,也可以寫在下邊map的內容中
server 172.16.29.170:8080 weight=1 max_fails=1 fail_timeout=30s;
}
upstream test02 {
server 172.16.29.170:8081 weight=1 max_fails=1 fail_timeout=30s;
}
upstream root {
server 172.16.29.170:8080 weight=1 max_fails=1 fail_timeout=30s;
}
map $COOKIE_testenv $group { #$COOKIE_testenv的前半部分$COOKIE_是固定格式,後邊的testenv則是cookie的key,$group是別名
test1 test01; #表示cookie的value=test1,則轉發給test1
test2 test02;
default root;
}
server {
listen 81;
server_name localhost;
access_log logs/access_log;
error_log logs/error_log;
location / {
proxy_pass http://$group$request_uri; #注意此處url的拼接
proxy_set_header X-Forwarded-For $remote_addr;
}
}
EOF
然後啓動NGINX:
nginx -t
nginx
3,訪問測試。
這個時候可以通過命令行來模擬請求,然後查看效果。
sh-4.2# curl localhost:81
test1
sh-4.2# curl localhost:81 --cookie "testenv=test1"
test1
sh-4.2# curl localhost:81 --cookie "testenv=test2"
test2
此處只要是有一個cookie名稱與內容是符合nginx定義的規則的,那麼如上規則就是成立的。
sh-4.2# curl localhost:81 --cookie "testenv=test1;user=root;pass=123"
test1
sh-4.2# curl localhost:81 --cookie "testenv=test2;user=root;pass=123"
test2
5,其他方面。
另外除了上邊的比較固定的方式之外,還有比較靈活的控制方案,主要集中在url的匹配上。
1,匹配結尾關鍵字。
需求就是匹配到cookie的指定結尾進行分流轉發。NGINX配置如下:
map $COOKIE_testenv $group {
~*1$ 172.16.29.170:8080;
~*2$ 172.16.29.170:8081;
default 172.16.29.170:8080;
}
server {
listen 81;
server_name localhost;
access_log logs/access_log;
error_log logs/error_log;
location / {
proxy_pass http://$group$request_uri;
proxy_set_header X-Forwarded-For $remote_addr;
}
}
然後重新加載NGINX配置,請求一下驗證效果:
sh-4.2# curl localhost:81 --cookie "testenv=dfhg;user=root;pass=123"
test1
sh-4.2# curl localhost:81 --cookie "testenv=dfhg1;user=root;pass=123"
test1
sh-4.2# curl localhost:81 --cookie "testenv=dfhg2;user=root;pass=123"
test2
2,匹配開頭關鍵字。
與上邊的道理是一致的,只不過配置內容更改一下即可。
map $COOKIE_testenv $group {
~*^1 172.16.29.170:8080;
~*^2 172.16.29.170:8081;
default 172.16.29.170:8080;
}
server {
listen 81;
server_name localhost;
access_log logs/access_log;
error_log logs/error_log;
location / {
proxy_pass http://$group$request_uri;
proxy_set_header X-Forwarded-For $remote_addr;
}
}
然後請求一下,驗證一下效果:
sh-4.2# curl localhost:81 --cookie "testenv=dfhg;user=root;pass=123"
test1
sh-4.2# curl localhost:81 --cookie "testenv=1dfhg;user=root;pass=123"
test1
sh-4.2# curl localhost:81 --cookie "testenv=2dfhg;user=root;pass=123"
test2
3,匹配包含關鍵字。
還有一種比較靈活的策略,就是隻要包含指定的關鍵字標識,就往不同的後端進行分流轉發,配置如下:
map $COOKIE_testenv $group {
~*.*eryajf1.* 172.16.29.170:8080;
~*.*eryajf2.* 172.16.29.170:8081;
default 172.16.29.170:8080;
}
server {
listen 81;
server_name localhost;
access_log logs/access_log;
error_log logs/error_log;
location / {
proxy_pass http://$group$request_uri;
proxy_set_header X-Forwarded-For $remote_addr;
}
}
然後請求一下,驗證一下效果:
sh-4.2# curl localhost:81 --cookie "testenv=A3fklj;user=root;pass=123"
test1
sh-4.2# curl localhost:81 --cookie "testenv=A3fkeryajf1lj;user=root;pass=123"
test1
sh-4.2# curl localhost:81 --cookie "testenv=A3fkeryajf2lj;user=root;pass=123"
test2