ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

zuul网关实现灰度发布

2021-06-07 22:33:01  阅读:391  来源: 互联网

标签:网关 服务 im eureka 灰度 zuul metadata


本文使用zuul网关实现灰度发布,包括了网关到服务、服务到服务的灰度。

服务部署可分为三种方式

1)蓝绿发布

  蓝绿发布是通过冗余的方式来解决部署问题,生产环境为绿色配置,冗余的服务为蓝色配置。在部署服务时,首先在冗余服务器上部署最新代码,由部分用户使用,

若使用没有问题,则通过负载均衡将所有用户请求转发到冗余服务器中,即冗余的服务转变为生产环境服务。优点是无需停机部署,服务回滚方便。缺点耗费服务器资源。

2)滚动发布

  滚动发布指每次只部署一个或多个服务,直到服务部署完成为止。优点:用户无感知,平滑过渡;相比蓝绿发布节省服务器资源。缺点:部署复杂,且时间长;遇到

问题回滚比较复杂。

3)灰度发布

  只升级部分服务,让少量用户访问新部署的服务,其他用户使用老服务,用户反馈无误后,整个集群部署,将用户迁移到新服务上来。优点:在灰度时即可发现问题及

时处理,保证系统稳定性;如果出现问题,影响范围小;用户无感知,过渡平滑。

灰度发布实现步骤:

1)定义规则:哪些用户可以访问灰度环境,比如按百分比(10%的用户可以访问灰度),或让固定用户先体验灰度环境;

2)利用网关实现路由策略,即网关到服务的路由;

3)服务与服务之间的调用使用ribbon实现灰度规则。

代码实现

代码使用zuul网关实现,项目包括了zuul、im、search三个服务,im服务调用search服务,具体实现如下。

1.引入maven依赖,关键依赖

  <dependency>
            <groupId>io.jmnarloch</groupId>
            <artifactId>ribbon-discovery-filter-spring-cloud-starter</artifactId>
            <version>2.1.0</version>
 </dependency>        
<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-zuul</artifactId>
            <version>1.4.6.RELEASE</version>
 </dependency>

2.application.properties配置文件进行配置

server.port=9090

spring.application.name=zuul
#注册中心
eureka.client.service-url.defaultZone=http://localhost:8761/eureka
eureka.instance.prefer-ip-address=true
eureka.client.registerWithEureka=true 
#zuul网关路由 前缀
zuul.routes.prefix=/zuul
zuul.routes.im.path=/im/**
#im代表自定义服务
zuul.routes.im.service-id=im
#false不会截取  true截取前缀
zuul.routes.im.stripPrefix=true

#http://localhost:9090/zuul/im/index

3.GrayFilter过滤器实现网关到服务的灰度规则

@Component
public class GrayFilter extends ZuulFilter {
    private static final String GRAY = "gray";
    @Override
    public String filterType() {
        return FilterConstants.PRE_TYPE;
    }

    @Override
    public int filterOrder() {
        return 0;
    }

    @Override
    public boolean shouldFilter() {
        //是否开启过滤
        return true;
    }

    @Override
    public Object run() throws ZuulException {
        //实现灰度逻辑
        //前端在请求头中携带灰度标识字段
        //服务注册时加入metadata数据,代表该服务节点为灰度节点
        //首先从头部中获取标识
        RequestContext currentContext = RequestContext.getCurrentContext();
        HttpServletRequest request = currentContext.getRequest();
        String header = request.getHeader("gray_header");
        //将灰度的请求转发到meataData中forward为1的服务
        if(StringUtils.equals(header,GRAY)){
            RibbonFilterContextHolder.getCurrentContext().add("forward","1");
        }else {
            RibbonFilterContextHolder.getCurrentContext().add("forward","2");
        }
        return null;
    }
}

4.im、search服务启动时注册metadata到注册中心

eureka.client.service-url.defaultZone=http://localhost:8761/eureka/
eureka.client.enabled=true
#eureka.instance.hostname=localhost
#eureka.instance.instance-id=im
#灰度端口
server.port=8081
#生产端口
#server.port=8082
spring.application.name=im
#灰度发布需要metadata
#灰度为1
eureka.instance.metadata-map.forward=1

 

eureka.client.service-url.defaultZone=http://localhost:8761/eureka
server.port=8089
spring.application.name=search

#灰度为1
eureka.instance.metadata-map.forward=1

5.实现服务到服务的灰度规则

/**
 *  定义服务间灰度调用规则
 */
@Component
public class GrayRule extends AbstractLoadBalancerRule {

    private static final String GRAY = "gray";
    private static final String GRAY_HEADER = "forward";
    private static final String GRAY_VALUE = "1";
    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @Override
    public void initWithNiwsConfig(IClientConfig iClientConfig) {

    }

    @Override
    public Server choose(Object o) {
        ILoadBalancer loadBalancer = getLoadBalancer();
        return this.choose(loadBalancer);
    }

    private Server choose(ILoadBalancer lb){
        Server server = null;
        if (server==null){
       //获取请求头中的参数,具体实现在gitee Map<String, String> stringStringMap = GrayRibbonParamater.get(); String grayParmater = null; if(stringStringMap!=null){ grayParmater = stringStringMap.get("gray_header"); } //获得可到达的服务 List<Server> reachableServers = lb.getReachableServers(); for (Server reachableServer : reachableServers) { //获取服务的metadata Map<String, String> metadata = ((DiscoveryEnabledServer) reachableServer).getInstanceInfo().getMetadata(); if(StringUtils.equals(metadata.get(GRAY_HEADER),GRAY_VALUE)&&StringUtils.equals(grayParmater,GRAY)){ return reachableServer; } } } return server; } }

  

  

  

  

  

 

标签:网关,服务,im,eureka,灰度,zuul,metadata
来源: https://www.cnblogs.com/menbo/p/14855582.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有