当前位置:首页 > 科技  > 软件

SpringCloud全链路灰色具体发布!

来源: 责编: 时间:2023-11-13 17:18:22 460观看
导读灰度发布(Gray Release,也称为灰度发布或金丝雀发布)是指在软件或服务发布过程中,将新版本的功能或服务以较小的比例引入到生产环境中,仅向部分用户或节点提供新功能的一种发布策略。在传统的全量发布中,新版本的功能会一次

6Sb28资讯网——每日最新资讯28at.com

灰度发布(Gray Release,也称为灰度发布或金丝雀发布)是指在软件或服务发布过程中,将新版本的功能或服务以较小的比例引入到生产环境中,仅向部分用户或节点提供新功能的一种发布策略。6Sb28资讯网——每日最新资讯28at.com

在传统的全量发布中,新版本的功能会一次性全部部署到所有的用户或节点上。然而,这种方式潜在的风险是,如果新版本存在缺陷或问题,可能会对所有用户或节点产生严重的影响,导致系统崩溃或服务不可用。6Sb28资讯网——每日最新资讯28at.com

相比之下,灰度发布采用较小的规模,并逐步将新版本的功能引入到生产环境中,仅向一小部分用户或节点提供新功能。通过持续监测和评估,可以在发现问题时及时回滚或修复。这种逐步引入新版本的方式可以降低风险,并提高系统的稳定性和可靠性。6Sb28资讯网——每日最新资讯28at.com

1、实现思路

灰色发布的常见实现思路有以下几种:6Sb28资讯网——每日最新资讯28at.com

  • 根据用户划分:根据用户标识或用户组进行划分,在整个用户群体中只选择一小部分用户获得新功能。
  • 根据地域划分:在不同地区或不同节点上进行划分,在其中的一小部分地区或节点进行新功能的发布。
  • 根据流量划分:根据流量的百分比或请求次数进行划分,只将一部分请求流量引导到新功能上。

而在生产环境中,比较常用的是根据用户标识来实现灰色发布,也就是说先让一小部分用户体验新功能,以发现新服务中可能存在的某种缺陷或不足。6Sb28资讯网——每日最新资讯28at.com

2、具体实现

Spring Cloud 全链路灰色发布的关键实现思路如下图所示:6Sb28资讯网——每日最新资讯28at.com

6Sb28资讯网——每日最新资讯28at.com

灰度发布的具体实现步骤如下:6Sb28资讯网——每日最新资讯28at.com

  • 前端程序在灰度测试的用户 Header 头中打上标签,例如在 Header 中添加“grap-tag: true”,其表示要进行灰常测试(访问灰度服务),而其他则为访问正式服务。
  • 在负载均衡器 Spring Cloud LoadBalancer 中,拿到 Header 中的“grap-tag”进行判断,如果此标签不为空,并等于“true”的话,表示要访问灰度发布的服务,否则只访问正式的服务。
  • 在网关 Spring Cloud Gateway 中,将 Header 标签“grap-tag: true”继续往下一个调用服务中传递。
  • 在后续的调用服务中,需要实现以下两个关键功能:
  1. 在负载均衡器 Spring Cloud LoadBalancer 中,判断灰度发布标签,将请求分发到对应服务。
  2. 将灰度发布标签(如果存在),继续传递给下一个调用的服务。

经过第四步的反复传递之后,整个 Spring Cloud 全链路的灰度发布就完成了。6Sb28资讯网——每日最新资讯28at.com

3、核心实现思路和代码

灰度发布的关键实现技术和代码如下。6Sb28资讯网——每日最新资讯28at.com

(1)区分正式服务和灰度服务

在灰度发布的执行流程中,有一个核心的问题,如果在 Spring Cloud LoadBalancer 进行服务调用时,区分正式服务和灰度服务呢?6Sb28资讯网——每日最新资讯28at.com

这个问题的解决方案是:在灰度服务既注册中心的 MetaData(元数据)中标识自己为灰度服务即可,而元数据中没有标识(灰度服务)的则为正式服务,以 Nacos 为例,它的设置如下:6Sb28资讯网——每日最新资讯28at.com

spring:  application:    name: canary-user-service  cloud:    nacos:      discovery:        username: nacos        password: nacos        server-addr: localhost:8848        namespace: public        register-enabled: true         metadata: { "grap-tag":"true" } # 标识自己为灰度服务

