nginx基于cookie针对同一域名进行分流转发

1,说明。

很多时候,测试环境可能会有好多套环境,这个时候,如果每套都配置一个对应的域名,会非常麻烦,但是很多时候针对这个问题似乎又没有特别好的方案,新公司新气象,学到新的思路是在 NGINX 层面基于 cookie 来进行不同环境的分流转发,今天就来做一下这个实验。

2,环境准备。

因为在新环境,还没有个人自用的测试服务器,Mac 当中做实验又不习惯,于是只能通过 docker 来进行了。

所以需要先安装 docker 环境,这个就不在这里赘述了。

那么,docker 环境准备完毕之后,就可以开始实验了,所谓,docker 在手,天下我有。

3,思路说明。

首先跑两个 NGINX 的容器,访问之后会返回不同的结果,然后前端再添加一层 NGINX,代理所有的外部请求,根据 cookie 的不同,分发到不同的后端容器去。

4,开始操作。

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

4.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

4.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 的匹配上

5.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

5.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

5.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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

CN-FuWei

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值