使用Nginx+Lua实现Web项目的灰度发布Nginx编译安装Lua模块一、安装LUA环境及相关库官方网站:https://github.com/openresty/lua-nginx-module1、LuaJITwget http://luajit.org/download/LuaJIT-2.0.2.tar.gzmake && make install PREFIX=/usr/local/LuaJIT# vim /etc/profileexport LUAJIT_LIB=/usr/local/LuaJIT/libexport LUAJIT_INC=/usr/local/LuaJIT/include/luajit-2.0# source /etc/profile2、下载解压ngx_devel_kit和lua-nginx-modulecd /usr/local/srcwget https://github.com/simpl/ngx_devel_kit/archive/v0.3.0.tar.gzwget https://github.com/openresty/lua-nginx-module/archive/v0.10.9rc7.tar.gz分别解压tar xf v0.10.9rc7.tar.gz tar xf v0.3.0.tar.gz 3、重新编译编译Nginxcd /usr/local/src/wget http://nginx.org/download/nginx-1.12.1.tar.gz[root@node1 src]# tar xf nginx-1.12.1.tar.gz [root@node1 src]# cd nginx-1.12.1预编译./configure --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib64/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --user=nginx --group=nginx --with-compat --with-file-aio --with-threads --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_mp4_module --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --with-http_v2_module --with-mail --with-mail_ssl_module --with-stream --with-stream_realip_module --with-stream_ssl_module --with-stream_ssl_preread_module --with-cc-opt=‘-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -fPIC‘ --with-ld-opt=‘-Wl,-z,relro -Wl,-z,now -pie‘ --add-module=/usr/local/src/ngx_devel_kit-0.3.0 --add-module=/usr/local/src/lua-nginx-module-0.10.9rc7# 并行编译make -j 4 && make install4、加载lua库,加入到ld.so.conf文件echo "/usr/local/LuaJIT/lib"/etc/ld.so.confldconfig报错:[root@node1 nginx-1.12.1]# nginx -vnginx: error while loading shared libraries: libluajit-5.1.so.2: cannot open shared object file: No such file or directory解决:# ln -s /usr/local/LuaJIT/lib/libluajit-5.1.so /usr/lib64/libluajit-5.1.so.2二、使用Nginx+Lua实现Web项目的灰度发布灰度发布概念:按照一定的关系区别,分部分的代码进行上线,使代码的发布能平滑过渡上线1.使用用户的信息cookie等信息区别2.根据用户的ip地址区分灰度发布在百度百科中解释:灰度发布(又名金丝雀发布)是指在黑与白之间,能够平滑过渡的一种发布方式。在其上可以进行A/B testing,即让一部分用户继续用产品特性A,一部分用户开始用产品特性B,如果用户对B没有什么反对意见,那么逐步扩大范围,把所有用户都迁移到B上面来。灰度发布可以保证整体系统的稳定,在初始灰度的时候就可以发现、调整问题,以保证其影响度。灰度期:灰度发布开始到结束期间的这一段时间,称为灰度期。这里用于WEB系统新代码的测试发布,让一部分(IP)用户访问新版本,一部分用户仍然访问正常版本,其原理如图:具体实现步骤:1.部署两个tomcat实例:分别监听 8080和9090 端口tomcat8080作为灰度环境(升级以后的环境)tomcat9090作为生产环境(升级之前的环境)tomcat8080的测试页面代码:[root@node1 tomcat8080]# cat /data/tomcat8080/webapps/ROOT/java_test.jsp <%@ page language="java" import="java.util.*" pageEncoding="utf-8"%><HTML> ???<HEAD> ???????<TITLE>jsp Test Page</TITLE> ???</HEAD> ???<BODY> ???????<% ???????????Random rand = new Random(); ???????????out.println("<h1>Random number:</h1>"); ???????????out.println("<h1>gray server:</h1>"); ???????????out.println(rand.nextInt(99)+100); ???????????????????%> ???</BODY></HTML>[root@node1 tomcat8080]# cat /data/tomcat9090/webapps/ROOT/java_test.jsp <%@ page language="java" import="java.util.*" pageEncoding="utf-8"%><HTML> ???<HEAD> ???????<TITLE>jsp Test Page</TITLE> ???</HEAD> ???<BODY> ???????<% ???????????Random rand = new Random(); ???????????out.println("<h1>shengchang xianshang server</h1>"); ???????????out.println("<h1>Random number:</h1>"); ???????????out.println(rand.nextInt(99)+100); ???????????????????%> ???</BODY></HTML>测试tomcat是否部署正常
2.安装memcached[root@node1 ~]# yum install -y memcached[root@node1 conf.d]# memcached -p11211 -u nobody -d[root@node1 conf.d]# ps -ef|grep memcachednobody ???17177 ?????1 ?0 18:12 ? ???????00:00:00 memcached -p11211 -u nobody -droot ?????17213 ?17150 ?0 18:12 pts/1 ???00:00:00 grep --color=auto memcached[root@node1 conf.d]# netstat -tnlp|grep 11211tcp ???????0 ?????0 0.0.0.0:11211 ??????????0.0.0.0:* ??????????????LISTEN ?????17177/memcached ????tcp6 ??????0 ?????0 :::11211 ???????????????:::* ???????????????????LISTEN ?????17177/memcached修改nginx配置文件[root@node1 conf.d]# pwd/etc/nginx/conf.d修改nginx配置,引入lua脚本经过测试,通过命令引入脚本文件的方式测试无法通过content_by_lua_file /opt/app/dep.lua;①合并nginx写法,都写入nginx主配置文件:[root@node1 nginx]# cat nginx.confworker_processes ?1;events { ???worker_connections ?1024;}http { ???include ??????mime.types; ???default_type ?application/octet-stream; ???sendfile ???????on; ???keepalive_timeout ?65; ???proxy_next_upstream ????error timeout; ???proxy_redirect ?????????off; ???proxy_set_header ???????Host $host; ???proxy_set_header ???????X-Real-IP $http_x_forwarded_for; ???proxy_set_header ???????X-Forwarded-For $proxy_add_x_forwarded_for; ???client_max_body_size ???100m; ???client_body_buffer_size 256k; ???proxy_connect_timeout ??180; ???proxy_send_timeout ?????180; ???proxy_read_timeout ?????180; ???proxy_buffer_size ??????8k; ???proxy_buffers ??????????8 64k; ???proxy_busy_buffers_size 128k; ???proxy_temp_file_write_size 128k; ????upstream sc_server { ???????server 192.168.3.177:9090; ???} ???upstream gray_server { ???????server 192.168.3.177:8080; ???} ???lua_package_path "/usr/local/share/lua/5.1/memcached.lua"; ???server { ???????listen ??????80; ???????server_name ?localhost; ??????location / { ??????content_by_lua ‘ ???????????clientIP = ngx.req.get_headers()["X-Real-IP"] ???????????if clientIP == nil then ???????????????clientIP = ngx.req.get_headers()["x_forwarded_for"] ???????????end ???????????if clientIP == nil then ???????????????clientIP = ngx.var.remote_addr ???????????end ???????????????local memcached = require "resty.memcached" ???????????????local memc, err = memcached:new() ???????????????if not memc then ???????????????????ngx.say("failed to instantiate memc: ", err) ???????????????????return ???????????????end ???????????????local ok, err = memc:connect("127.0.0.1", 11211) ???????????????if not ok then ???????????????????ngx.say("failed to connect: ", err) ???????????????????return ???????????????end ???????????????local res, flags, err = memc:get(clientIP) ???????????????if err then ???????????????????ngx.say("failed to get clientIP ", err) ???????????????????return ???????????????end ???????????????if ?res == "1" then ???????????????????ngx.exec("@gray_server") ???????????????????return ???????????????end ????????????????ngx.exec("@sc_server") ????????????????????????????‘; ??????} ??????location @sc_server{ ??????????proxy_pass http://sc_server; ??????} ??????location @gray_server{ ??????????proxy_pass http://gray_server; ??????} ???location /hello { ???????default_type ‘text/plain‘; ???????content_by_lua ‘ngx.say("hello, lua")‘; ???} ???location /myip { ???default_type ‘text/palin‘; ???content_by_lua ‘ ???????clientIP = ngx.req.get_headers()["x_forwarded_for"] ???????if clientIP == nil then ???????????clientIP = ngx.var.remote_addr ???????end ???????????ngx.say("IP:",clientIP) ???????‘; ???} ???location = /50x.html { ???????root ??html; ???} ??}}②主配置和lua配置文件分开写主配置文件[root@node1 conf.d]# cat /etc/nginx/nginx.confuser ?nginx;worker_processes ?2;error_log ?/var/log/nginx/error.log warn;pid ???????/var/run/nginx.pid;events { ???worker_connections ?1024;}http { ???include ??????/etc/nginx/mime.types; ???default_type ?application/octet-stream; ???log_format ?main ?‘$remote_addr - $remote_user [$time_local] "$request" ‘ ?????????????????????‘$status $body_bytes_sent "$http_referer" ‘ ?????????????????????‘"$http_user_agent" "$http_x_forwarded_for" "$request_uri"‘; ???access_log ?/var/log/nginx/access.log ?main; ???sendfile ???????on; ???#tcp_nopush ????on; ???keepalive_timeout ?65; ???#gzip ?on; ???include /etc/nginx/conf.d/*.conf;}lua的配置文件[root@node1 conf.d]# cat /etc/nginx/conf.d/gray_lua.conf upstream sc_server { ???server 192.168.3.177:9090;}upstream gray_server{ ???server 192.168.3.177:8080;}lua_package_path "/usr/local/share/lua/5.1/memcached.lua"; ???server { ???????listen ??????80; ???????server_name ?localhost; ??????location / { ??????content_by_lua ‘ ???????????clientIP = ngx.req.get_headers()["X-Real-IP"] ???????????if clientIP == nil then ???????????????clientIP = ngx.req.get_headers()["x_forwarded_for"] ???????????end ???????????if clientIP == nil then ???????????????clientIP = ngx.var.remote_addr ???????????end ???????????????local memcached = require "resty.memcached" ???????????????local memc, err = memcached:new() ???????????????if not memc then ???????????????????ngx.say("failed to instantiate memc: ", err) ???????????????????return ???????????????end ???????????????local ok, err = memc:connect("127.0.0.1", 11211) ???????????????if not ok then ???????????????????ngx.say("failed to connect: ", err) ???????????????????return ???????????????end ???????????????local res, flags, err = memc:get(clientIP) ???????????????if err then ???????????????????ngx.say("failed to get clientIP ", err) ???????????????????return ???????????????end ???????????????if ?res == "1" then ???????????????????ngx.exec("@gray_server") ???????????????????return ???????????????end ????????????????ngx.exec("@sc_server") ??????????????‘; ??????} ??????location @sc_server{ ??????????proxy_pass http://sc_server; ??????} ??????location @gray_server{ ??????????proxy_pass http://gray_server; ??????} ???location /hello { ???????default_type ‘text/plain‘; ???????content_by_lua ‘ngx.say("hello, lua")‘; ???} ???location /myip { ???default_type ‘text/palin‘; ???content_by_lua ‘ ???????clientIP = ngx.req.get_headers()["x_forwarded_for"] ???????if clientIP == nil then ???????????clientIP = ngx.var.remote_addr ???????end ???????????ngx.say("IP:",clientIP) ???????‘; ???} ???error_page ??500 502 503 504 ?/50x.html; ???location = /50x.html { ???????root ??/usr/share/nginx/html; ???}}3.安装lua_memcached插件wget https://github.com/agentzh/lua-resty-memcached/archive/v0.11.tar.gztar xf v0.11.tar.gz cp -r lua-resty-memcached-0.11/lib/resty /usr/share/lua/5.1/向memcached中插入本机ip数据,作为可以访问灰度环境的IP[root@node1 conf.d]# telnet 127.0.0.1 11211Trying 127.0.0.1...Connected to 127.0.0.1.Escape character is ‘^]‘.set 192.168.3.84 0 0 11STOREDget 192.168.3.84VALUE 192.168.3.84 0 11END测试是否可以分离:不在memcached中的IP访问java_test.jsp[root@node1 tomcat8080]# ifconfig eth0eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> ?mtu 1500 ???????inet 192.168.3.177 ?netmask 255.255.255.0 ?broadcast 192.168.3.255 ???????inet6 fe80::3c78:50fd:7203:2f0e ?prefixlen 64 ?scopeid 0x20<link> ???????ether 00:50:56:3b:dc:7e ?txqueuelen 1000 ?(Ethernet) ???????RX packets 495041 ?bytes 239594322 (228.4 MiB) ???????RX errors 0 ?dropped 0 ?overruns 0 ?frame 0 ???????TX packets 54942 ?bytes 10493549 (10.0 MiB) ???????TX errors 0 ?dropped 0 overruns 0 ?carrier 0 ?collisions 0[root@node1 tomcat8080]# curl http://192.168.3.177/java_test.jsp<HTML> ???<HEAD> ???????<TITLE>jsp Test Page</TITLE> ???</HEAD> ???<BODY> ???????<h1>shengchang xianshang server</h1><h1>Random number:</h1>114 ???</BODY></HTML>在memcached环境中的IP访问:lua脚本的基础知识[root@node1 ~]# yum install -y lua基本语法:1运行方式交互模式运行:[root@node1 ~]# luaLua 5.1.4 ?Copyright (C) 1994-2008 Lua.org, PUC-Rio> print("hello lua")hello lua写入脚本运行:[root@node1 ~]# cat test.lua #!/usr/bin/luaprint("hello lua")[root@node1 ~]# lua test.lua hello lua2.注释--行注释--[[块注释--]]3.变量> a = ‘aio\n123"‘> print(a)aio123"> a="aio\n123\""> print(a)aio123"> a=‘\97io\10\04923"‘> print(a)aio123"> a=[[aio>> 123"]]> print(a)aio123"布尔类型只有nil和false是false,数字0 空字符串(‘ \0‘ )都是truelua中的变量如果没有特殊说明,全是全局变量如果是局部变量前面加Local4.循环while循环语句[root@node1 ~]# cat add.lua #!/usr/bin/luasum = 0num = 1while num <= 100 do ?sum = sum + num ?num = num + 1endprint("sum=",sum)[root@node1 ~]# lua add.lua sum= ???5050注意:lua没有++ 或者 += 这样的操作for循环[root@node1 ~]# cat for.lua #!/usr/bin/luasum = 0for i = 1,100 do ?sum = sum + iendprint("sum=",sum)[root@node1 ~]# lua for.lua sum= ???5050if-else判断语句(脚本测试不通过)if age == 40 and sex == "Male" then ?print("大于40男人")elseif age > 60 and sex ~= "Female" then ?print("非女人且大于60")else ?local age = io.read() ?print(‘your age is‘..age)end
使用Nginx+Lua实现Web项目的灰度发布
原文地址:https://www.cnblogs.com/reblue520/p/8301919.html