灰度发布方案

一、灰度发布定义

灰度发布(又名金丝雀发布)是指在黑与白之间,能够平滑过渡的一种发布方式。在其上可以进行A/B testing,即让一部分用户继续用产品特性A,一部分用户开始用产品特性B,如果用户对B没有什么反对意见,那么逐步扩大范围,把所有用户都迁移到B 上面来。灰度发布可以保证整体系统的稳定,在初始灰度的时候就可以发现、调整问题,以保证其影响度。

二、实现思路方向

1、在代码中做。

一套线上环境,代码中做开关,对于不同的用户走不同的逻辑

2、在接入层做。

多套(隔离的)线上环境,接入层针对不同用户转发到不同的环境中

两种方案的优缺点:

方案

优点

缺点

在代码中做

灵活,粒度细;一套代码(环境)运维成本低

灰度逻辑侵入代码

在接入层做

无需(少)侵入代码;风险小

多套线上环境,运维成本高

灵活的灰度方案一般需要在接入层实现,具体就是自定义负载均衡策略实现。

下面介绍在接入层使用的方式,第一是在nginx层实现(使用ngx+lua),第二是在网关层实现(spring-cloud-zuul)。

第三是dubbo的灰度,项目中如果使用dubbo,有可能会需要dubbo服务的灰度实现。

负载均衡又可分为服务端负载均衡和客户端负载均衡

服务器端负载均衡:例如Nginx,通过Nginx进行负载均衡,先发送请求,然后通过负载均衡算法,在多个服务器之间选择一个进行访问;即在服务器端再进行负载均衡算法分配。

客户端负载均衡:例如ribbon或者dubbo,客户端会有一个服务器地址列表,在发送请求前通过负载均衡算法选择一个服务器,然后进行访问,这是客户端负载均衡;即在客户端就进行负载均衡算法分配。

三、nginx灰度方案说明

Nginx是一款轻量级的Web服务器/反向代理服务器以及电子邮件代理服务器。

nginx.conf

负载均衡策略:轮询(默认)、weight、ip_hash、fair(响应时间)、url_hash

简单的根据cookie进行灰度

Openresty

Nginx有很多的特性和好处,但是在Nginx上开发成了一个难题,Nginx模块需要用C开发,而且必须符合一系列复杂的规则,最重要的用C开发模块 必须要熟悉Nginx的源代码,使得开发者对其望而生畏。为了开发人员方便,所以接下来我们要介绍一种整合了Nginx和lua的框架,那就是OpenResty。

OpenResty® 是一个基于 Nginx 与 Lua 的高性能 Web 平台,其内部集成了大量精良的 Lua 库、第三方模块以及大多数的依赖项。用于方便地搭建能够处理超高并发、扩展性极高的动态 Web 应用、Web 服务和动态网关。

Openresty学习地址:https://moonbingbing.gitbooks.io/openresty-best-practices/content/base/intro.html

新浪微博开源项目

git地址:https://github.com/CNSRE/ABTestingGateway

ABTestingGateway是一个可以动态设置分流策略的灰度发布系统,工作在7层,基于nginx和ngx-lua开发,使用 redis 作为分流策略数据库,可以实现动态调度功能。

ABTestingGateway是在 nginx 转发的框架内,在转向 upstream 前,根据 用户请求特征 和 系统的分流策略 ,查找出目标upstream,进而实现分流。

nginx实现的灰度系统中,分流逻辑往往通过 rewrite 阶段的 if 和rewrite 指令等实现,优点是性能较高,缺点是功能受限容易出错,以及转发规则固定,只能静态分流。针对这些缺点, ABTestingGateway,采用ngx-lua 实现系统功能,通过启用lua-shared-dict和lua-resty-lock作为系统缓存和缓存锁,系统获得了较为接近原生nginx转发的性能。

架构图:

特性:

实现原理:在代理转发前,使用rewrite_by_lua_file模块重写到目标upstream

diversion.lua逻辑:

例:略

四、dubbo灰度方案说明

Dubbo架构

Dubbo服务调用过程

Loadbalance(负载均衡)说明

在集群负载均衡时,Dubbo 提供了多种均衡策略,缺省为 random 随机调用

负载均衡策略Random(随机)、RoundRobin(轮询)、LeastActive(最小活跃调用数)、ConsistentHash(一致性Hash)

