Java灰度发布

news2024/11/15 19:27:53

有没有在北京面试java的小伙伴,每家公司面试问的问题都不一样,昨天面试官问到了灰度发布,一脸懵,好像在哪儿听说过,毕竟我都没发布过,之前都是项目组长在干这些事儿,所以聊聊,了解一下

todo这都是为了面试准备的,流程逻辑是对的,但自己还没尝试过,等有时间回来自己实现一下

什么是灰度发布

在这里插入图片描述

  • 全量发布:把旧服务kill掉,把新服务启动,这个过程就可以理解为全量发布

    • 回滚周期长

      如果我们更新完应用之后,我们做线上回归测试的时候发现有BUG,这个时候就要做回滚,过程就是把新服务kill掉,再把旧服务启动,这个过程的整个服务是挂掉的,不会提供服务的,那么在这段时间服务就是不可用的,就会导致一部分的用户群体流失,这个问题是非常严重的

    • 一些BUG可能会导致服务集群雪崩

      在实际生产中部署了不止一台机器,因为要做高可用,可能部署了两台以上的机器,假设代码中有一个内存泄漏的代码,内存泄漏可能刚刚部署看不到这个问题,在经过了几天或者一周之后,会导致我们整个新版本的服务集群全线宕机,这个问题也是非常严重的。

    我们在新版本上面去做回滚的时候会比我们BUG回归的回滚时间更长, 总的导致一个问题就是我们的服务可用性差了。

    我们在一些互联网公司,服务可用性要做到99.999%

  • 灰度发布

    • 降低发布影响面

      集群里拿出一台机器部署一个新版本,然后放一部分内测流量(用户)进来,如果在这个新的版本发现了问题之后,就可以直接把那一小部分流量直接转到我们的旧版上面,它的影响面也仅在那一部分小的群体

    • 可以做到不停机迁移

      从集群中拿一台机器更新到新版再放流量进来,这是不会影响集群中的其他服务的

    • 回滚速度快

灰度发布, 也叫金丝雀发布。是指在黑与白之间,能够平滑过渡的一种发布方式。AB test就是一种灰度发布方式,让一部分用户继续用A,一部分用户开始用B,如果用户对B没有什么反对意见,那么逐步扩大范围,把所有用户都迁移到B上面来。

灰度发布可以保证整体系统的稳定,在初始灰度的时候就可以发现、调整问题,以保证其影响度,而我们平常所说的金丝雀部署也就是灰度发布的一种方式。

具体到服务器上,实际操作中还可以做更多控制,譬如说,给最初更新的10台服务器设置较低的权重、控制发送给这10台服务器的请求数,然后逐渐提高权重、增加请求数。一种平滑过渡的思路, 这个控制叫做“流量切分”

核心组件说明

  • 注册中心: Nacos
  • 网关: SpringCloudGateway
  • 负载均衡器: Ribbon (使用SpringCloudLoadBalancer实现也是类似的)
  • 服务间RPC调用: OpenFeign

灰度发布代码实现

要实现Spring Cloud项目灰度发布技术方案有很多,重点在于服务发现,怎么将灰度流量只请求到灰度服务,这里我们会使用Nacos作为注册中心和配置中心,核心就是利用Nacos的Metadata设置一个version值,在调用下游服务是通过version值来区分要调用那个版本,这里会省略一些流程,文章末尾提供了源码地址需要自提。

在这里插入图片描述

在请求进入网关时开始对是否要请求灰度版本进行判断,通过Spring Cloud Gateway的过滤器实现,在调用下游服务时重写一个Ribbon的负载均衡器实现调用时对灰度状态进行判断。

kerwin:
  tool:
    gray:
      gateway:
        ## 是否开启灰度发布功能
        enabled: true
        ## 自定义灰度版本请求头
        grayHeadKey: gray
        ## 自定义灰度版本请求头匹配值
        grayHeadValue: gray-996
        ## 使用灰度版本IP数组
        grayIPList:
          - '127.0.0.1'
        ## 使用灰度版本城市数组
        grayCityList:
          - 本地

配置Nacos全局配置文件(common-config.yaml)

所有服务都会使用到这个配置

kerwin:
  tool:
    gray:
      ## 配置是否加载灰度自动配置类,如果不配置那么默认不加载
      load: true
      ## 配置生产版本和灰度版本号
      version:
        prodVersion: V1
        grayVersion: V2

