匿名
未登录
登录
Linux78|wiki
搜索
查看“Openresty+redis实现灰度发布”的源代码
来自Linux78|wiki
名字空间
页面
讨论
更多
更多
页面选项
查看
查看源代码
历史
←
Openresty+redis实现灰度发布
因为以下原因,您没有权限编辑本页:
您所请求的操作仅限于该用户组的用户使用:
wiki:用户|用户
您可以查看与复制此页面的源代码。
使用nginx+lua+redis 灰度发布方案。nginx+lua实现反向代理,获取客户端ip;redis存放ip信息(ip为访问微服务允许的地址)。 有两种方案可以实现 第一种:nginx+lua获取用户ip,然后再用lua编写程序直接访问redis 集群,查询ip信息返回结果; 第二种:nginx+lua获取用户ip,然后用lua编写程序用http请求到redis缓存服务(单独微服务),缓存服务返回ip地址; 开始是考虑第一种方案,因为openresty没有太好的redis cluster的支持包,资料少;如果用第二种方案redis缓存服务可以单独拎出来,不但可以为nginx使用,还可以为其他服务所用。 两种方案都会说下,不过第一种方案用的是单机redis 假设都有了OpenResty和redis环境 ==== 第一种方案 ==== 在nginx.conf http块中添加代码 //外部配置 include lua.conf; //新系统地址 upstream new{ server 192.168.1.103:8081; } //老系统地址 upstream old{ server 192.168.1.103:8080; } lua.conf 代码 //nginx的server配置 server { listen 80; server_name _; location /lua { //redis lua 脚本 content_by_lua_file conf/redistest.lua; default_type 'text/html'; } //代理到新服务 location @new{ proxy_pass http://new; } //代理到原来服务 location @old{ proxy_pass http://old; } } redistest.lua脚本 //引入redis模块,只能联单机 local redis = require "resty.redis" local cache = redis.new() cache:set_timeout(60000) //链接 local ok, err = cache.connect(cache, '192.168.19.10', 6379) //这里如果链接redis失败,则转发到@old对应的服务器(传统服务) if not ok then ngx.exec("@old") return end //如果nginx只有一层分发层,这下面这四行代码可以不写 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 //从remote_addr变量中拿到客户端ip,同样nginx只有一层的时候此变量为客户端ip,多层不是 if local_ip == nil then local_ip = ngx.var.remote_addr end //在redis中根据客户端ip获取是否存在值;redis中存放的是key:ip val:ip,存放的ip访问微服务 local intercept = cache:get(local_ip) //如果存在则转发到@new对应的服务器(微服务) if intercept == local_ip then ngx.exec("@new") return end //如果不存在,则转发到@old对应的服务器(传统服务) ngx.exec("@old") //关闭客户端 local ok, err = cache:close() if not ok then ngx.say("failed to close:", err) return end 逻辑较简单,但是有些问题1:redis集群要配置多ip,防止宕机问题 2:链接问题,如果有线程池最好了。这里不再多说 ==== 第二种方案 ==== nginx.conf不变 lua.conf 中的redistest.lua 改为httptest.lua httptest.lua代码如下 //这是缓存服务地址 backend = "http://192.168.1.156:8080" //缓存服务访问路径 local method="httptest" local requestBody = "/"..method //模块 local http = require("resty.http") local httpc = http.new() //设置超时时间 httpc:set_timeout(1000) //发送请求 local resp, err = httpc:request_uri(backend, {-- method = "GET",-- path = requestBody, keepalive=false }) //如果请求失败访问老系统 if not resp then-- ngx.exec("@old")---- return-- end //缓存服务取回ip local isHave=resp.body //关闭连接 httpc:close() //请求ip local local_ip = ngx.var.remote_addr //命中则访问微服务 if isHave == local_ip then ngx.exec("@new") return end //没命中访问老系统 ngx.exec("@old") 这里的缓存地址只有一个,实际中有多个,可以采用随机取值去访问一个。超时时间一定要设置,如果缓存系统一直没响应或者缓存服务宕机则直接访问老系统。 例子中在缓存服务中只是存储了真实ip,实际中是存储的IP网段,nginx拿到真实ip字符拆分然后去匹配的。 这里有两点优化没有写出1:http可以用连接池代替 2:可以在nginx内部使用缓存,把命中的ip都存起来,再有链接可以先走本地缓存,再走缓存服务可以提高性能。 目前http没有找到相关连接池,所以一直在非连接池下运行,性能还可以。 另一点直接在nginx中使用了内存来进行缓存。 在nginx.conf http块中添加代码 结构为:lua_shared_dict [name] [size] lua_shared_dict rediscache 100m; 更改httptest.lua的代码如下 backend = "http://192.168.1.156:8080" //加载共享内存 local cache_ngx = ngx.shared.rediscache local local_ip=ngx.var.remote_addr /优先从本地缓存中去取 local cacheip=cache_ngx:get(local_ip) //本地缓存中不存在,去缓存服务中去取,然后加载到本地缓存 if cacheip =="" or cacheip == nil then local http = require("resty.http") local httpc = http.new() httpc:set_timeout(1000) local method="httptest" local requestBody = "/"..method local resp, err = httpc:request_uri(backend, { method = "GET", path = requestBody, keepalive=false }) if not resp then ngx.exec("@new") return end cacheip=resp.body httpc:close() //加载到本地缓存,设置过期时间 cache_ngx:set(local_ip,cacheip,10*60) end if cacheip == local_ip then ngx.exec("@new") return end ngx.exec("@old")
返回至
Openresty+redis实现灰度发布
。
导航
导航
首页
最近更改
随机页面
栏目
Nginx
Kubernetes
Spring Cloud
Wiki工具
Wiki工具
特殊页面
页面工具
页面工具
用户页面工具
更多
链入页面
相关更改
页面信息
页面日志