国产在线观看精品免费,亚洲日本VA久久一区二区,香蕉久久99综合一区二区三区,久久精品99国产精品蜜桃小说

基于 Nginx+lua+Memcache 實(shí)現灰度發(fā)布

2021-11-04 09:23:50 shuai.chang

睿智創(chuàng  )新RAIZ,一體化IT服務(wù)提供商

一、灰度發(fā)布原理說(shuō)明

灰度發(fā)布在百度百科中解釋?zhuān)?/strong>
灰度發(fā)布是指在黑與白之間,能夠平滑過(guò)渡的一種發(fā)布方式。AB test就是一種灰度發(fā)布方式,讓一部分用戶(hù)繼續用A,一部分用戶(hù)開(kāi)始用B,如果用戶(hù)對B沒(méi)有什么反對意見(jiàn),那么逐步擴大范圍,把所有用戶(hù)都遷移到B上面 來(lái)?;叶劝l(fā)布可以保證整體系統的穩定,在初始灰度的時(shí)候就可以發(fā)現、調整問(wèn)題,以保證其影響度。
這里的用于WEB系統新代碼的測試發(fā)布,讓一部分(IP)用戶(hù)訪(fǎng)問(wèn)新版本,一部分用戶(hù)仍然訪(fǎng)問(wèn)正常版本,其原理如圖:

睿智創(chuàng  )新RAIZ,一體化IT服務(wù)提供商

執行過(guò)程:

  • 當用戶(hù)請求到達前端代理服務(wù)Nginx,內嵌的lua模塊解析Nginx配置文件中的lua腳本代碼;

  • Lua變量獲得客戶(hù)端IP地址,去查詢(xún)memcached緩存內是否有該鍵值,如果有返回值執行@client_test,否則執行@client。

  • Location @client_test把請求轉發(fā)給部署了new版代碼的服務(wù)器,location @client把請求轉發(fā)給部署了normal版代碼的服務(wù)器,服務(wù)器返回結果。整個(gè)過(guò)程完成。

下面把安裝配置過(guò)程詳細說(shuō)明。

二、安裝配置過(guò)程詳解

1、安裝nginx

安裝依賴(lài)包

yum -y install gcc gcc-c++ autoconf libjpeg libjpeg-devel libpng libpng-devel freetype freetype-devel libxml2 libxml2-devel zlib zlib-devel glibc glibc-devel glib2 glib2-devel bzip2 bzip2-devel ncurses ncurses-devel curl curl-devel e2fsprogs e2fsprogs-devel krb5 krb5-devel libidn libidn-devel openssl openssl-devel openldap openldap-devel nss_ldap openldap-clients openldap-servers make pcre-devel

yum -y install gd gd2 gd-devel gd2-devel lua lua-devel

yum –y install memcached


下載lua模塊、lua-memcache操作庫文件和nginx包

wget https://github.com/simpl/ngx_devel_kit/archive/v0.2.18.tar.gz
wget https://github.com/chaoslawful/lua-nginx-module/archive/v0.8.5.tar.gz
wget https://github.com/agentzh/lua-resty-memcached/archive/v0.11.tar.gz
wget http://nginx.org/download/nginx-1.4.2.tar.gz

#解壓編譯安裝
tar xvf nginx-1.4.2.tar.gz
cd nginx-1.4.2/
./configure \
--prefix=/soft/nginx/ \
--with-http_gzip_static_module \
--add-module=/root/ngx_devel_kit-0.2.18/ \
--add-module=/root/lua-nginx-module-0.8.5/

make&&make install

拷貝lua的memcached操作庫文件

tar xvf v0.11.tar.gz

cp -r lua-resty-memcached-0.11/lib/resty/ /usr/lib64/lua/5.1/

配置nginx

#vim /soft/nginx/conf/nginx.conf
worker_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 client {
      server  192.168.200.29:80;
  }
  upstream client_test {
      server  192.168.200.29:81;
  }

  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("@client_test")
                  return
              end
                ngx.exec("@client")           
              '
;
      }
      location @client{
          proxy_pass http://client;
      }
    location @client_test{
          proxy_pass http://client_test;
      }

  location /hello {
      default_type 'text/plain';
    content_by_lua 'ngx.say("hello, lua")';
  }

  location = /50x.html {
      root  html;
  }
  }
}

檢測配置文件。

#/soft/nginx/sbin/nginx -t

nginx: the configuration file /soft/nginx/conf/nginx.conf syntax is ok

nginx: configuration file /soft/nginx/conf/nginx.conf test is successful

啟動(dòng)nginx

/soft/nginx/sbin/nginx

啟動(dòng)memcached服務(wù)

memcached -u nobody -m 1024 -c 2048 -p 11211 –d


三、測試驗證

測試lua模塊是否運行正常
訪(fǎng)問(wèn)http://測試服務(wù)器ip地址/hello。如果顯示:hello,lua 表示安裝成功。
睿智創(chuàng  )新RAIZ,一體化IT服務(wù)提供商
在另一臺測試機(這里是192.168.200.29)設置兩個(gè)虛擬主機,一個(gè)用80端口是執行正常代碼,一個(gè)是81端口執行灰度測試代碼。
在memcached中以你的客戶(hù)機IP地址為key,value值為1。這里我的IP是192.168.68.211.
telnet localhost 11211
Trying ::1...
Connected to localhost.
Escape character is '^]'.
set 192.168.68.211 0 3600 1
1
STORED
get 192.168.68.211
VALUE 192.168.68.211 9 1
1
END
quit
注意:
set后第一個(gè)值為key值。
192.168.68.211這是key值是需要灰度測試的IP地址;
0 表示一個(gè)跟該key有關(guān)的自定義數據;
3600 表示該key值的有效時(shí)間;
1 表示key所對應的value值的字節數。
下面訪(fǎng)問(wèn)Nginx,效果符合預期,我的IP已經(jīng)在memcached中存儲值,所以請求轉發(fā)給執行灰度測試代碼的主機。

睿智創(chuàng  )新RAIZ,一體化IT服務(wù)提供商

從memcached刪除我的主機IP值。
睿智創(chuàng  )新RAIZ,一體化IT服務(wù)提供商
再次請求Nginx,請求轉發(fā)給執行正常代碼內容的主機。
睿智創(chuàng  )新RAIZ,一體化IT服務(wù)提供商
整個(gè)配置并不復雜,整個(gè)判斷過(guò)程對服務(wù)的影響非常小。如果需要使用這個(gè)系統最好自己看看lua腳本。


我要咨詢(xún)