## 配置Ribbon调用user-app和order-app服务时使用我们自定义灰度轮询算法
user-app:
  ribbon:
    NFLoadBalancerRuleClassName: com.kerwin.gray.loadbalancer.GrayRoundRobinRule
order-app:
  ribbon:
    NFLoadBalancerRuleClassName: com.kerwin.gray.loadbalancer.GrayRoundRobinRule

md看了半天,知识点有点多,有些复杂了,不是我这个水平能够掌握的

总结一下得了,别面试问的时候一句话说不出来就行

在请求进入网关时开始对是否要请求灰度版本进行判断,通过Spring Cloud Gateway的过滤器实现,在调用下游服务时重写一个Ribbon的负载均衡器实现调用时对灰度状态进行判断。

  1. 配置文件中的自定义属性

    • 是否开启灰度发布功能
    • 灰度发布的版本(几种匹配情况)
      • 自定义灰度版本请求头以及请求值 固定值 gray=gray-996
      • 灰度版本IP数组
      • 灰度版本城市数组
      • 灰度版本用户数组
  2. 整体的逻辑

在请求进入网关时开始对是否要请求灰度版本进行判断,通过Spring Cloud Gateway的过滤器实现,在调用下游服务时重写一个Ribbon的负载均衡器实现调用时对灰度状态进行判断。

  1. 利用GlobalFilter和Order接口实现前置过滤器和后置过滤器

    • 前置过滤器中判断灰度开关是否打开,判断灰度发布的版本,只要符合其中一项就将灰度状态的枚举设置到灰度的ThreadLocal中

    • 后置过滤器是为了在调用完下游业务服务后在响应之前将 GrayFlagRequestHolder 中的 ThreadLocal 清除避免照成内存泄漏。

    • 全局异常处理器是为了处理异常情况下将 GrayFlagRequestHolder 中的 ThreadLocal 清除避免照成内存泄漏,如果在调用下游业务服务时出现了异常就无法进入后置过滤器。

  2. 自定义Ribbon负载均衡路由(业务服务也是使用的这个)

    • 灰度Ribbon负载均衡路由抽象类,这是Ribbon的一个抽象类,主要作用是获取服务列表,

      会对GrayFlagRequestHolder 中存储的当前线程灰度状态枚举进行判断,
      如果枚举值为GrayStatusEnum.ALL则响应全部服务列表不区分版本,
      如果枚举值为GrayStatusEnum.PROD则返回生产版本的服务列表,
      如果枚举值为GrayStatusEnum.GRAY则返回灰度版本的服务列表

      版本号会在GrayVersionProperties 中配置,通过服务列表中在Nacos的metadata中设置的version和GrayVersionProperties的版本号进行匹配出对应版本的服务列表

      它这可以获取到所有服务并判断他们的nacos中的Version进行匹配返回相应的服务列表

    • 自定义轮询算法实现GrayRoundRobinRule

      直接拷贝了Ribbon的轮询算法,将里面获取服务列表的方法换成了自定义AbstractGrayLoadBalancerRule 中的方法

  3. 自定义SpringMVC请求拦截器

    自定义SpringMVC请求拦截器获取上游服务的灰度请求头,如果获取到则设置到GrayFlagRequestHolder 中,之后如果有后续的RPC调用同样的将灰度标记传递下去。

  4. 自定义OpenFeign请求拦截器

    自定义OpenFeign请求拦截器,取出自定义SpringMVC请求拦截器中设置到GrayFlagRequestHolder中的灰度标识,并且放到调用下游服务的请求头中,将灰度标记传递下去。

存在问题
1、如果项目中使用到了分布式任务调度那怎么区分灰度版本
这里其实挺好解决的,就拿xxl-job来说,注册不同的执行器就行,在发布灰度版本时注册到灰度版本的执行器即可。

2、如果项目中使用的了MQ我们收发消息怎么控制灰度
这里和解决分布式任务调度思想是一样的灰度版本的服务发送消息的时候投递到另外一个MQ的服务端,就是弄两套MQ服务端,生产的服务使用生产的MQ,灰度发布使用灰度的MQ

