一、概述

为了保障公司业务不受单点机房故障影响;需要做机房双活;把流量分别导向不同的IDC机房,按比例分配;方法有多种,本文所讲的就是模拟按客户端不同cookie分流实现;nginx plug+自带cookie分配,就是商业版支持,对于 大多的创业公司用的是源生的开源nginx则可以通过应用层给不同的客户端分配cookie值来导向到不同的IDC机房;这么说容易理解点;本文就是通过模拟不同的客户端cookie导向到不同的IDC机房;
架构如下:
nginx 基于cookie分流

图中的高可用负载既可以是单个机房的,也可以是多个机房的入口;下面的IDCA ,IDCB等机房,既可以是具体的web,也可以是多个机房;

功能实现:
nginx商业版自带的cookie分配默认是通过客户端携带的cookie做hash分配到各后端;这里是通过应用层给客户端分配cookie并导向到指定后端;实现过程如下:
应用程序给客户端分配生成特定cookie键值,如ickey=”yunhnagweb201801”,安全公司或高可用负载设备通过匹配cookie值,将流量分配到不同的IDC机房;键值以01结尾分配到IDCA;键值以02结尾分配到IDCB;

二、测试

本次测试由于没有应用层分配cookie,通过模拟方式进行即生成cookie是在负载设备上通过请求ip的后缀来生成cookie并将请求分配到指定web(或叫IDC)上;
测试环境:
测试所用三台主机:nginx 均是通过epel库yum安装即可!
负载设备:10.8.11.203 Centos7 nginx 1.12 域名:test.test.com
Web1(模拟IDCA): 10.8.11.144 域名:test.test.com
Web2(模拟IDCB): 10.8.11.181 域名:test.test.com
以上域名在本地和三台hosts做对应解析;
当用户访问负载设备test.test.com时 通过请求的来源ip后缀来确定流量分配到那台IDC上;

配置
入口负载设备 nginx配置

[root@10.8.11.203 conf.d]# cat test_map_cookie.conf
map $COOKIE_ickey $group {
~*[0-5]$ zone01;     #cookie 0-5结尾走zone01
~*[6-9]$ zone02;     # cookie 6-9 结尾走zone02
default root;          #默认
  }

upstream zone01

server 10.8.11.144:8080 weight=1 max_fails=1 fail_timeout=30s;
 }

upstream zone02 {
server 10.8.11.181:8080 weight=1 max_fails=1 fail_timeout=30s;
 } 

upstream root {
server 10.8.11.203:80 weight=1 max_fails=1 fail_timeout=30s;
 }

server {
add_header Set-Cookie "ickey=bqx1x3x5hhda0000000002${remote_addr}";  #模拟客户端访问时带的cookie(一般是应用层分配好)
listen 80;
server_name test.test.com;
access_log logs/access_log main;
error_log logs/error_log;

location / {
proxy_pass http://$group;
proxy_set_header X-Forwarded-For $remote_addr;
 }  
 }

这里注意的是 后端web侦听的端口不要和上层负载设备端口一样;实测中这样会行不通!

两台web配置
为了能看到来自那台web(IDC)响应,各自返回的web内容加以区别;

Web1(IDCA):

[root@test-web_redis-144 conf.d]# cat web144.conf 
server{
    listen 8080;
    server_name test.test.com;
    root /home/dongyc/web144/; 
        index index.html;   
        access_log  /var/log/nginx/test.ickey.cn_nginx.log  main;
}

查看web内容:

[root@test-web_redis-144 conf.d]# cat /home/dongyc/web144/index.html 
<h1>test web web144 form IDCA.</h1>

Web2(IDCB):

[root@test-web_redis-181 conf.d]# cat web181.conf 
server{
        listen 8080;
        server_name test.test.com;
        root /home/dongyc/web181/;
        index index.html;
        access_log  /var/log/nginx/test.ickey.cn_nginx.log  main;

}

查看web内容:

[root@test-web_redis-181 conf.d]# cat /home/dongyc/web181/index.html 
<h1>test web 181 from IDCB.</h1>

三、测试效果

由于客户端cookie模拟时以客户端ip结尾,同时 0-5结尾的分配到IDCA,6-9分配到IDCB;因此找两台ip结尾分别在以上两个区间即可看到效果,本次找的一台是65 和66结尾的客户端请求,以便 看到效果;
10.8.11.65请求:
nginx 基于cookie分流

10.8.11.66请求:
nginx 基于cookie分流

请求通过入口负载设备;通过cookie的值分配请求发往何处;此方案可行并得到验证;
线上可通过改造应用层给各客户端分配特定cookie,安全公司通过cookie按比例分配到不同IDC;并在并个IDC出现故障时;切换流量到正常IDC中!

影响:
当某IDC故障时,需要即时切换,并会丢失故障IDC登录用户的连接状态;