【最佳实践】利用OpenNJet实现灰度发布

在应用的新版本测试发布过程中,经常需要先使用部分选定的账号进行验证,待验证完成后,再逐步将业务流量切换到新版本,直至所有流量均切换到新的集群。

测试账号的检测可以使用多种方式,如通过Header中字段,Cookie中的值,或者URL 中的参数等方式。

在之后章节的配置及场景中,将使用HTTP Header中的staffid 字段做为测试账号的判断依据,7xxxx 的账号将被认定为测试工号。

初始静态配置

初始配置中,将设置两组upstream: backendA , backendB , 并通过split_clients 指令设置使用header中的staffid值做为流量配比依据,并设置100%的流量将指向后端 backendA

 split_clients $http_staffid $backend {
     100%    backendA;
     *       backendB;
   }

完整配置如下:

njet.conf
worker_processes auto;
cluster_name app1;
node_name node1;

error_log logs/error.log info;
load_module modules/njt_http_split_clients_2_module.so;
load_module modules/njt_http_dyn_bwlist_module.so;
load_module modules/njt_http_lua_module.so;
load_module modules/njt_dyn_ssl_module.so;
load_module modules/njt_agent_dynlog_module.so;  
load_module modules/njt_http_location_module.so;
helper ctrl modules/njt_helper_ctrl_module.so njet_ctrl.conf;
helper broker modules/njt_helper_broker_module.so ;

events {
    worker_connections  1024;
}

http {
   split_clients $http_staffid $backend {
     100%    backendA;
     *       backendB;
   }

   upstream backendA {
     server 192.168.1.4:18081;
   } 
   upstream backendB {
     server 192.168.2.4:18081;
   } 

   server {
       listen      18080 ssl; 
       ssl_certificate     cert/server.crt;  
       ssl_certificate_key  cert/server.key; 
       server_name www.test.com;
   
       location / {
         proxy_pass http://${backend};
       }
   }
}
njet_ctrl.conf
load_module modules/njt_http_sendmsg_module.so;
load_module modules/njt_ctrl_config_api_module.so; 
load_module modules/njt_helper_health_check_module.so;
load_module modules/njt_http_upstream_api_module.so; 
load_module modules/njt_http_location_api_module.so;
load_module modules/njt_doc_module.so;
load_module modules/njt_http_vtsd_module.so;

error_log logs/error_ctrl.log error;

events {
    worker_connections  1024;
}
http {
    include mime.types;
    access_log off;
    server {
        listen       8081;
        location / {
            return 200 "njet control panel\n";
        }
        location /hc {
            health_check_api;
        }
        location /api {
             api write=on;
        }
        location /kv {
            dyn_sendmsg_kv;
        }
        location /config {
            config_api;
        } 
        location /doc {
            doc_api;
        }
        location /dyn_loc {
           dyn_location_api;
        }  
        location /metrics {
            vhost_traffic_status_display;
            vhost_traffic_status_display_format html;
        }
    }
}

灰度发布步骤

​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​动态添加location

当新版本已经部署到backendB 集群后, 通过动态location提供的API 添加一个条件location, location 中设置所有的 7xxxx 测试工号将访问到 backendBNjet 提供的条件表达式中,可以使用$http_* 获取到请求header 中的值, $http_staffid  ~* "7.*" 表达式将匹配所有headerstaffid 7xxxx 的请求。

使用测试工号测试

通过上一个步骤添加条件location 后, 所有非 7xxxx 的工号将继续访问到集群 backendA, 所有 7xxxx 做为测试工号,将访问到集群backendB

​​​​​​​删除表达式location

当测试完成后,可以使用动态API 删除条件location

删除条件location后,所有的流量均指向backendA, 包括 7xxxx 的测试工号。

​​​​​​​逐步调整分流比例直至100%

使用模块提供的动态配置API 逐步调整分流比例。

如调整到 5050 的比例时:

最后调整到 0100 的比例, 所有的流量将指向 backendB

这时,应用的新版本已经完成部署和切换 (A => B ), 当下一个版本发布时,可以使用相同的步骤,完成 (B => A) 的切换。 


OpenNJet 最早是基于 NGINX1.19 基础 fork 并独立演进,随着 NGINX 版本迭代,吸收上游 NGINX 的更新,已经同步更新到 NGINX1.23.1 版本,OpenNJet 具有高性能、稳定、易扩展的特点,同时也解决了 NGINX 长期存在的难于动态配置、管理功能影响业务等问题。

作为底层引擎,OpenNJet 利用动态加载机制可以实现不同的产品形态,如API网关、消息代理、出入向代理,负载均衡,WAF等等。在云原生架构中,OpenNJet 除了提供南北向通信网关的功能以外,还提供了服务网格中东西向通信、透明流量劫持、熔断、遥测与故障注入等新功能特性。

传送门:https://gitee.com/njet-rd

RustDesk 1.2:采用 Flutter 重写桌面版本,支持 Wayland 被控 GPT-4 模型架构泄露:包含 1.8 万亿参数、采用混合专家模型 (MoE) 马斯克宣布成立 xAI 公司 deepin V23 成功适配 WSL CentOS 项目宣称“向所有人开放” Rust 1.71.0 稳定版发布 React 正在经历 Angular.js 的时刻吗? 微软推出新的默认字体 Aptos,替代 Calibri 微软:加大力度在 Windows 11 使用 Rust IntelliJ IDEA 2023.1.4 发布
{{o.name}}
{{m.name}}

猜你喜欢

转载自my.oschina.net/u/6606114/blog/10089167