3、这里整个实现流程不是很复杂,但也是很没必要,只是提供一种实现方案可以参考
其实通过Nginx + Lua脚本方式直接路由网关,然后给灰度整套服务都使用一个Nacos灰度的命名空间,生产的使用生产的命名空间,这样就能将两套服务都隔离了,分布式任务调度、MQ等配置都可以独立在自己命名空间的配置文件中岂不美哉

部分内容引用自:
https://www.bilibili.com/video/BV1E84y1q7H7/?spm_id_from=333.337.search-card.all.click&vd_source=64c73c596c59837e620fed47fa27ada7
https://blog.51cto.com/u_6813689/11876044

华为的员工有这个经济基础,有条件比国人先走一步,做一个乐观、开放、自律、正派的人,给周边做个表率。当前一部分华为人反映出来的现象,恰恰相反,令人不安。一部分员工,不知道自己的祖坟为什么埋得这么好,还是碰到了什么神仙,突然富有后,就不知所措了。有些人表现得奢侈,张狂,在小区及社会上表现出那种咄咄逼人,不仅自己,自己的家人也趾高气扬……;一部分人对社会充满了怀疑的眼光,紧紧地捂着自己的钱袋子,认为谁都在打他的主意,对谁都不信任……。这些,都不是华为精神,这些人员不适合担任行政管理职位的,不管高低都不合适。他们所领导的团队一定萎靡不振。

任正非:要快乐地度过充满困难的一生

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2110898.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

驾驭Autofac,ASP.NET WebApi实现依赖注入详细步骤总结

前言 嘿,小伙伴们,今天我们来一场 Autofac 的学习之旅吧! Autofac 是一个轻量级的依赖注入框架,专门为 .NET 应用程序量身定做,它就像是你代码中的 “魔法师”,用它来管理对象的生命周期,让你…

828华为云征文|华为云Flexus X实例docker部署最新gitlab社区版,搭建自己的私人代码仓库

828华为云征文|华为云Flexus X实例docker部署最新gitlab社区版,搭建自己的私人代码仓库 华为云最近正在举办828 B2B企业节,Flexus X实例的促销力度非常大,特别适合那些对算力性能有高要求的小伙伴。如果你有自建MySQL、Redis、Ng…

大数据采集迁移工具

Flume Sqoop kafka框架 MQ:消息队列 broker相当于服务器 消息队列

栈和队列(1)

空栈先移动栈顶再加数据,满栈先插入数据再移 栈的基本概念栈是一种后进先出(LIFO,Last In First Out)的数据结构。栈支持两种主要的操作:•压栈(Push):向栈中添加一个元素。•弹栈&…

Kubernetes v1.28.0安装详解

Kubernetes v1.28.0安装详解 一.环境初始化 要在所有节点执行命令进行配置 1、检查操作系统的版本 此部署环境为CentOS 7.9 [rootCentOS7 ~]# cat /etc/redhat-release CentOS Linux release 7.9.2009 (Core) [rootCentOS7 ~]#2、主机名解析 为了方便集群节点间的互相调…

活动系统开发之采用设计模式与非设计模式的区别-数据库设计及代码设计

1、数据库ER图 2、应用框架选用 PHP语言对应的thinkphp6.1应用框架 3、功能代码设计(后端) a、父类Base.php i:控制登录,只能登录后管理员才能操作; ii:控制按钮权限,管理员不仅要登录,且必须要有对应菜单…

报错处理:超过Uobject最大数量

处理方式 一、打包时项目中设置游戏中UObject的最大数量为100000000 二、打包后的配置文件中设置 打包路径: 一厅统管\Windows\YZ_YTTG\Saved\Config\Windows\Engine.ini文件下添加配置文件 [/Script/Engine.GarbageCollectionSettings] gc.MaxObjectsInEditor1000…

API 网关 OpenID Connect 实战:单点登录(SSO)如此简单

