Nginx+lua实现灰度发布

之前简单写过缓存预热加上二级缓存,感觉还挺好玩的,在b站看到nginx的视频,也调用lua的模块,做了灰度发布,自己做了几个小时,结果最后失败了,可能是虚拟机的原因,nginx那台经常登不上,下面就是它的主要流程。

Nginx调用Lua指令

Nginx调用Lua模块指令, Nginx的可插拔模块加载执行, 共11个处理阶段

语法
set_by_lua set_by_lua_file 设置Nginx变量,可以实现负载的赋值逻辑
access_by_lua access_by_lua_file 请求访问阶段处理, 用于访问控制
content_by_lua content_by_lua_file 内容处理器, 接受请求处理并输出响应
变量
ngx.var nginx变量
ngx.req.get_headers 获取请求头
ngx.req.get_uri_args 获取url请求参数
ngx.redirect 重定向
ngx.print 输出响应内容体
ngx.say 输出响应内容体,最后输出一个换行符
ngx.header 输出响应头

Nginx+Lua实现代码灰度发布

使用Nginx结合lua实现代码灰度发布

按照一定的关系区别,分不分的代码进行上线,使代码的发布能平滑过渡上线

1.用户的信息cookie等信息区别
2.根据用户的ip地址, 颗粒度更广

实践架构图

执行过程:

  • 1.用户请求到达前端代理Nginx, 内嵌的lua模块会解析Nginx配置文件中Lua脚本
  • 2.Lua脚本会获取客户端IP地址,查看Memcached缓存中是否存在该键值
  • 3.如果存在则执行@java_test,否则执行@java_prod
  • 4.如果是@java_test, 那么location会将请求转发至新版代码的集群组
  • 5.如果是@java_prod, 那么location会将请求转发至原始版代码集群组
  • 6.最后整个过程执行后结束

实践环境准备:

系统 服务 地址
CentOS7 Nginx+Lua+Memached 192.168.1.109
CentOS7 Tomcat集群8080_Prod 192.168.1.145
CentOS7 Tomcat集群9090_Test 192.168.1.144

1.安装两台服务器Tomcat,分别启动80809090端口

[root@tomcat-node1-20 ~]# yum install java -y
[root@tomcat-node1-20 ~]# mkdir /soft/src -p
[root@tomcat-node1-20 ~]# cd /soft/src
[root@nginx ~]# wget http://mirrors.tuna.tsinghua.edu.cn/apache/tomcat/tomcat-9/v9.0.7/bin/apache-tomcat-9.0.7.tar.gz
[root@tomcat-node1-20 src]# tar xf apache-tomcat-9.0.7.tar.gz  -C /soft
[root@tomcat-node1-20 soft]# cp -r apache-tomcat-9.0.7/ tomcat-8080
[root@tomcat-node1-20 bin]# /soft/tomcat-8080/bin/startup.sh
//注意tomcat默认监听在8080端口, 如果需要启动9090端口需要修改server.xml配置文件

2.配置Memcached并让其支持Lua调用

//安装memcached服务
[root@Nginx-Lua ~]# yum install memcached -y

//配置memcached支持lua
[root@Nginx-Lua ~]# cd /soft/src
[root@Nginx-Lua ~]# wget https://github.com/agentzh/lua-resty-memcached/archive/v0.11.tar.gz
[root@Nginx-Lua ~]# tar xf v0.11.tar.gz
[root@Nginx-Lua ~]# cp -r lua-resty-memcached-0.11/lib/resty/memcached.lua /etc/nginx/lua/

//启动memcached
[root@Nginx-Lua ~]# systemctl start memcached
[root@Nginx-Lua ~]# systemctl enable memcached

3.配置负载均衡调度

#必须在http层
lua_package_path "/etc/nginx/lua/memcached.lua";
upstream java_prod {
        server 192.168.1.145:8080;
}

upstream java_test {
        server 192.168.1.144:9090;
}

server {
        listen 80;
        server_name 192.168.1.109;


        location /hello {
                default_type 'text/plain';
                content_by_lua 'ngx.say("hello ,lua scripts")';
        }

        location /myip {
                default_type 'text/plain';
                content_by_lua '
                        clientIP = ngx.req.get_headers()["x_forwarded_for"]
                        ngx.say("Forwarded_IP:",clientIP)
                        if clientIP == nli then
                                clientIP = ngx.var.remote_addr
                                ngx.say("Remote_IP:",clientIP)
                        end
                        ';
        }
        location / {
                default_type 'text/plain';
                content_by_lua_file /etc/nginx/lua/dep.lua;
        }
       location @java_prod {
                proxy_pass http://java_prod;
                include proxy_params;
        }

        location @java_test {
                proxy_pass http://java_test;
                include proxy_params;
        }
}


//nginx反向代理tomcat,必须配置头部信息否则返回400错误
[root@nginx-lua conf.d]# cat ../proxy_params 
proxy_redirect default;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

proxy_connect_timeout 30;
proxy_send_timeout 60;
proxy_read_timeout 60;

proxy_buffer_size 32k;
proxy_buffering on;
proxy_buffers 4 128k;
proxy_busy_buffers_size 256k;
proxy_max_temp_file_size 256k;

4.编写Nginx调用灰度发布Lua脚本

[root@nginx ~]# cat /etc/nginx/lua/dep.lua 
--获取x-real-ip
clientIP = ngx.req.get_headers()["X-Real-IP"]

--如果IP为空-取x_forwarded_for
if clientIP == nil then
    clientIP = ngx.req.get_headers()["x_forwarded_for"]
end

--如果IP为空-取remote_addr
if clientIP == nil then
     clientIP = ngx.var.remote_addr
end

--定义本地,加载memcached
    local memcached = require "resty.memcached"
--实例化对象
    local memc, err = memcached:new()
--判断连接是否存在错误
    if not memc then
        ngx.say("failed to instantiate memc: ", err)
        return
    end
--建立memcache连接
    local ok, err = memc:connect("127.0.0.1", 11211)
--无法连接往前端抛出错误信息
    if not ok then
        ngx.say("failed to connect: ", err)
        return
    end
--获取对象中的ip-存在值赋给res
    local res, flags, err = memc:get(clientIP)
--
 --ngx.say("value key: ",res,clientIP)
    if err then
        ngx.say("failed to get clientIP ", err)
        return
    end
--如果值为1则调用local-@java_test
    if res == "1" then
        ngx.exec("@java_test")
        return
    end
--否则调用local-@java_prod
        ngx.exec("@java_prod")
        return

5.使用Memcache set IP, 测试灰度发布

//telnet传入值
[root@nginx conf.d]# telnet 127.0.0.1 11211
# set对应IP
set 211.161.160.201 0 0 1
# 输入1
1
posted @ 2020-11-27 14:07  天宇轩-王  阅读(1243)  评论(0编辑  收藏  举报