前言

Nginx相关技术短信本篇幅不做详细介绍,所以学习本文之前要对Nginx有相关的了解。

生产环境即线上环境,在经历开发、测试再到上线,不可避免的会更新生产环境,但谁又能保证测试过的代码到线上运行就一定不会有问题?

相信大部人都有相似经历,测试环境好好的代码,上了生产却可能发生问题,为何呢?

因为环境不一样,最经常发生的情况可能是:新的迭代中数据库表结构发生了变化、数据初始化不一致、配置文件不一致。

要如何避免这种情况呢,那就引入灰度模式,简单的说来就是模拟线上环境,即准生产环境,配置一致、数据一致,然后再看有没有问题,如果一切正常则上线,此时能kill掉99%可能出现的BUG(另外1%可能是硬件或网络问题,情况极少)。

其实灰度模式不止这个好处,下面简单列举一下:

1、做为内测环境,先对内部开放,功能是否达到预期要求,而不是上线让用户当小白鼠。

2、做为备份环境,因为灰度的数据跟线上是一模一样,旦生产发生故障,可快速切换为灰度,保证有足够的反应时间来修复生产。

3、作为负载均衡环境,当流量高峰时,可适当引流入灰度,以减轻生产压力。

实现步骤

一、配置结构

Nginx的配置文件为:nginx.conf,这是主配置,我们另外新建二个配置文件:

这二个文件其实是对nginx.conf的延伸,在nginx.conf中include进来的,放在与nginx.conf同级的目录下即可。

它们主要定义一些全局变量,就是规则定义,一般情况下用到grey_cond.rules就可以了,如果配合项目管理工具(如jenkins发布),需要手动控制灰度规则,那么grey_cond_set.rules就起作用了。

下面是这二个文件与nginx.conf的关系配置,我直接贴配置代码:

