Gitlib Gitlib
首页
  • 分类
  • 标签
  • 归档
  • Golang开发实践万字总结
  • MySQL核心知识汇总
  • Redis实践总结
  • MQ实践万字总结
  • Docker数据持久化总结
  • Docker网络模式深度解读
  • 常用游戏反外挂技术总结
  • 读书笔记
  • 心情杂货
  • 行业杂谈
  • 友情链接
关于我
GitHub (opens new window)

Ravior

以梦为马,莫负韶华
首页
  • 分类
  • 标签
  • 归档
  • Golang开发实践万字总结
  • MySQL核心知识汇总
  • Redis实践总结
  • MQ实践万字总结
  • Docker数据持久化总结
  • Docker网络模式深度解读
  • 常用游戏反外挂技术总结
  • 读书笔记
  • 心情杂货
  • 行业杂谈
  • 友情链接
关于我
GitHub (opens new window)
  • 操作系统

  • 计算机网络

  • 数据结构和算法

  • MySQL

  • Redis

  • Nginx

    • Nginx入门之安装部署
    • Nginx高级用法总结
    • Nginx使用常见问题汇总
    • Nginx与HAProxy负载均衡比较
    • Nginx status状态详解
    • Nginx常见问题之Location优先级
    • Nginx+Keepalived搭建高可用集群
    • Nginx实战灰度发布
      • 灰度发布类型
      • 实践
    • 常见负载均衡算法
  • MongoDB

  • 其他

  • 计算机基础
  • Nginx
Ravior
2017-03-20
目录

Nginx实战灰度发布

灰度发布,就是根据各种条件,让一部分用户使用旧版本,另一部分用户使用新版本,而并不是直接将所有流量切过来,测试人员对新版本做运行状态观察,收集各种运行时数据,也就是所谓的A/B测试,如果没有问题,那么可以将少量的用户流量导入到新版本上,将负面影响控制在最小范围内。

# 灰度发布类型

依据实现终端不同,我认为灰度发布可以分为两类:

  • 客户端灰度:客户端依据特殊条件,例如用户ID/IP等条件实现分流
  • 服务端灰度:依托Web服务器反向代理或者编码,对不同IP/用户ID等条件实现分流

# 实践

这里我们主要讨论服务段灰度发布,我们依托Openresty(Nginx+Lua)+Redis来实现灰度发布,原理如下图:

灰度发布

执行过程:

  1. 当用户请求到达前端web(代理)服务器Openresty,内嵌的lua模块解析Nginx配置文件中的lua脚本代码;
  2. Lua获取客户端IP地址,去查询Redis中是否有该键值,如果有返回值执行@clien2,否则执行@client1;
  3. Location @client2把请求转发给预发布服务器,location @client1把请求转发给生产服务器,服务器返回结果,整个过程完成;

Openresty配置如下:

upstream client1 { 
    server 127.0.0.1:8080;  #模拟生产服务器
}
upstream client2 {
    server 127.0.0.1:8090;  #模拟预发布服务器
}

server {
    listen       80;
    server_name  localhost;
    
    location ^~ /test {
        content_by_lua_file ab.lua
    }
    
    location @client1{
            proxy_pass http://client1;
    }
    location @client2{
            proxy_pass http://client2;
    }
 }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

ab.lua代码实现如下:

local redis = require "resty.redis" 
local cache = redis.new() 
cache:set_timeout(60000)

local ok, err = cache.connect(cache, '127.0.0.1', 6379) 
if not ok then 
    ngx.say("failed to connect:", err) 
    return 
end 


local local_ip = ngx.req.get_headers()["X-Real-IP"]
if local_ip == nil then
    local_ip = ngx.req.get_headers()["x_forwarded_for"]
end

if local_ip == nil then
    local_ip = ngx.var.remote_addr
end
--ngx.say("local_ip is : ", local_ip)

local intercept = cache:get(local_ip) 


if intercept == local_ip then
    ngx.exec("@client2")
    return
end

ngx.exec("@client1")

local ok, err = cache:close() 
 
if not ok then 
    ngx.say("failed to close:", err) 
    return 
end
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37

到此最基本的灰度发布已经实现,如果要做更细粒度灰度发布可参考新浪开源的一个动态路由系统考ABTestingGateway项目。ABTestingGateway是一个可以动态设置分流策略的灰度发布系统,工作在7层,基于nginx和ngx-lua开发,使用redis作为分流策略数据库,可以实现动态调度功能。

ABTestingGateway:https://github.com/CNSRE/ABTestingGateway

#Nginx
上次更新: 2022/12/01, 11:09:34
Nginx+Keepalived搭建高可用集群
常见负载均衡算法

← Nginx+Keepalived搭建高可用集群 常见负载均衡算法→

最近更新
01
常用游戏反外挂技术总结
11-27
02
Golang开发实践万字总结
11-11
03
Redis万字总结
10-30
更多文章>
Theme by Vdoing | Copyright © 2011-2022 Ravior | 粤ICP备17060229号-3 | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式