灰度发布怎么实现(什么是灰度用户有哪些策略)


前言

相信很多小伙伴们都听说过灰度发布,但是不一定知道如何实现?今天我们就介绍一下基本原理,以及提供代码实现给小伙伴们。

灰度概念

可用于大型应用的微服务生态灰度发布如何实现?

即原来的生产环境是1.0版本,那现在我们需要升级到2.0版本,但是我们需要验证2.0版本,在生产环境不会出问题,而且要稳定后,才能够完全切换为2.0

小伙伴们就会问,2.0版本应该我们测试人员 测试了啊,肯定没有问题啊。升级到2.0,直接升级就行了啊。

这个是不对的,因为生产环境有很多场景是独有的,如用户流量,数据量等。所以必须要验证2.0的稳定性;升级步骤如下:

1)100%的用户流量 打到 1.0版本上面;但测试人员可以通过测试工具指定线上2.0版本,即测试人员请求的是2.0版本。

2)测试初步验证后,可以先分5%的用户流量到2.0版本,95%的用户流量还是在1.0版本

3)查看2.0的稳定情况,分阶段的分配用户流量

4)完成切换到2.0版本,下线1.0版本;在下线1.0版本的时候不同的方案 会遇到不同的坑

实现原理一

老顾这个灰度的框架是建立在springcloud alibaba生态的注册中心和配置中心都是使用的是nacos;我们先来看看整个系统架构,在升级状态是什么情况

可用于大型应用的微服务生态灰度发布如何实现?

在spring cloud中,不管是网关 -> 服务A -> 服务B -> 服务C整个请求,网关是怎么知道有哪些服务A的?服务A是怎么知道有哪些服务B?服务B有哪些服务C?

这个是因为我们的所有服务都注册到了nacos注册中心里面,然后每个服务实例会通过5秒的心跳去请求nacos,获取到nacos里面的注册信息。

这个就是很重要的一个点,服务信息的同步;我们可以重写每个服务实例去拉取服务信息的时候,做一些过滤处理。举个例子,我们怎么保证服务A(1.0)只访问服务B(1.0)

服务A(1.0)在调用服务B时,需要去拉取服务B的服务实例信息,当我们发现服务B中有2.0版本时,就直接过滤掉;1.0才同步到本地缓存;通过这原理,就是保证了服务A(1.0)实例,只能访问服务B(1.0)

那怎么重写拉去服务呢?就是继承NacosServerList重写getInitialListOfServers、getUpdatedListOfServers方法,直接上源代码

可用于大型应用的微服务生态灰度发布如何实现?

实现原理二

只实现过滤掉不需要的版本,是不够的;因为我们有另一个需求,就是流量权重;即服务A可以访问服务B(1.0),也就是访问服务B(2.0);只是流量权重占比不一样而已;那怎么实现呢?

那就要用到我们客户端client的rabbion组件了,这个组件主要用来调用服务实例的,而是可以实现负载均衡;那我们就可以重写负载均衡算法,实现自定义的流量权重这个需求。

具体实现就是继承ZoneAvoidanceRule

重写Server choose(Object key),直接上代码

public class ZoneAvoidanceRuleDecorator extends ZoneAvoidanceRule {

。。。。。。

@Override

public Server choose(Object key) {

//todo 选择的逻辑

}

}

知道了基本的原理后,就可以直接去写了

实现原理三

另一个需求,就是我们需要考虑到在线动态的改变灰度路由的规则,而不是每次改变了规则,需要重新启动服务,这个就不对了。

这个的实现可以考虑利用nacos自身的功能。去订阅nacos的配置中心的变化,从而达到动态更新

案例

因为篇幅原因,老顾这里只介绍一些原理,具体源代码,可以到git上面去获取,要给个star哦

https://gitee.com/gujiachun/gray

引入依赖

1. 微服务项目需引入
gray-plugin-framework-starter-service项目

<dependency>

<groupId>com.rainbow.gray</groupId>

<artifactId>gray-plugin-framework-starter-service</artifactId>

<version>1.0.0-SNAPSHOT</version>

</dependency>

2. 网关项目需引入
gray-plugin-framework-starter-gateway项目

<dependency>

<groupId>com.rainbow.gray</groupId>

<artifactId>gray-plugin-framework-starter-gateway</artifactId>

<version>1.0.0-SNAPSHOT</version>

</dependency>

3. 本组件推荐使用远程配置的方法,配置rule规则,现在只支持nacos配置中心

4. 组件支持全局订阅,或局部订阅。

全局订阅即:DataId = group1,Group=group1;即DataId也为group名称,这样每个微服务以及网关都只订阅的是同一个rule规则

局部订阅即:DataId = 服务名称,Group=group1;即DataID是服务名称,即只有这个服务订阅了rule规则;其他服务不适用

(推荐全局订阅,因为灰度发布一般针对所有的服务生效;而且规则里面可以细化到每个服务的规则)

规则说明

可用于大型应用的微服务生态灰度发布如何实现?
可用于大型应用的微服务生态灰度发布如何实现?
可用于大型应用的微服务生态灰度发布如何实现?
可用于大型应用的微服务生态灰度发布如何实现?
可用于大型应用的微服务生态灰度发布如何实现?

使用说明

1. 配置nacos,在bootstrap.properties中配置nacos注册中心

spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848

spring.cloud.nacos.discovery.username=nacos

spring.cloud.nacos.discovery.password=nacos

spring.cloud.nacos.discovery.namespace=sit

2. 在bootstrap.properties中组件需要的配置

nacos.server-addr=${spring.cloud.nacos.discovery.server-addr}

nacos.username=${spring.cloud.nacos.discovery.username}

nacos.password=${spring.cloud.nacos.discovery.password}

nacos.plugin.namespace=${spring.cloud.nacos.discovery.namespace}

3. 在application.properties 配置元数据,非常重要,这个就是每个服务不同的版本version,地域region,环境env,区zone相关的配置

spring.cloud.nacos.discovery.metadata.group=example-service-group

spring.cloud.nacos.discovery.metadata.version=1.0

spring.cloud.nacos.discovery.metadata.region=dev

spring.cloud.nacos.discovery.metadata.env=env1

spring.cloud.nacos.discovery.metadata.zone=zone1

4. 亲和性

此场景就是在多机房部署时,如何保证优先调用同一机房的服务,避免跨机房调用

启动和关闭可用区亲和性,即同一个可用区的服务才能调用,同一个可用区的条件是调用端实例和提供端实例的元数据Metadata的zone配置值必须相等。缺失则默认为false

spring.application.zone.affinity.enabled=true

启动和关闭可用区亲和性失败后的路由,即调用端实例没有找到同一个可用区的提供端实例的时候,当开关打开,可路由到其它可用区或者不归属任何可用区,当开关关闭,则直接调用失败。缺失则默认为true

spring.application.zone.route.enabled=true

 外部参数Header

通过前端(Postman)方式传入灰度路由策略,来代替配置中心方式,传递全链路路由策略。这样就可以实现由测试人员自行选择走哪些路径

注意:当配置中心和外部参数都配置后,会先从配置中心的规则会先过滤执行,然后外部参数再过滤的原则

版本匹配策略,Header格式如下任选一个

1. n-d-version=1.0

2. n-d-version={"discovery-guide-service-a":"1.0", "discovery-guide-service-b":"1.0"}

版本权重策略,Header格式如下任选一个

1. n-d-version-weight=1.0=90;1.1=10

2. n-d-version-weight={"discovery-guide-service-a":"1.0=90;1.1=10", "discovery-guide-service-b":"1.0=90;1.1=10"}

区域匹配策略,Header格式如下任选一个

1. n-d-region=qa

2. n-d-region={"discovery-guide-service-a":"qa", "discovery-guide-service-b":"qa"}

区域权重策略,Header格式如下任选一个

1. n-d-region-weight=dev=99;qa=1

2. n-d-region-weight={"discovery-guide-service-a":"dev=99;qa=1", "discovery-guide-service-b":"dev=99;qa=1"}

IP地址和端口匹配策略,Header格式如下任选一个

1. n-d-address={"discovery-guide-service-a":"127.0.0.1:3001", "discovery-guide-service-b":"127.0.0.1:4002"}

2. n-d-address={"discovery-guide-service-a":"127.0.0.1", "discovery-guide-service-b":"127.0.0.1"}

3. n-d-address={"discovery-guide-service-a":"3001", "discovery-guide-service-b":"4002"}

环境隔离下动态环境匹配策略

1. n-d-env=env1

服务下线实时性的流量绝对无损,全局唯一ID屏蔽策略

1. n-d-id-blacklist=e92edde5-0153-4ec8-9cbb-b4d3f415aa33;af043384-c8a5-451e-88f4-457914e8e3bc

服务下线实时性的流量绝对无损,IP地址和端口屏蔽策略

1. n-d-address-blacklist=192.168.43.101:1201;192.168.*.102;1301

当外界传值Header的时候,网关也设置并传递同名的Header,需要决定哪个Header传递到后边的服务去。需要通过如下开关做控制

# 当外界传值Header的时候,网关也设置并传递同名的Header,需要决定哪个Header传递到后边的服务去。如果下面开关为true,以网关设置为优先,否则以外界传值为优先。缺失则默认为true

spring.application.strategy.gateway.header.priority=false

# 当以网关设置为优先的时候,网关未配置Header,而外界配置了Header,仍旧忽略外界的Header。缺失则默认为true

spring.application.strategy.gateway.original.header.ignored=true

总结

整体灰度的功能还是挺多,不过实现的原理就是上面介绍的原理;这里也要感谢开源社区的nepxion discovery开源项目,借鉴了设计思路,以及一些代码设计,简化了实现

---End---


老顾的微服务网关分享课程,请大家多多支持

推荐阅读

一线大厂级别公共Redis集群监控,细化到每个项目实例

Sharding-jdbc的实战入门之水平分表(一)

Sharding-Jdbc之水平分库和读写分离(二)

a、dubbo如何处理业务异常,这个一定要知道哦!

b、企业级SpringBoot应用多个子项目配置文件规划、多环境支持(一)

c、企业级SpringBoot应用多个子项目配置文件规划、多环境支持(二)

d、企业级SpringBoot应用多个子项目配置文件之配置中心(三)

e、利用阿里开源工具进行排查线上CPU居高问题

f、阿里二面:如何快速排查死锁?如何避免死锁?

g、微服务分布式架构中,如何实现日志链路跟踪?

h、网关如何聚合各个微服务的接口文档?

i、Kubernetes之POD、容器之间的网络通信

j、K8S中的Service的存在理由

k、企业微服务项目如何进入K8S的全过程

l、阿里开源项目Sentinel限流、降级的统一处理

m、大厂二面:Redis的分布式布隆过滤器是什么原理?

1基于RocketMq的SpringCloud Stream框架实战入门

2、如何搭建消息中间件应用框架之SpringCloud Stream

3面试必备:网关异常了怎么办?如何做全局异常处理?

4Gateway网关系列(二):SpringCloud Gateway入门实战,路由规则

5Gateway网关系列开篇:SpringCloud的官方网关Gateway介绍

6API网关在微服务架构中的应用,这一篇就够了

7学习Lambda表达式看这篇就够了,不会让你失望的哦(续篇)

8Lambda用在哪里?几种场景?

9、为什么会出现Lambda表达式,你知道吗?

10、不说“分布式事务”理论,直接上大厂阿里的解决方案,绝对实用

11、女程序员问到这个问题,让我思考了半天,Mysql的“三高”架构

12、大厂二面:CAP原则为什么只能满足其中两项?而不能同时满足

13、阿里P7二面:聊聊零拷贝的原理

14、秒杀系统的核心点都在这里,快来取

15、你了解如何利用token方式实现分布式Session吗?

16、Mysql索引结构演变,为什么最终会是那个结构呢?让你一看就懂

17、一场比赛涉及到的知识,用通俗易通的方式介绍并发协调

18、企业实战Redis全方面思考,你思考了吗?

19、面试题:Thread的start和run的区别

20、面试题:什么是CAS?CAS的作用以及缺点

21、如何访问redis中的海量数据?避免事故产生

22、如何解决Redis热点问题?以及如何发现热点?

23、如何设计API接口,实现统一格式返回?

24、你真的知道在生产环境下如何部署tomcat吗?

25、分享一线互联网大厂分布式唯一ID设计 之 snowflake方案

26、分享大厂分布式唯一ID设计方案,快来围观

27、你想了解一线大厂的分布式唯一ID生成方案吗?

28、你知道如何处理大数据量吗?(数据拆分篇)

29、如何永不迁移数据和避免热点? 根据服务器指标分配数据量(揭秘篇)

30、你知道怎么分库分表吗?如何做到永不迁移数据和避免热点吗?

31、你了解大型网站的页面静态化吗?

32、你知道如何更新缓存吗?如何保证缓存和数据库双写一致性?

33、你知道怎么解决DB读写分离,导致数据不一致问题吗?

34、DB读写分离情况下,如何解决缓存和数据库不一致性问题?

35、你真的知道怎么使用缓存吗?

36、如何利用锁,防止缓存击穿?重构思想的重要性

37、海量订单产生的业务高峰期,如何避免消息的重复消费?

38、你知道如何保障生产端100%消息投递成功吗?

39、微服务下的分布式session该如何管理?

40、阿里二面:filter、interceptor、aspect应如何选择?很多人中招

41、互联网架构重要组员CDN,很多高级开发都没有实操过,来看这里

42、阿里二面:CDN缓存控制原理,看看能不能难住你

43、SpringCloud Alibaba之Nacos多环境多项目管理

44、SpringCloud Alibaba系列之Nacos配置中心玩法

45、SpringCloud Alibaba之Nacos注册中心

46、SpringCloud Plus版本之SpringCloud Alibaba

47、SpringCloud Alibaba之Nacos集群、持久化

48、SpringCloud Alibaba之Nacos共享配置、灰度配置

49、SpringCloud Alibaba之Sentinel工作原理

50、SpringCloud Alibaba之Sentinel流控管理

51、SpringCloud Alibaba之Sentinel降级管理

52、SpringCloud Alibaba之Sentinel热点参数限流

53、SpringCloud Alibaba之Sentinel的API实战

文案策划

秦志强:利用文案策划在家兼职年赚50万+的秘密>>>>
版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站不拥有所有权,不承担相关法律责任。如发现有侵权/违规的内容, 联系QQ15101117,本站将立刻清除。