负载均衡配置:

自定义负载均衡实现:

例:

实现LoadBalance接口,或者继承AbstractLoadBalance 重写策略;

根据dubbo SPI发现机制,还需要在resources下添加META-INF/dubbo/com.alibaba.dubbo.rpc.cluster.LoadBalance

demo逻辑:目标服务的端口和灰度服务端口的一致,并且请求方法的第一个参数类型是Long(userId)并且是灰度用户,则判断为灰度服务,否则按照默认随机调用其余非灰度服务

四、springCloud灰度方案说明

Ribbon 提供了几个负载均衡的组件,其目的就是让请求转给合适的服务器处理

默认轮询

自定义策略需要继承AbstractLoadBalancerRule

开源方案:

自定义DiscoveryEnabledRule继承PredicateBaseRule

首先在请求开始处,实现自己的灰度逻辑,比如下面的demo根据请求url如果包含‘version’向holder中添加route为A的标识,否则添加route为B的标识。 (Holder本质是一个localThread)

在目标服务添加matadateMap

PredicateBaseRule中使用google提供的pridicate,MetadataAwarePredicate中实现apply方法判断发现的服务是否是目标服务

原文发布于微信公众号 - Linyb极客之路(gh_c420b2cf6b47)

原文发表时间:2018-07-28

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏数据和云

ASM的备份解析与恢复

编辑说明:《Oracle性能优化与诊断案例精选》出版以来,收到很多读者的来信和评论,我们会通过连载的形式将书中内容公布出来,希望书中内容能够帮助到更多的读者朋友...

3356
来自专栏腾讯移动品质中心TMQ的专栏

GT3.1简化您的App性能测试(2)——原理讲解,溯本求源

GT3.1的版本更新,带来了全面的维度分析。那么这些功能是如何实现的呢?本章GT君将详细的从CUP维度、内存维度、流量维度、流畅度维度为大家讲解这些功能的作用和...

5746
来自专栏IT技术精选文摘

缓存更新的套路

看到好些人在写更新缓存数据代码时,先删除缓存,然后再更新数据库,而后续的操作会把数据再装载的缓存中。然而,这个是逻辑是错误的。试想,两个并发操作,一个是更新操作...

4137
来自专栏Java架构沉思录

深入浅出Unix IO模型

在介绍Unix IO模型之前,我们先来说说什么是IO。根据维基百科的定义,IO的指的是输入输出,通常指数据在内部存储器和外部存储器或其他周边设备之间的输入和输出...

1132
来自专栏漫漫全栈路

ASP.NET MVC学习笔记01初始

技术栈跳来跳去,最后还是选择回归最初。从Asp.Net的WebFrom到PHP到Python的Django,最后还时回到了最熟悉的.net平台。三层之前只做过...

3706
来自专栏数据和云

深入内核:从Oracle ASM自动备份头块到ASMFD

张乐奕 云和恩墨副总经理 Oracle ACE 总监 ITPUB Oracle数据库管理版版主、Oracle高可用版版主、ACOUG联合创始人 在 Oracle...

3278
来自专栏杨海春的专栏

常用机器性能评估工具

软件系统跑在机器上,处理能力受硬件制约,所以,单机处理能力会有上限。评估机器处理能力的上限,检查程序的瓶颈在哪,有助于程序性能分析。主要的几大硬件:CPU、内存...

6540
来自专栏数据和云

【视频】In Memory的内部结构和实现机制

小编寄语 罗马不是一日建成的。新特性5分钟系列视频,带你循序渐进学习Oracle12.2的最新特性,相约成长的路上,不见不散! { 本期话题 } In ...

3326
来自专栏Java后端技术

你误解了Windows的文件后缀名吗?

  有很多的小伙伴对windows下的文件后缀名不能很好地理解作用和区别,更不用说高深的使用了,在这里给大家说一下这些文件后缀名到底有什么区别,有什么作用呢?

981
来自专栏Java架构沉思录

深入浅出Unix IO模型

前言 在介绍Unix IO模型之前,我们先来说说什么是IO。根据维基百科的定义,IO 指的是输入输出,通常指数据在内部存储器和外部存储器或其他周边设备之间的输入...

4517

扫码关注云+社区

领取腾讯云代金券