Nginx+Lua 實現灰度發佈

灰度發佈,灰度發佈(又名金絲雀發佈)是指在黑與白之間,能夠平滑過渡的一種發佈方式。在其上可以進行A/B testing,即讓一部分用戶繼續用產品特性A,一部分用戶開始用產品特性B,如果用戶對B沒有什麼反對意見,那麼逐步擴大範圍,把所有用戶都遷移到B上面來。灰度發佈可以保證整體系統的穩定,在初始灰度的時候就可以發現、調整問題,以保證其影響度。

Nginx+Lua 實現灰度發佈


一、概念

灰度發佈概念

按照一定的關係區分,分不分的代碼進行上線,使代碼的發佈能平滑過渡上線

△使用用戶的信息cookie等信息區別

△根據用戶的ip地址區分 (本次使用ip地址區分)

灰度發佈(又名金絲雀發佈)是指在黑與白之間,能夠平滑過渡的一種發佈方式。在其上可以進行A/B testing,即讓一部分用戶繼續用產品特性A,一部分用戶開始用產品特性B,如果用戶對B沒有什麼反對意見,那麼逐步擴大範圍,把所有用戶都遷移到B上面來。灰度發佈可以保證整體系統的穩定,在初始灰度的時候就可以發現、調整問題,以保證其影響度。

灰度期:灰度發佈開始到結束期間的這一段時間,稱為灰度期。

這裡用於WEB系統新代碼的測試發佈,讓一部分(IP)用戶訪問新版本,一部分用戶仍然訪問正常版本,其原理如圖:

Nginx+Lua 實現灰度發佈

二、環境準備

2.1 安裝LUA環境及相關庫

模塊目錄全部放在/opt/下

<code>#安裝LuaJITwget -P /opt/ http://down.i4t.com/LuaJIT-2.0.5.tar.gztar xf LuaJIT-2.0.5.tar.gzcd LuaJIT-2.0.5make && make installecho "export LUAJIT_LIB=/usr/local/lib" >>/etc/profileecho "export LUAJIT_INC=/usr/local/include/luajit-2.0" >>/etc/profilesource /etc/profile/<code>

ngx_devel_kit和lua-nginx-module都是lua需要的模塊

<code>#下載ngx_devel_kit模塊wget -P /opt/ http://down.i4t.com/ngx_devel_kit-0.3.0.tar.gztar xf ngx_devel_kit-0.3.0.tar.gz#下載lua-nginx-module模塊wget -P /opt/ http://down.i4t.com/lua-nginx-module-0.10.13.tar.gztar xf lua-nginx-module-0.10.13.tar.gz/<code>

還需要安裝redis2-nginx-module模塊

redis2-nginx-module 是一個支持 Redis 2.0 協議的 Nginx upstream 模塊,它可以讓 Nginx 以非阻塞方式直接防問遠方的 Redis 服務,同時支持 TCP 協議和 Unix Domain Socket 模式,並且可以啟用強大的 Redis 連接池功能

<code>wget -P /opt/ http://down.i4t.com/redis2-nginx-module-0.15.tar.gztar xf redis2-nginx-module-0.15.tar.gz/<code>

接下來就是安裝Nginx了,版本我們採用目前穩定版1.14

<code>#下載nginxwget -P /opt/ http://down.i4t.com/nginx-1.14.2.tar.gztar xf  nginx-1.14.2.tar.gz/<code>

現在進行編譯安裝nginx

<code>1.安裝依賴包yum install -y gcc glibc gcc-c++ prce-devel openssl-devel pcre-devel lua-devel libxml2 libxml2-devel libxslt-devel  perl-ExtUtils-Embed   GeoIP GeoIP-devel GeoIP-data zlib zlib-devel openssl  pcre pcre-devel gcc g++ gcc-c++ gd-devel2.創建用戶useradd -s /sbin/nologin nginx -M3.編譯安裝nginxcd /opt/nginx-1.14.2./configure --prefix=/usr/local/nginx-1.14.2 \\--user=nginx --group=nginx --with-http_ssl_module \\--with-http_stub_status_module \\--add-module=/opt/lua-nginx-module-0.10.13 \\--add-module=/opt/ngx_devel_kit-0.3.0 \\--add-module=/opt/redis2-nginx-module-0.15#必須按照我的版本來,否則會出現問題make && make install#設置軟連ln -s /usr/local/nginx-1.14.2 /usr/local/nginx#設置模塊,否則nginx -t報錯ln -s /usr/local/lib/libluajit-5.1.so.2 /lib64/libluajit-5.1.so.2錯誤提示如下:/usr/local/nginx/sbin/nginx -t/usr/local/nginx/sbin/nginx: error while loading shared libraries: libluajit-5.1.so.2: cannot open shared object file: No such file or directory/<code>

三、Nginx配置Lua

在nginx編譯之後,我們需要先檢查一下lua是否安裝成功

1.首先檢查nginx服務是否正常

Nginx+Lua 實現灰度發佈

2.驗證lua模塊是否成功

<code>location /test {       default_type 'text/plain';       content_by_lua 'ngx.say("test")'; }/<code>

3.reload nginx檢查是否正常