(2)负载均衡调用灰度服务

Spring Cloud LoadBalancer 判断并调用灰度服务的关键实现代码如下:6Sb28资讯网——每日最新资讯28at.com

private Response<ServiceInstance> getInstanceResponse(List<ServiceInstance> instances,                                                          Request request) {        // 实例为空        if (instances.isEmpty()) {            if (log.isWarnEnabled()) {                log.warn("No servers available for service: " + this.serviceId);            }            return new EmptyResponse();        } else { // 服务不为空            RequestDataContext dataContext = (RequestDataContext) request.getContext();            HttpHeaders headers = dataContext.getClientRequest().getHeaders();            // 判断是否为灰度发布(请求)            if (headers.get(GlobalVariables.GRAY_KEY) != null &&                    headers.get(GlobalVariables.GRAY_KEY).get(0).equals("true")) {                // 灰度发布请求,得到新服务实例列表                List<ServiceInstance> findInstances = instances.stream().                        filter(s -> s.getMetadata().get(GlobalVariables.GRAY_KEY) != null &&                                s.getMetadata().get(GlobalVariables.GRAY_KEY).equals("true"))                        .toList();                if (findInstances.size() > 0) { // 存在灰度发布节点                    instances = findInstances;                }            } else { // 查询非灰度发布节点                // 灰度发布测试请求,得到新服务实例列表                instances = instances.stream().                        filter(s -> s.getMetadata().get(GlobalVariables.GRAY_KEY) == null ||                                !s.getMetadata().get(GlobalVariables.GRAY_KEY).equals("true"))                        .toList();            }            // 随机正数值 ++i( & 去负数)            int pos = this.position.incrementAndGet() & Integer.MAX_VALUE;            // ++i 数值 % 实例数 取模 -> 轮询算法            int index = pos % instances.size();            // 得到服务实例方法            ServiceInstance instance = (ServiceInstance) instances.get(index);            return new DefaultResponse(instance);        }    }

以上代码为自定义负载均衡器,并使用了轮询算法。如果 Header 中有灰度标签,则只查询灰度服务的节点实例,否则则查询出所有的正式节点实例(以供服务调用或服务转发)。6Sb28资讯网——每日最新资讯28at.com

(3)网关传递灰度标识

要在网关 Spring Cloud Gateway 中传递灰度标识,只需要在 Gateway 的全局自定义过滤器中设置 Response 的 Header 即可,具体实现代码如下:6Sb28资讯网——每日最新资讯28at.com

package com.example.gateway.config;import com.loadbalancer.canary.common.GlobalVariables;import org.springframework.cloud.gateway.filter.GatewayFilterChain;import org.springframework.cloud.gateway.filter.GlobalFilter;import org.springframework.core.Ordered;import org.springframework.http.HttpStatus;import org.springframework.http.server.reactive.ServerHttpRequest;import org.springframework.http.server.reactive.ServerHttpResponse;import org.springframework.stereotype.Component;import org.springframework.web.server.ServerWebExchange;import reactor.core.publisher.Mono;@Componentpublic class LoadBalancerFilter implements GlobalFilter {    @Override    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {        // 得到 request、response 对象        ServerHttpRequest request = exchange.getRequest();        ServerHttpResponse response = exchange.getResponse();        if (request.getQueryParams().getFirst(GlobalVariables.GRAY_KEY) != null) {            // 设置金丝雀标识            response.getHeaders().set(GlobalVariables.GRAY_KEY,                    "true");        }        // 此步骤正常,执行下一步        return chain.filter(exchange);    }}

(4)Openfeign 传递灰度标签

HTTP 调用工具 Openfeign 传递灰度标签的实现代码如下:6Sb28资讯网——每日最新资讯28at.com

import feign.RequestInterceptor;import feign.RequestTemplate;import jakarta.servlet.http.HttpServletRequest;import org.springframework.stereotype.Component;import org.springframework.web.context.request.RequestContextHolder;import org.springframework.web.context.request.ServletRequestAttributes;import java.util.Enumeration;import java.util.LinkedHashMap;import java.util.Map;@Componentpublic class FeignRequestInterceptor implements RequestInterceptor {    @Override    public void apply(RequestTemplate template) {        // 从 RequestContextHolder 中获取 HttpServletRequest        ServletRequestAttributes attributes = (ServletRequestAttributes)                RequestContextHolder.getRequestAttributes();        // 获取 RequestContextHolder 中的信息        Map<String, String> headers = getHeaders(attributes.getRequest());        // 放入 openfeign 的 RequestTemplate 中        for (Map.Entry<String, String> entry : headers.entrySet()) {            template.header(entry.getKey(), entry.getValue());        }    }    /**     * 获取原请求头     */    private Map<String, String> getHeaders(HttpServletRequest request) {        Map<String, String> map = new LinkedHashMap<>();        Enumeration<String> enumeration = request.getHeaderNames();        if (enumeration != null) {            while (enumeration.hasMoreElements()) {                String key = enumeration.nextElement();                String value = request.getHeader(key);                map.put(key, value);            }        }        return map;    }}

小结

灰度发布是微服务时代保证生产环境安全的必备措施,而其关键实现思路是:6Sb28资讯网——每日最新资讯28at.com

  • 注册中心区分正常服务和灰度服务;
  • 负载均衡正确转发正常服务和灰度服务;
  • 网关和 HTTP 工具传递灰度标签。

这样,我们就完整的实现 Spring Cloud 全链路灰度发布功能了。6Sb28资讯网——每日最新资讯28at.com

本文链接:http://www.28at.com/showinfo-26-23626-0.htmlSpringCloud全链路灰色具体发布!

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com

上一篇: 高效联动,携程机票IVR可视化的探索和实践

下一篇: 八个 yyds 的开源前端实战项目!

标签:
  • 热门焦点
  • 三言两语说透设计模式的艺术-简单工厂模式

    一、写在前面工厂模式是最常见的一种创建型设计模式,通常说的工厂模式指的是工厂方法模式,是使用频率最高的工厂模式。简单工厂模式又称为静态工厂方法模式,不属于GoF 23种设计
  • 服务存储设计模式:Cache-Aside模式

    Cache-Aside模式一种常用的缓存方式,通常是把数据从主存储加载到KV缓存中,加速后续的访问。在存在重复度的场景,Cache-Aside可以提升服务性能,降低底层存储的压力,缺点是缓存和底
  • 一年经验在二线城市面试后端的经验分享

    忠告这篇文章只适合2年内工作经验、甚至没有工作经验的朋友阅读。如果你是2年以上工作经验,请果断划走,对你没啥帮助~主人公这篇文章内容来自 「升职加薪」星球星友 的投稿,坐
  • 之家push系统迭代之路

    前言在这个信息爆炸的互联网时代,能够及时准确获取信息是当今社会要解决的关键问题之一。随着之家用户体量和内容规模的不断增大,传统的靠"主动拉"获取信息的方式已不能满足用
  • 三言两语说透柯里化和反柯里化

    JavaScript中的柯里化(Currying)和反柯里化(Uncurrying)是两种很有用的技术,可以帮助我们写出更加优雅、泛用的函数。本文将首先介绍柯里化和反柯里化的概念、实现原理和应用
  • 阿里瓴羊One推出背后,零售企业迎数字化新解

    作者:刘旷近年来随着数字经济的高速发展,各式各样的SaaS应用服务更是层出不穷,但本质上SaaS大多局限于单一业务流层面,对用户核心关切的增长问题等则没有提供更好的解法。在Saa
  • AI芯片初创公司Tenstorrent获三星和现代1亿美元投资

    Tenstorrent是一家由芯片行业资深人士Jim Keller领导的加拿大初创公司,专注于开发人工智能芯片,该公司周三表示,已经从现代汽车集团和三星投资基金等
  • 苹果公司要求三星和LG Display生产「无边框」OLED iPhone显示屏

    据 The Elec 报道,苹果已要求其供应商为未来的 iPhone 型号开发「无边框」OLED 显示面板。苹果显然已要求三星和 LG Display 开发新的 OLED 显示面
  • 上海举办人工智能大会活动,建设人工智能新高地

    人工智能大会在上海浦江两岸隆重拉开帷幕,人工智能新技术、新产品、新应用、新理念集中亮相。8月30日晚,作为大会的特色活动之一的上海人工智能发展盛典人工
Top