Nginx + Lua + Memcache基于IP实现灰度发布

  • 执行过程
    • 用户请求到达前端代理Nginx,内嵌的Lua模块会解析Nginx配置文件中的Lua脚本
    • Lua脚本会获取客户端IP地址,查看Memcache缓存中是否存在该键值
    • 如果存在则执行java-prod(旧版),否则执行java-test(新版)
    • 如果是java-test,那么location会将请求转发至新代码集群组
    • 如果是java-prod,那么location会将请求转发至旧代码集群组
系统服务地址
CentOS7.4Nginx + Lua + Memcache192.168.1.20
CentOS7.4Tomcat(集群)8080_Prod版本192.168.1.19
CentOS7.4Tomcat(集群)8081_Test版本192.168.1.21

1. 在192.168.1.19、192.168.1.21上部署Tomcat

[root@centos7u4-node1 ~]# mkdir -p /soft/app && cd /soft/app
[root@centos7u4-node1 app]# wget https://mirrors.tuna.tsinghua.edu.cn/apache/tomcat/tomcat-9/v9.0.14/bin/apache-tomcat-9.0.14.tar.gz 
[root@centos7u4-node1 app]# tar xf apache-tomcat-9.0.14.tar.gz
[root@centos7u4-node1 app]# yum install -y java

# 改Test版本Tomcat端口
[root@centos7u4-node2 /soft/app/apache-tomcat-9.0.14/conf]$ vim server.xml 
...
    <Connector port="8081" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" />

# Tomcat集群8080_Prod版本
[root@centos7u4-node1 apache-tomcat-9.0.14]# netstat -lntp |grep java
tcp6       0      0 127.0.0.1:8005          :::*                    LISTEN      1610/java           
tcp6       0      0 :::8009                 :::*                    LISTEN      1610/java           
tcp6       0      0 :::8080                 :::*                    LISTEN      1610/java           
[root@centos7u4-node1 apache-tomcat-9.0.14]# 

# Tomcat集群8081_Test版本
[root@centos7u4-node2 /soft/app/apache-tomcat-9.0.14/bin]$ ss -lntp |grep java
LISTEN     0      100         :::8009                    :::*                   users:(("java",pid=3116,fd=58))
LISTEN     0      100         :::8081                    :::*                   users:(("java",pid=3116,fd=53))
LISTEN     0      1         ::ffff:127.0.0.1:8005                    :::*                   users:(("java",pid=3116,fd=73))
[root@centos7u4-node2 /soft/app/apache-tomcat-9.0.14/bin]$ 

[root@centos7u4-node1 ROOT]# vi java.jsp
<%@page import="java.text.SimpleDateFormat"%>
<%@page import="java.util.*"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>JSP在页面显示实时时间</title>
</head>
<body>
        <%
                Date d = new Date();
                SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                String now = df.format(d);
        %>
        <h1>Tomcat 8080 - Prod - 旧版</h1>   //8081服务器上是<h1>Tomcat 8081</h1>别的都一样
        当前时间:<%=now %>
        <br>
</body>


2. 在192.168.1.20主机上配置Memcache并让其支持Lua调用

Nginx安装配置Lua支持:https://blog.csdn.net/qq_31725371/article/details/85226116

[root@nginx_lua ~]$ yum install -y memcached
[root@nginx_lua /soft/src]$ wget https://github.com/openresty/lua-resty-memcached/archive/v0.14.tar.gz
[root@nginx_lua /soft/src]$ tar xf  v0.14.tar.gz 
[root@nginx_lua /soft/src]$ mkdir /soft/nginx/conf/lua
[root@nginx_lua /soft/src]$ cp /soft/src/lua-resty-memcached-0.14/lib/resty/memcached.lua /soft/nginx/conf/lua/

# 启动Memcached,并加入开机自启
[root@nginx_lua /soft/nginx/conf/lua]$ systemctl start memcached.service 
[root@nginx_lua /soft/nginx/conf/lua]$ systemctl enable memcached.service


3. 配置Nginx

[root@nginx_lua /soft/nginx/conf/conf.d]$ vim lua.conf 

lua_package_path "/soft/nginx/conf/lua/memcached.lua";

upstream java_prod {
        server 192.168.1.19:8080;
}
upstream java_test {
        server 192.168.1.21:8081;
}

server {
        listen 80;
        server_name 192.168.1.20;
        include proxy_params;

        location /ip {
                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 /soft/nginx/conf/lua/dep.lua;
        }

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

        location @java_prod {
                proxy_pass http://java_prod;
        }


}

[root@nginx_lua /soft/nginx/conf/conf.d]$ vim ../proxy_params 
#proxy_redirect  default;
# 默认情况下,NGINX在代理请求中重新定义两个头字段“Host”和“Connection”
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_set_header  Accept-Encoding  "";

proxy_connect_timeout 30;          #nginx跟后端服务器连接超时时间(代理连接超时)
proxy_send_timeout 60;             #后端服务器数据回传时间(代理发送超时)
proxy_read_timeout 60;             #连接成功后,后端服务器响应时间(代理接收超时)
proxy_buffer_size 32k;              #设置代理服务器(nginx)保存用户头信息的缓冲区大小
proxy_buffers 4 128k;               #proxy_buffers缓冲区,网页平均在128k以下的话,这样设置
proxy_busy_buffers_size 256k;       #高负荷下缓冲大小(proxy_buffers*2)
proxy_temp_file_write_size 256k;    #设定缓存文件夹大小,大于这个值,将从upstream服务器传

client_max_body_size 10m;          #允许客户端请求的最大单文件字节数
client_body_buffer_size 128k;      #缓冲区代理缓冲用户端请求的最大字节数

[root@nginx_lua /soft/nginx/conf/conf.d]$ vim /soft/nginx/conf/lua/dep.lua
--建立memcache连接本地11211端口
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


在这里插入图片描述

4. 现在我测试一直只能访问旧版

在这里插入图片描述

5. 现在将某一定范围的ip值设置为1(比如整个杭州地市的ip导入到Memcache中),模拟灰度发布

[root@nginx_lua ~]# telnet 127.0.0.1 11211
Trying 127.0.0.1...
Connected to 127.0.0.1.
set 192.168.1.6 0 0 1
1
STORED

然后在访问同一个地址http://192.168.1.20/java.jsp得到了不同的显示了

在这里插入图片描述

# 删除这个ip有访问的是旧版的了,实现了灰度发布
[root@nginx_lua ~]# telnet 127.0.0.1 11211
Trying 127.0.0.1...
Connected to 127.0.0.1.
set 192.168.1.6 0 0 1
1
STORED
END
delete 192.168.1.6
DELETED
quit

在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值