http {

sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048; include /etc/nginx/mime.types;
default_type application/octet-stream; log_format access '$proxy_add_x_forwarded_for $remote_user [$time_local] "$request" '
'$status $body_bytes_sent $request_time "$http_referer" '
'"$http_user_agent" '
'upsteam: $upstream_addr';
access_log /data/log/nginx/access.log access;
error_log /data/log/nginx/error.log; gzip on;
gzip_http_version 1.0;
gzip_disable "msie6"; gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript; include /etc/nginx/grey_cond.rules;
include /etc/nginx/grey_cond_set.rules;
include /etc/nginx/sites-enabled/*;
}

其中include /etc/nginx/sites-enabled/*;这是真正的业务规则,后面细说。

注意:这里的顺序要保证灰度规则文件在业务规则之前,而且grey_cond.rules要在grey_cond_set.rules之前(保证手动控制能生效)。

简单的描述为:全局规则--->手动规则--->业务规则。业务规则可覆盖手动规则,手动规则可覆盖全局规则,我们真正要实现的是业务规则,这样的顺序可以带来规则变化上的灵活性。

二、定制灰度规则

无外乎几种情况:

1、根据请求IP制定规则,如内部用户访问灰度,外部用户访问生产

2、根据特殊请求路径制定规则,如一个新功能上线,需要走灰度

3、根据客户端制定规则,如ios还是android

其他更多规则视具体情况而定。以下是本机示例:

root@m1:/etc/nginx# cat grey_cond.rules
set $grey_cond 0; if ($http_x_forwarded_for = 115.228.193.20){
set $grey_cond 1;
}
if ($http_user_agent ~ "AppVersion/5.0"){
set $grey_cond 1;
} if ($http_x_forwarded_for = 124.95.61.78){
set $grey_cond 1;
}
if ($http_x_forwarded_for = 134.188.193.83){
set $grey_cond 1;
set $sns_grey_cond 1;
set $rocket_grey_cond 1;
} if ($http_x_forwarded_for = 221.76.138.142){
set $grey_cond 1;
set $sns_grey_cond 1;
set $rocket_grey_cond 1;
} if ($http_user_agent ~ "Android"){
set $grey_cond 1;
}
....

上面示例代码中给了部分规则,如按IP地址(一般是公司内部的公网IP地址,如有多个配置多行即可)。

三、定制动控制规则

grey_cond_set.rules初始化可以是空,你可以把它理解成为一个临时性的文件,在需要时往里面写入一段nginx文本。

根据上段介绍,这个文件中的变量是可以向上覆盖的,你可以手动编辑这个文件,或者通过jenkins执行命令写入,然后然后配合nginx reload来做文章。

本机示例:

1、初始状态 (可空)

root@m1:/etc/nginx# cat grey_cond_set.rules
#Default beta testing policy.

2、通过jenkins写入

这个jenkins配置中,有一行脚本变量 为:-PpolicyFile=grey_cond_set.rules,正是我们说的那个临时文件,下面还有一行变量是要写入这个临时文件中的:-PpolicyString="set $grey_cond 1;",

如果对jenkins不熟悉,可适当去了解一下,本文不做详情介绍。

那么这个执行是怎么进行的呢,就是通过/var/lib/jenkins/buildscripts/build.gradle这个构建脚本来执行其中的deployPolicy方法,下面直接贴示例代码:

[root@jenkins buildscripts]# cat build.gradle
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'org.hidetake:gradle-ssh-plugin:1.1.4'
}
} apply plugin: 'org.hidetake.ssh' ssh.settings {
logging = 'stdout'
} remotes {
javaServer {
host = remoteHost
user = remoteUser
password = remotePassword
knownHosts = allowAnyHosts
} nginxServer {
host = remoteHost
user = remoteUser
password = remotePassword
knownHosts = allowAnyHosts
} nodeJsServer {
host = remoteHost
user = remoteUser
password = remotePassword
knownHosts = allowAnyHosts
}
} ..... task deployPolicy {
def policyFile = project.properties['policyFile']
doLast{
ssh.run {
session(remotes.nginxServer) {
if(project.hasProperty('policyString')) {
println "policy applied: '$policyString'"
executeSudo("echo '$policyString' > /etc/nginx/$policyFile", pty: true)
executeSudo("service nginx reload", pty: true)
}
}
}
}
} .....

这个脚本中标红的部分为核心,policyFile与policyString就是在jenkins中传进来的,下面二行executeSudo就是执行linux下的二个命令,一个是写入我们上面说到的临时文件,一个是重新加载nginx配置。

四、常用规则

10%的灰度:
-PpolicyString="if ($http_x_forwarded_for ~ 0$){set $grey_cond 1;}"   
50度灰:
-PpolicyString="if ($http_x_forwarded_for ~ [0,1,2,3,4]$){set $grey_cond 1;}"   //这是一个正则匹配,ip以0,1,2,3,4结尾的就跳灰度
纯灰:
-PpolicyString="set $grey_cond 1;"
纯生产:
-PpolicyString="#Defaultbeta testing policy." //可以是空,也可以是一个注释性文本

  

更多待续...

Nginx 灰度实现方式(支持纯灰度,纯生产,50度灰及更多比例配置)的更多相关文章

  1. nginx的upstream目前支持5种方式的分配(转)

    nginx的upstream目前支持5种方式的分配 1.轮询(默认) 每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down掉,能自动剔除. 2.weight 指定轮询几率,weight ...

  2. nginx的upstream目前支持5种方式的分配

    Nginx   nginx的upstream目前支持5种方式的分配 FROM: 转载 1 轮询(默认) 每个请求按时间顺序逐一分配到不同的后端服务器, 如果后端服务器down掉, 能自动剔除. 2 w ...

  3. NGINX Plus 现在完全支持 HTTP/2

    早些时候,我们发布了支持 HTTP/2 协议的 NGINX Plus R7.作为 HTTP 协议的最新标准,HTTP/2 的设计为现在的 web 应用程序带来了更高的性能和安全性.(LCTT 译注: ...

  4. IIS tomcat共用80端口解决一个IP多个域名:使用Nginx反向代理方式使两者兼容

    环境: windows server 2003,IIS6服务器,Tomcat7服务器 域名有几个: 以下是使用IIS的域名: http://www.formuch.com/ http://www.fo ...

  5. nginx安装及配置支持php的教程(全)

    本文的实验环境为:Centos4.5,nginx版本为:nginx-0.7.26   pcre-7.8.tar.gz  正则表达式下载地址:ftp://ftp.csx.cam.ac.uk/pub/so ...

  6. Nginx以服务方式启动并用定时任务每天备份日志

    1.安装Nginx以服务方式启动: a.下载 instsrv.exe.srvany.exe 以管理员方式启动CMD执行以下命令: instsrv Nginx D:\nginx\srvany.exe b ...

  7. (转)IIS tomcat共用80端口解决一个IP多个域名:使用Nginx反向代理方式使两者兼容

    from :http://www.cnblogs.com/wuyou/p/3455619.html 环境: windows server 2003,IIS6服务器,Tomcat7服务器 域名有几个: ...

  8. nginx配置反向代理支持session

    Nginx反向代理tomcat,很是方便,但是也有些细节的问题需要注意:今天遇到了这样一个问题,tomcat中路径“host/web1”,nginx中直接“host/”代理,这时候session就无法 ...

  9. [日志分析]Graylog2采集Nginx日志 被动方式

    graylog可以通过两种方式采集nginx日志,一种是通过Graylog Collector Sidecar进行采集(主动方式),另外是通过修改nginx配置文件的方式进行收集(被动方式). 这次说 ...

随机推荐

  1. 在Ubuntu中添加和删除PPA的软件源

    PPA,英文全称为 Personal Package Archives,即个人软件包档案.是 Ubuntu Launchpad 网站提供的一项源服务,允许个人用户上传软件源代码,通过 Launchpa ...

  2. Bazel构建工具的安装

    官方Doc:https://docs.bazel.build/versions/master/install-ubuntu.html 使用Bazel定制的APT存储库 (recommended) 1. ...

  3. bit 32/64

    [asm]64位编译32位汇编需要注意的   汇编语言在32位和64位下有区别    32位的汇编在代码前增加.code32    as可以通过--32指定生成32位汇编 在64位系统下ld链接生成3 ...

  4. 【linux & &&命令】&后台(并行)命令 &&串行命令

    & 放在一个命令末尾,可以将这个命令放到后台执行.放到后台后主进程将继续向下执行,后台命令将与主进程并行执行. &&  放在一个命令末尾,与什么都没有单纯换行实际效果相同,等待 ...

  5. function $(id) {}表示什么函数

    function $(id) {}表示什么函数 一.总结 1.就是简写,不然每次打document.getElementById很烦 二.问题 function $(id) {return docum ...

  6. adb server version (31) doesn't match this client (36)

    运行adb 命令的时候报错: C:\Users\Administrator>adb devices List of devices attachedadb server version (31) ...

  7. for练习相关

    for嵌套: 大圈套小圈思想:有一种重复的情况而这种情况每一次对应另外情况多次. ------------------------------------------------------- 例如: ...

  8. Python自动发邮件-yagmail库

    之前写过用标准库使用Python Smtplib和email发送邮件,感觉很繁琐,久了不用之后便忘记了.前几天看知乎哪些Python库让你相见恨晚?,看到了yagmail第三方库,学习过程中遇到一些问 ...

  9. POJ:2049Finding Nemo(bfs+优先队列)

    http://poj.org/problem?id=2049 Description Nemo is a naughty boy. One day he went into the deep sea ...

  10. [LeetCode] 437. Path Sum III_ Easy tag: DFS

    You are given a binary tree in which each node contains an integer value. Find the number of paths t ...