<code>[root@abcdocker ~]# vim /usr/local/nginx/conf/nginx.conf[root@abcdocker ~]# /usr/local/nginx/sbin/nginx  -tnginx: the configuration file /usr/local/nginx-1.14.2/conf/nginx.conf syntax is oknginx: configuration file /usr/local/nginx-1.14.2/conf/nginx.conf test is successful[root@abcdocker ~]# /usr/local/nginx/sbin/nginx  -s reload[root@abcdocker ~]# curl 127.0.0.1/testtest/<code>

當訪問/test時返回值也為test代表沒有問題,也可以在瀏覽器訪問

Nginx+Lua 實現灰度發佈

四、安裝redis

<code>#yum安裝yum install epel-releaseyum repolistyum install redis -y#修改redis ipsed -i 's/127.0.0.1/0.0.0.0/g' /etc/redis.conf#啟動服務service redis start[root@abcdocker logs]# ps -ef|grep redisredis    24334     1  1 05:04 ?        00:00:00 /usr/bin/redis-server 10.4.82.138:6379root     24349 14935  0 05:04 pts/0    00:00:00 grep --color=auto redis#檢查Telnet是否正常[root@abcdocker logs]# telnet 10.4.82.138 6379Trying 10.4.82.138...Connected to 10.4.82.138.Escape character is '^]'./<code> 

編譯安裝:https://i4t.com/2796.html

五、接下來修改Nginx配置文件,引用lua腳本

1.下載加載lua庫的redis腳本文件

<code>cd /optgit clone https://github.com/openresty/lua-resty-redis.gitcd lua-resty-redis/make && make install#當make完畢之後會生成我們的路徑,複製相關路徑就可以ll /usr/local/lib/lua/resty/redis.lua/<code>

2.創建lua腳本

<code>#創建lua目錄mkdir /usr/local/nginx/conf/lua#腳本內容如下cat > /usr/local/nginx/conf/lua/abcdocker.lua <<eoflocal>/<code>

2.修改nginx.conf,引用redis.lua腳本

<code>cat /usr/local/nginx/conf/nginx.conf user  nginx;worker_processes  1;events {    worker_connections  1024;}http {    include       mime.types;    default_type  application/octet-stream;    sendfile        on;    keepalive_timeout  65;    lua_package_path  "/usr/local/lib/lua/resty/redis.lua";    lua_shared_dict ip_blacklist 1m;    server {        listen       80;        server_name  localhost;        location / {        lua_code_cache off;        proxy_set_header   Host             $host;        proxy_set_header   X-Real-IP        $remote_addr;        proxy_set_header  X-Forwarded-For  $proxy_add_x_forwarded_for;        content_by_lua_file "/usr/local/nginx/conf/lua/script/redis.lua";        }        location @prod1 {                 proxy_pass  http://10.4.82.140:8080;               }        location @prod2 {                 proxy_pass  http://10.4.82.138:8080;             }  }}#在http標籤添加lua變量及i4t.conf#lua_package_path  "/usr/local/lib/lua/resty/redis.lua";#lua腳本路徑#lua_shared_dict ip_blacklist 1m; 共享內存區域始終由當前nginx服務器實例中的所有nginx工作進程共享#content_by_lua_file 自定義lua腳本路徑#lua_code_cache  nginx配置中將lua_code_cache配置成on/off來控制是否關閉lua 的cache緩存,如果設置為off.則每次修改lua腳本都會重新加載新的lua代碼,從而實現快速調試響應。同時狀態為off時啟動或重啟nginx都會提示:nginx: [alert] lua_code_cache is off; this will hurt performance in /path/to/nginx.conf。因為這會影響nginx性能表現。一般開發調試的時候使用off, 線上運行時設置為on。#localtion @prod1代表環境1#localtion @prod2代表環境2#更多變量地址:https://github.com/openresty/lua-nginx-module/<code>

啟動

<code>$ /usr/local/nginx/sbin/nginx -tnginx: [alert] lua_code_cache is off; this will hurt performance in /usr/local/nginx-1.14.2/conf/nginx.conf:22nginx: the configuration file /usr/local/nginx-1.14.2/conf/nginx.conf syntax is oknginx: configuration file /usr/local/nginx-1.14.2/conf/nginx.conf test is successful#這裡的警告可以忽略,是由於lua_code_cache為off影響的/<code>

接下來就是部署2臺tomcat

10.4.82.138 8080

10.4.82.140 8080

我這裡就不寫安裝了,不會的可以參考下面文檔

企業必會tomcat https://i4t.com/2514.html

Nginx+Lua 實現灰度發佈

當我們默認訪問的時候,不修改redis參數,不加任何變量訪問的是prod2環境

默認訪問如下圖

Nginx+Lua 實現灰度發佈

接下來我們進入到redis裡面,讓我們這個ip訪問成prod1環境

這裡的腳本邏輯解釋如下

redis Key 為0 訪問Pord1

redis Key 為空 訪問Pord2

redis Key 為1 訪問Pord2

Nginx+Lua 實現灰度發佈

我們修改過nginx之後再次訪問10.4.82.138 項目就變為tomcat代碼了

Nginx+Lua 實現灰度發佈

Lua腳本可以進行自定義,我這裡只是簡單的實現,後期會考慮使用cookie實現~



分享到:


相關文章: