Spring cloud架构中利用zuul网关实现灰度发布功能
蓝绿发布、金丝雀发布(灰度发布)、AB测试
首先,了解下这几种发布方式的基础概念。
目前常见的发布策略有蓝绿发布、金丝雀发布(灰度发布)、AB测试这几种,在国内的开发者中,对这几个概念有独立的理解。蓝绿发布通常被大家成为热部署;金丝雀发布在国内的名头完全被他的变种发布方式盖过了,主要是灰度发布与AB测试,下面来详细的为大家解释一下他们之间的异同。
蓝绿发布
在发布的过程中用户无感知服务的重启,通常情况下是通过新旧版本并存的方式实现,也就是说在发布的流程中,新的版本和旧的版本是相互热备的,通过切换路由权重的方式(非0即100)实现不同的应用的上线或者下线。
金丝雀发布
通过在线上运行的服务中,新加入少量的新版本的服务,然后从这少量的新版本中快速获得反馈,根据反馈决定最后的交付形态。
灰度发布
灰度发布是通过切换线上并存版本之间的路由权重,逐步从一个版本切换为另一个版本的过程。虽然有很多人包括专业大牛认为灰度发布与金丝雀发布是等同的,但是在具体的操作和目的上面个还是有些许差别的。金丝雀发布更倾向于获取快速的反馈,而灰度发布更倾向于从一个版本到另一个版本平稳的切换。
AB测试
AB测试和灰度发布非常像,但是从发布的目的上,可以简单的区分灰度发布与AB测试,AB测试侧重的是从A版本或者B版本之间的差异,并根据这个结果进行决策。最终选择一个版本进行部署。因此和灰度发布相比,AB测试更倾向于去决策,和金丝雀发布相比,AB测试在权重和流量的切换上更灵活。
在Spring cloud架构体系中基于eureka、ribbon实现灰度发布,是本篇要讲的知识。
我们要发布版本了,在不确定正确性的情况下,我们选择先部分节点升级,然后让一些特定的流量进入到这些新节点,完成测试后再全量发布。
我们知道,在eureka中注册各个服务后,如果一个服务有多个实例,那么默认会走ribbon的软负载均衡来进行分发请求。
我们要完成灰度发布,要做的就是修改ribbon的负载策略(rule),通过一些特定的标识,譬如我们可以选择header里带有foo=1的全部路由到金丝雀服务上,其他的还走原来的老版本。或者可以设置个比重,虽然roll个小于4的正数,将等于1的路由到金丝雀,这样就会有1/4的请求到达金丝雀。诸如此类,我们可以定制各种规则来进行灰度测试。
在SpringCloud体系中,完成这件事,模式比较固定,就是根据eureka的metadata进行自定义元数据,然后修改ribbon的Rule规则。
使用很简单,我们直接上例子,注意我这里只发出来目标服务和zuul的代码,eureka的就不放了。eureka很简单,就是一个eureka server项目,什么也没有。
我们的目标服务是User,在User的application.yml里,由于我要启动2个,所以使用不同的端口
application.yml
server:
port: 8888
eureka:
instance:
prefer-ip-address: true
metadata-map:
lancher: 2
client:
service-url:
defaultZone: http://localhost:10000/eureka/
application-dev.yml
server:
port: 8889
eureka:
instance:
metadata-map:
lancher: 1
就是那个metadata-map元数据,这是一个map,里面就自定义一些key-value键值对。将来匹配时就用这个键值对。
然后分别启动这两个实例,启动后就有两个user注册到了eureka。
zuul配置:
在zuul项目里添加依赖,https://github.com/jmnarloch/ribbon-discovery-filter-spring-cloud-starter
<dependency>
<groupId>io.jmnarloch</groupId>
<artifactId>ribbon-discovery-filter-spring-cloud-starter</artifactId>
<version>2.1.0</version>
</dependency>
这个就是做ribbon的Rule的。
package com.example.zuul_route; import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import io.jmnarloch.spring.cloud.ribbon.support.RibbonFilterContextHolder;
import org.springframework.context.annotation.Configuration; import javax.servlet.http.HttpServletRequest; import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.*; /**
* @author log4geek.cc wrote on 2018/11/17.
*/
@Configuration
public class PreFilter extends ZuulFilter {
@Override
public int filterOrder() {
return PRE_DECORATION_FILTER_ORDER - 1;
} @Override
public String filterType() {
return PRE_TYPE;
} @Override
public boolean shouldFilter() {
RequestContext ctx = RequestContext.getCurrentContext();
// a filter has already forwarded
// a filter has already determined serviceId
return !ctx.containsKey(FORWARD_TO_KEY)
&& !ctx.containsKey(SERVICE_ID_KEY);
} @Override
public Object run() {
RequestContext ctx = RequestContext.getCurrentContext();
HttpServletRequest request = ctx.getRequest();
if (request.getParameter("foo") != null) {
// put the serviceId in `RequestContext`
RibbonFilterContextHolder.getCurrentContext()
.add("lancher", "1");
} else {
RibbonFilterContextHolder.getCurrentContext()
.add("lancher", "2");
} return null;
}
}
这个是zuul的filter,关键代码在run方法,
RibbonFilterContextHolder.getCurrentContext() .add("lancher", "1");
这句话就代表将请求路由到metadata-map里lancher为1的那个服务。
整个过程很简单,我们就可以在这里定制各种规则了,把符合什么条件的请求,只发送到某个实例
Spring cloud架构中利用zuul网关实现灰度发布功能的更多相关文章
- Spring Cloud 专题之四:Zuul网关
书接上回: SpringCloud专题之一:Eureka Spring Cloud专题之二:OpenFeign Spring Cloud专题之三:Hystrix 经过前面三章对Spring Cloud ...
- 【Spring Cloud学习之四】Zuul网关
环境 eclipse 4.7 jdk 1.8 Spring Boot 1.5.2 Spring Cloud 1.2 一.接口网关接口网关:拦截所有的请求,交由接口网关,然后接口网关进行转发,类似ngi ...
- Spring Cloud之搭建动态Zuul网关路由转发
传统方式将路由规则配置在配置文件中,如果路由规则发生了改变,需要重启服务器.这时候我们结合上节课内容整合SpringCloud Config分布式配置中心,实现动态路由规则. 将yml的内容粘贴到码云 ...
- Spring Cloud(六)服务网关 zuul 快速入门
服务网关是微服务架构中一个不可或缺的部分.通过服务网关统一向外系统提供REST API的过程中,除了具备服务路由.均衡负载功能之外,它还具备了权限控制等功能.Spring Cloud Netflix中 ...
- Spring Cloud架构教程 (三)服务网关(基础)
通过之前几篇Spring Cloud中几个核心组件的介绍,我们已经可以构建一个简略的(不够完善)微服务架构了.比如下图所示: alt 我们使用Spring Cloud Netflix中的Eureka实 ...
- Spring Cloud架构教程 (四)服务网关(路由配置)
传统路由配置 所谓的传统路由配置方式就是在不依赖于服务发现机制的情况下,通过在配置文件中具体指定每个路由表达式与服务实例的映射关系来实现API网关对外部请求的路由. 没有Eureka和Consul的服 ...
- Spring Cloud架构教程 (七)消息驱动的微服务(核心概念)【Dalston版】
下图是官方文档中对于Spring Cloud Stream应用模型的结构图.从中我们可以看到,Spring Cloud Stream构建的应用程序与消息中间件之间是通过绑定器Binder相关联的,绑定 ...
- spring cloud深入学习(十一)-----服务网关zuul
前面的文章我们介绍了,Eureka用于服务的注册于发现,Feign支持服务的调用以及均衡负载,Hystrix处理服务的熔断防止故障扩散,Spring Cloud Config服务集群配置中心,似乎一个 ...
- Spring Cloud 系列之 Netflix Zuul 服务网关
什么是 Zuul Zuul 是从设备和网站到应用程序后端的所有请求的前门.作为边缘服务应用程序,Zuul 旨在实现动态路由,监视,弹性和安全性.Zuul 包含了对请求的路由和过滤两个最主要的功能. Z ...
随机推荐
- 第10组 Beta冲刺(1/4)
队名:凹凸曼 组长博客 作业博客 组员实践情况 童景霖 过去两天完成了哪些任务 文字/口头描述 继续学习Android studio和Java 制作剩余界面前端 展示GitHub当日代码/文档签入记录 ...
- Docker整合dockerfly实现UI界面管理(单机版)
一.搜索镜像 docker search dockerfly 二.根据镜像使用排名(一般情况下拉取使用率最高的镜像名),我这里使用的是阿里云镜像地址 docker pull registry.cn-h ...
- Redis的三个框架:Jedis,Redisson,Lettuce
Jedis api 在线网址:http://tool.oschina.net/uploads/apidocs/redis/clients/jedis/Jedis.html redisson 官网地址: ...
- Spring Security教程之退出登录logout(十)
要实现退出登录的功能我们需要在http元素下定义logout元素,这样Spring Security将自动为我们添加用于处理退出登录的过滤器LogoutFilter到FilterChain.当我们指定 ...
- 二叉树遍历(前序、中序、后序)-Java实现
一.前序遍历 访问顺序:先根节点,再左子树,最后右子树:上图的访问结果为:GDAFEMHZ. 1)递归实现 public void preOrderTraverse1(TreeNode root) { ...
- 怎么看系统是UEFI还是Legacy BIOS启动模式?
在命令行 cmd 中输入 msinfo32 ,找到右侧[BIOS模式],看到这里显示的是[uefi],那么说明是[uefi]方式启动的,反之显示为[BIOS],那么就是传统[BIOS]启动模式.如下 ...
- Git系列 —— github提交一个空目录
转载自github提交一个空目录 github默认不上传空目录,有的时候需要空目录来保持程序的结构. 两种场景 1.始终保持空目录,即时里面有文件,也全部忽略掉. 建立一个.gitignore文件放到 ...
- centos7安装mysql初始化报错
[root@localhost bin]# ./mysqld --initialize --user=mysql2019-09-16T06:15:28.835202Z 0 [Warning] TIME ...
- C#中如何禁止WindowsMediaPlayer双击全屏显示
问题描述:在项目中使用WindowsMediaPlayer播放视频时,双击会出现视频全屏的效果,而且视频恢复后会暂停,除非再次双击返回后才能正常播放.那么如何禁止WindowsMediaPlayer的 ...
- person类与其子类在使用中的内存情况(含java的改写和c#的屏蔽)
JAVA 普通person类及调用代码: public class Person { public String xm; public int nl; public void setme(String ...