作者:戴靖泽,阿里云 API 网关研发,Higress 开源社区 Member 前言 随着企业的发展,所使用的系统数量逐渐增多,用户在使用不同系统时需要频繁登录,导致用户体验较差。单点登录(Single Sign-On&a…

2024最新!Facebook手机版和网页版改名教程!

Facebook作为全球最大的社交平台之一,允许用户自定义名字和昵称。在Facebook更新姓名可以帮助您更好的展现账号形象。本文将为您提供详细的步骤指导,帮助您在手机APP和网页版上轻松完成Facebook改名操作。 Facebook手机版改名 打开Facebook APP并登录账号…

区块链ARC如何能让节点能够大规模处理交易数据

​​发表时间:2024年8月7日 TAAL技术主管Michael Bckli表示,TAAL公司一直在对ARC进行测试,并准备在今年年底全面发布。因TAAL在区块链交易处理方面具备深厚的专业知识,BSV区块链委托TAAL进行ARC开源参考落地方案的开发。 ARC是一个…

魔珐科技受邀参与外滩大会:以3D数字人AIGC产品赋能大资管行业,重塑金融服务边界

在人工智能浪潮的推动下,金融行业正经历着前所未有的场景革命。2024年Inclusion外滩大会作为行业交流的盛会,汇聚了众多学者、专家及企业领袖,共同探讨AI技术在多领域的深度应用,特别是其在金融行业中的革新潜力。 在外滩大会上&…

在桌面商业分析应用程序中启用高级 Web UI

挑战 Mercur Business Control 应用程序在企业界,尤其是金融领域,拥有悠久的应用历史。它帮助企业处理、可视化和分析海量数据,从而做出明智的商业决策。 随着产品的不断演进和现代化,Mercur Solutions AB 为该应用创建了 Web 客…

使用RestTemplate获取国内大盘股票数据的基本信息并存入数据库中

目录 使用RestTemplate获取国内大盘股票数据的基本信息并存入数据库中 第一步:导入RestTemplate依赖,并配置RestTemplate让其加入到SpringIoC容器中 第二步:在yml文件定义股票的相关参数 第三步:向新浪网发送请求,获…

FP7195:非同步升压恒流LED区动IC

前言:LED驱动芯片是什么? LED驱动芯片是一种能够将电源的电压和电流转换为适合LED(发光二极管)使用的电压和电流的芯片。这种芯片的主要作用是控制LED的亮度和电流,从而保证LED的正常工作和长寿命。简单来说&#xff…

【C++二分查找】1802. 有界数组中指定下标处的最大值

本文涉及的基础知识点 C二分查找 LeetCode 1802. 有界数组中指定下标处的最大值 给你三个正整数 n、index 和 maxSum 。你需要构造一个同时满足下述所有条件的数组 nums(下标 从 0 开始 计数): nums.length n nums[i] 是 正整数 &#xf…

Vue组件:使用$emit()方法监听子组件事件

1、监听自定义事件 父组件通过使用 Prop 为子组件传递数据,但如果子组件要把数据传递回去,就需要使用自定义事件来实现。父组件可以通过 v-on 指令(简写形式“”)监听子组件实例的自定义事件,而子组件可以通过调用内建…

Ollama Qwen2 支持 Function Calling

默认 Ollama 中的 Qwen2 模型不支持 Function Calling,使用默认 Qwen2,Ollama 会报错。本文将根据官方模板对 ChatTemplate 进行改进,使得Qwen2 支持 Tools,支持函数调用。 Ollama 会检查对话模板中是否存在 Tools,如…

wlanapi.dll丢失怎么办?有没有什么靠谱的修复wlanapi.dll方法

在遇到各种系统文件错误当中,其中之一就是“wlanapi.dll文件丢失”的问题。这种问题通常发生在Windows操作系统上,特别是当系统试图执行与无线网络相关的任务时。wlanapi.dll是一个重要的系统文件,它负责处理Windows无线网络服务的许多功能。…

一种非接触式智能垃圾桶设计(论文+源码+实物)

1系统方案设计 通过对需求展开分析,本设计非接触式智能垃圾桶采用STM32F103单片机作为控制器,通过红外传感器实现垃圾桶的满溢检测,通过三个SG90舵机分别控制可回收、不可回收、其他垃圾桶盖的开关,并通过WiFi通信模块将数据信息…

Windows编译Hikari-LLVM15[llvm-18.1.8rel]并集成到Android Studio NDK

Windows编译Hikari-LLVM15[llvm-18.1.8rel]并集成到Android Studio NDK 工具1、w64devkit2、ndk3、cmake 编译1、准备工作2、开始编译 集成1、替换文件2、使用 工具 1、w64devkit w64devkit 解压出来给个环境变量 验证一下 2、ndk 通过android studio安装 ndk\27.1.1229…