前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >zuul灰度发布功能实现

zuul灰度发布功能实现

作者头像
天涯泪小武
发布2019-01-17 11:51:19
2.2K0
发布2019-01-17 11:51:19
举报
文章被收录于专栏:SpringCloud专栏SpringCloud专栏

灰度发布、蓝绿发布、金丝雀发布各是什么意思,可以看这篇http://www.appadhoc.com/blog/product-release-strategy/。

基于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

代码语言:javascript
复制
server:
  port: 8888
eureka:
  instance:
    prefer-ip-address: true
    metadata-map:
      lancher: 2
  client:
    service-url:
      defaultZone: http://localhost:10000/eureka/

application-dev.yml

代码语言:javascript
复制
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

代码语言:javascript
复制
<dependency>
			<groupId>io.jmnarloch</groupId>
			<artifactId>ribbon-discovery-filter-spring-cloud-starter</artifactId>
			<version>2.1.0</version>
		</dependency>

这个就是做ribbon的Rule的。

代码语言:javascript
复制
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 wuweifeng wrote on 2018/1/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的那个服务。

so,很简单,我们就可以在这里定制各种规则了,把符合什么条件的请求,只发送到某个实例。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018年01月22日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
存储网关
存储网关(Cloud Storage Gateway,CSG)是一种混合云存储服务。您可以通过 CSG 使用标准文件共享协议访问位于对象存储 COS 中的数据,无缝接入公有云,实现数据的实时共享和冷热分层。腾讯云 CSG 可以根据您的业务需求灵活地部署在云上或者本地,让您更轻松地进行数据的云上处理、备份归档以及灾难恢复。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档