• 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的那个服务。
    整个过程很简单,我们就可以在这里定制各种规则了,把符合什么条件的请求,只发送到某个实例

  • 相关阅读:
    技术周刊 · 耿耿星河欲曙天 | SpaceX 上的前端架构;跨平台新选择;开源世界的新“大门”;用户推荐算法的敲门砖……
    说说SVG的feTurbulence滤镜
    机器学习进阶
    小程序与动画的故事
    技术周刊 · 迢迢山径峻 | Web 开发成长图谱;下一代前端构建技术;AI 应用下支离破碎的真实;不懂产品不会开发;虚拟货币是新时代的黄金
    从中断机制看 React Fiber 技术
    三分钟了解数字人民币
    凹凸技术揭秘:如何服务 toG 项目——数字人民币项目前端总结
    使用 Phaser3+Matter.js 实现“合成大西瓜”游戏
    痞子衡嵌入式:快速定位i.MXRT600板级设计ISP[2:0]启动模式引脚上电时序问题的方法
  • 原文地址:https://www.cnblogs.com/shihaiming/p/11416459.html
Copyright © 2020-2023  润新知