Nginx + Lua + Memcache基于IP实现灰度发布_根据ip地址进行灰度发布的方法-程序员宅基地

技术标签: Nginx  Lua  Memcache  

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

在这里插入图片描述

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_31725371/article/details/85226056

智能推荐

C/C++ 高速路口计费系统_c++高速公路自动收费系统源码-程序员宅基地

文章浏览阅读822次,点赞4次,收藏4次。部分代码:如需完整代码,请私聊。_c++高速公路自动收费系统源码

大数据如何为教育添“智慧”?-程序员宅基地

文章浏览阅读79次。在一部手机上可实时了解全市所有交通信息、通过在线教育可实现“无纸课堂”、借助“云端”可享个性化健康服务……这些看似极具智慧的场景,通过大数据开放应用,“十三五”期间或可覆盖至所有中山市民。教育 建大数据库令教学更智慧一个长着方形显示器的脑袋、有着柱形身子的机器人,在宽敞的教室里移来移去。你叫一声“老师”,它就会走到你跟前;如果你将英文单词读错,它也会..._如何进行教育数据汇聚

4.6.6类和对象-继承-同名静态成员处理_c#类中有与类同名的静态成员-程序员宅基地

文章浏览阅读79次。类和对象_c#类中有与类同名的静态成员

常见的 JavaScript 内存泄露-程序员宅基地

文章浏览阅读147次。内存泄漏:由于疏忽或错误造成程序未能释放已经不再使用的内存。内存泄漏并非指内存在物理上的消失,而是应用程序分配某段内存后,由于设计错误,导致在释放该段内存之前就失去了对该段内存的控制,从而造成了内存的浪费。1、意外的全局变量js对未声明变量会在全局最高对象上创建它的引用,(是以属性存在的,而不是变量),如果在游览器上就是window对象,如果在node环境下就是global;如果未声明的变..._javascript内存泄露

Python学习笔记——removebg库之抠图-程序员宅基地

文章浏览阅读2.8k次。1.搜索remove.bghttps://www.remove.bg/2.翻译(网站翻译或者谷歌翻译)首页底端3.登陆账号(没注册注册)4.获取密钥4.14.24.34.44.55、查看API5.15.2跳转到GitHubhttps://github.com/brilam/remove-..._removebg

如何在获取全部数据后通过js纯前端实现分页效果_纯js前端实现分页代码-程序员宅基地

文章浏览阅读9.3k次,点赞4次,收藏36次。之前一直使用前后端配合的方式实现分页效果,即在后台将数据进行分页处理,前端向后端发送页数参数,单独的请求某一页的数据。目前在数据量不是很大的基础上要实现js纯前端分页,找了几个插件没有很好的解决方案,最后参照网络博客使用js实现。说明:在调研过程中参考了一位大神的博客,但是忘记了博客链接,部分代码直接来自于该博客。_纯js前端实现分页代码

随便推点

大数据毕设分享 python图像检索系统设计与实现-程序员宅基地

文章浏览阅读698次,点赞30次,收藏18次。 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。为了大家能够顺利以及最少的精力通过毕设,学长分享优质毕业设计项目,今天要分享的是python图像检索系统设计与实现学长这里给一个题目综合评分(每项满分5分)难度系数:3分工作量:3分创新点:4分图像检索:是从一堆图片中找到与待匹配的图像相似的图片,就是以图找图。

Linux kernel mmc 框架说明,包括mmc_test使用方法_linux kernel mmc测试-程序员宅基地

文章浏览阅读9k次,点赞7次,收藏38次。本章基于Linux kernel 4.4.20,从总线角度分析了Linux mmc 的框架,因为在多个地方看到求教mmc_test使用方法,在此附上了mmc_test 的使用说明。_linux kernel mmc测试

原因的原因不是原因,结果的结果不是结果-程序员宅基地

文章浏览阅读1.4k次。点击“技术领导力”关注∆每天早上8:30推送来源:孤独大脑一人生难料,世事无常,大多是“原因”和“结果”之间的纠缠。故事A某地空气极好,但是当地死于呼吸系统疾病的患者数量,却名列全国..._原因的原因不是原因

mysql openrowset_SQL的OPENROWSET开启和使用方法-程序员宅基地

文章浏览阅读470次。1、开始—>所有程序—>MicrosoftSQLServer2005—>配置工具—>SQLServer外围应用配置器—>功能的外围应用配置器—>实例名—>DatabaseEngine—>即席远程查询—>启用OpenRowset和OpenDatasource支持。2.代码启用启用:execsp_con..._mysql openrowset

css3的attr函数使用,加载unicode矢量图标_svg图片的unicode-程序员宅基地

文章浏览阅读824次。加载阿里矢量图标除了使用class与svg,我们也可以使用attr加载使用unicodecss3函数var,calc,attr的使用使用css的attr特性简单实现计数器的效果本文示例code example[4]最近找到一个VUE的文档,它将VUE的各个知识点进行了总结,整理成了《Vue 开发必须知道的36个技巧》。内容比较详实,对各个知识点的讲解也十分到位。_svg图片的unicode

ESP32 Arduino 怎么上传烧录程序_esp32每次烧录都要按boot-程序员宅基地

文章浏览阅读5.4k次,点赞7次,收藏18次。今天买了块esp32版,买回来后,按着官方提供的视频去安装好 arduino,结果烧录上去,一直提示connecting中,第一反应,是不是版子坏了?去联系了某宝客服,由于时间太晚,客服爱回不回的样子。那只能去官方交流群问问了,结果也是好久才有人回答。群友的回答是:用g0口接地,后来下载成功了。高兴的在群里发了一个红包。这个就和node mcu,stm32版子有所不同了,这些版子boot都默认用跳线帮接地了。接着我百度了一下,有三种方法下载1、用g0口接地。2、下载时,一直按_esp32每次烧录都要按boot