从一个服务预热不生效问题谈微服务无损上线

作者:凡问、启淮

前言

本文基于阿里云技术服务团队和产研团队,在解决易易互联使用 MSE(微服务引擎)产品无损上线功能所遇到问题的过程总结而成。本文将从问题和解决方法谈起,再介绍相关原理,后进一步拓展到对微服务引擎和云原生网关无损上线能力的介绍。

易易互联是吉利集团旗下的企业,专注于新能源汽⻋换电业务,提供便捷的换电解决⽅案,成⽴于 2017 年。

易易互联的核⼼业务围绕换电技术与服务展开,包括换电站的研发、建设和运营、电池销售与租赁、以及与之相关的技术服务如电池管理、云平台监控等。其换电站具备⾼智能化特点,配备全天候智能温控系统,⽀持恒温慢充和动态巡检,确保电池充电过程的⾼效与安全,同时实现⻋、站、云平台之间的互联互通。截至 2024 年 5 月,易易互联已在重庆、杭州、 广州、成都、天津等 30 多个城市布局和运营超 400 座换电站,已是营运市场换电补能领域的领先品牌。

易易互联后端采⽤微服务架构,因为换电业务系统包含⻋、站、云三个平台,并且其物联⽹+互联⽹的业务特点,在业务快速迭代的同时,对业务稳定性也有着⾮常⾼的要求。因此,很早开始,易易互联便引⼊ MSE(微服务引擎),通过服务治理的⼀系列功能,提升微服务架构应⽤的研发效率和稳定性。

起因

1.1 客户案例

MSE(阿里云微服务引擎,以下简称 MSE)无损上下线能力可以很好地规避变业务迭代与变更带来的流量损失,保证了业务的连续性,为高增长业务提供坚实的技术保障。而最近易易互联在使用过程中反馈了一例服务无损上线相关问题:服务预热开始时间早于服务注册时间,导致服务上线流量有损。客户对此不解,更是想了解其影响和背后原因原理。

客户的应用的无损上线各功能的执行顺序及业务流量则如下图所示:

在这里插入图片描述

而【无损上线 [ 1] 】官方文档预热曲线如下图:

在这里插入图片描述

执行顺序从上图可看到有两个特点:

  1. 预热开始的时间点确实早于服务注册的时间点。

  2. 预热开始后的 QPS 呈现均匀脉冲形状。

为何上述两幅图的顺序不一致呢?通过原理分析和测试验证,确定问题原因是 K8s liveness 探针配置了 Spring Boot Actuator health 接口,而 MSE 将对 Spring Boot Actuator health 接口调用判断为服务预热开始导致。

1.2 如何避免服务预热误判

接下来讨论如何避免误判问题的发生。对于此问题的回答,我们通过介绍 Spring MVC 请求处理流程和服务预热判断的实现原理来详细说明。

在这里插入图片描述

如上图所示:

① 针对 Spring Boot/Cloud 应用,包括服务预热判断在内的很多 MSE 核心逻辑是通过在 DispatcherServlet 上增强实现的。 DispatcherServlet 是 Spring MVC 中用来统一处理请求分发的核心组件。

② 进一步,针对不同请求的分发处理,通过 HandlerMapping 完成,HandlerMapping 的一种实现便是用来处理 Actuator 请求的 EndpointHandlerMapping 组件。

③ 如果发现请求是访问 Actuator Endpoint 的,EndpointHandlerMapping 就会把请求分发至对应组件,如 /actuator/info转发至 InfoEndpoint。而对于健康检查请求 /actuator/health则分发至 HealthEndpoint。

通过上面的流程可见,因为对服务预热判断的逻辑是在 DispatcherServlet,而判断健康检查的组件在 DispatcherServlet 之后的 HandlerMapping,导致 MSE 要想准确判断请求是正常业务 RPC,还是健康检查这样的非业务调用,存在相当困难。这也是导致此问题的核心原因。

而解决此问题的直接方法,也是通过增加配置,告知 MSE,哪些请求不用纳入服务预热判断逻辑。 具体方法如下:

避免服务预热误判的直接方法

在应用运行时的环境变量中增加如下配置,可避免误判问题:profile_micro_service_record_warmup_ignored_path=<skip_urls,如 /actuator/health,多个地址用,分割>

但上述方式,要引入额外配置,有一定侵入性,也不便在大规模组织中统一规范,不算是最优方案。那是否有更好的方式?

通常情况,K8s liveness 配置 TCP 协议即可,并不一定需要配置 HTTP。而将 K8s liveness 探针配置为 TCP 协议,并不会触发此问题,那能否通过此方案作为解决方案?

如何使用方可以统一和规范 K8s liveness 探针配置,配置为 TCP 不失为一种规避方案。但从产品角度,不能假定所有客户都这样做。并且将 K8s liveness 配置 HTTP 协议探针,能更准确反映服务的真实状态,也有不少使用场景,因此不能将强制 TCP 作为解决方案。

对于如何更优雅地解决此问题方面,目前正在考虑的方向包括自动识别并忽略用户的存活探针/就绪探针等端点、RPC 流量打标等方法。

前者可以一定程度上避免显式配置问题,但无法完全解决此问题。而后者通过解决如何判断流量是否来自于真实的业务调用这一核心问题解决。在 Consumer 发起服务调用时,给请求 header 中加上某个特定的标签。Provider 侧在接收流量时,在首次检测到请求带有这些标签时,就可以认定此时服务预热开始,并上报相关事件。这种方式最为精确,但需要服务 Provider/Consumer 全部接入 MSE。因此,最终方案应该是综合使用多种手段,屏蔽技术复杂性,使得服务预热更加有效。

1.3 再谈微服务的无损上线

MSE 微服务治理的无损上线功能是在 21 年底正式上线。微服务无损上线的功能,最早产生在需求快速迭代,强调研发效率的互联网行业,以及注重稳定性的 ToB 行业。

而近些年,以汽车为代表的传统行业,随着愈加注重数字化,对软件系统的稳定性和研发效率日益重视,也盼望着微服务治理等技术的普及和易用。

如果没有无损上线能力,当应用发布或因弹性调度而导致的应用重启,应用将产生如错误率增加、RT 升高等表现。随着微服务的拆分,链路上的任意环节的上述问题,就可能导致全链路的异常表现。而在互联网 ToC 业务领域,除了少部分如支付、出行关乎民生的基础服务外,多数可能只会影响娱乐、消费等场景。但当传统行业也数字化之后,微服务稳定性将进一步影响我们生活的方方面面,如汽车行业中的车控、充电等功能。

纵观整个为服务治理,可分为开发态、变更态和运行态。 这三个领域中,变更态是有研发行为主动产生,对线上环境会有直接影响的领域。而变更态中的治理技术,则可分为无损上下线和全链路灰度两大部分。由此也可见无损上线的重要性。

在这里插入图片描述

面对如此重要的无损上线功能,虽然功能在正式发布后经过了多年打磨,但因为微服务治理技术面临的主要难题是与众多技术以及不同的配置方式的相互整合,难免出现不相兼容匹配的情况。当出现这种问题时,除了产品的优化改进外,从产品原理角度理解,进而按照最佳方式使用,也是关键。

实现无损上线的三大功能

本节将再对 MSE 无损上线进行介绍,以帮助大家用好此特性。

MSE 服务治理无损上线特性提供了三种功能,分别是延迟注册、小流量服务预热和就绪检查。

在这里插入图片描述

服务延迟注册采用被动等待的策略,以便在引入外部服务调用前,应用内部组件已完成初始化。 现代应用所依赖的外部服务和技术众多,导致内部组件众多,且关系复杂,最终导致生命周期的复杂化。在这种情况下,通过增加等待时间,以是应用在提供服务前完成初始化,便成为最简单的选择。

但有一些组件,如内置了开启延迟初始化的连接池、线程池的组件,必须通过真实调用才能触发组件初始化。但直接放入全量调用,有难免产生大面积的服务抖动。此时便需要第二种功能,服务小流量预热。 小流量预热方法通过在服务消费端根据各个服务提供者实例的启动时间计算权重,结合负载均衡算法,控制刚启动应用流量随启动时间逐渐递增到正常水平的这样一个过程,帮助刚启动运行的服务进行预热。需要微服务 Comsumer 和 Provider 都有 MSE 服务治理功能纳管才能实现。如同服务延迟注册的时长一样,服务小流量预热的时长也没有统一标准,而是需要根据线上实际情况,以及测试结果,通过观察错误率、RT 等指标,逐步调整而得。

此外, MSE 无损上线还提供了一套进阶能力,来解决 K8s 场景下,服务变更潜在的流量损失和 RT 升高的问题。在 K8s 滚动发布应用时,如果发布中的应用,其 readiness 探测已经成功,则 K8s 会认为当前应用已经做好准备,并把流量路由到这个应用中。再按照默认的滚动发布策略,老的节点就会被下线。在这个前提下,我们就应该考虑好,readiness 探测通过后,到底有没有准备好接收流量?

无损上线功能考虑到这个场景,提供了一套内置的就绪检查。如果用户使用了无损上线提供的就绪检查,那么 K8s readiness 会在服务注册完毕后,才会通过,这样可以保证至少正在上线的应用已经注册到注册中心,可以被消费者应用发现和调用,避免了新节点还没注册,老节点就被下线,进而带来的消费者应用发起调用时,出现没有可用节点的问题。

此外,在 K8s 上服务发布时,可能会在一个比较短的时间内,将所有老节点替换成新启动的节点。而提供服务的这些新节点,可能还没有进行充分预热,此时系统的整体 rt 难免会变长。所以无损上线还提供了通过就绪检测前完成服务预热的功能,可以保证按照 K8s 默认滚动发布策略的情况下,新创建的节点在预热结束之后,老 Pod 才会被 K8s 下线,避免了平均 RT 升高的问题。

如需使用这些进阶功能,您需要将就绪检查配置成 MSE 服务治理提供的就绪检测端口,如下:

在这里插入图片描述

云原生网关的无损上线能力

除了上述场景,微服务网关也是一类需要考虑无损上线能力的场景。阿里云 MSE 云原生网关产品,也提供了相应的特性。

应用发布经常会在网关上看到 5XX 错误码上升,影响客户体验。这是因为应用启动瞬间缓存没有 ready 等原因,突然大量流量涌入会导致处理慢,请求 RT 上涨,最终导致客户调用服务超时,并且用户流量越大这个问题越严重。为了解决这个问题,MSE 云原生网关也提供了服务预热能力,使用方法如下:

步骤 1: 在服务管理中配置负载均衡策略,将预热时间改成 60s(60s 内逐渐把流量调大,该值为经验值)。

在这里插入图片描述

步骤 2: 假设后端有 2 个 Endpoint 滚动发布,节点逐步从低到高调整权重,放大流量,从而用小流量预热系统,保证上线流量无损。

在这里插入图片描述

🔔 注: 在观察上述预热过程中,有用户反馈错误码减少的同时,没有看到曲线平缓上升过程。通常原因是观测大盘的采样周期是分钟级,看不到 60s 内的变化情况。如果希望看到观测效果,可以把预热时间调大,或者把采样周期调整到秒级(会导致可观测成本增加)。

小结

在后续版本的 MSE 微服务治理中,将考虑前述的改进措施,避免显式配置,从而解决服务预热误判问题的同时,简化使用 ,降低门槛。

进一步,比微服务治理功能更重要是,MSE 所代表的技术如何更好地推动云原生落地。目前无损上线特性所提供的功能,是通过增加自适应的时间来提供更稳定的服务,这与云原生的弹性伸缩强调的快速响应有所不同。如何在快速和稳定之间寻找一个最佳的平衡,一直是云原生技术人不得不面对的重要课题。

不过目前而言,微服务治理和弹性伸缩技术还处于技术普及阶段,尤其是正在进行数字化转型的行业和领域。重点仍是普及和用好 MSE 微服务引擎的各种功能。因此,希望大家能多多使用 MSE 微服务治理,包括无损上线在内的各项功能。如遇问题,可通过各种服务渠道,如工单或企业技术服务等,反馈问题。阿里云将和客户一起共同推动云原生技术发展。

相关链接:

[1] 无损上线

https://help.aliyun.com/zh/mse/user-guide/graceful-start

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

4.11.seq2seq 序列到序列学习

序列到序列学习(seq2seq) ​ 使用两个循环神经网络的编码器和解码器&#xff0c;应用于序列到薛烈类的学习任务。 ​ ​ 在图中&#xff0c;特定的"<eos>"表示序列结束词元。一旦输出序列生成此词元&#xff0c;模型就会停止预测。在循环神经网络解码器的初…

JS+CSS案例:可适应上下布局和左右布局的菜单(含二级菜单)

今天,我给大家分享一个原创的CSS菜单,整个菜单全由CSS写成,仅在切换布局时使用JS。合不合意,先看看效果图。 本例图片 接下来,我来详细给大家分享它的制作方法。 文件夹结构 因为涉及到了样式表切换,所以,你需要借鉴一下我的文件夹结构。 CSS文件夹: reset.css 用于…

维吉尼亚密码加解密实现(python)

维吉尼亚密码 原理 维吉尼亚密码&#xff08;Vigenere&#xff09;是使用一系列凯撒密码组成密码字母表的加密算法&#xff0c;属于多表密码的一种简单形式。 下面给出一个例子 明文&#xff1a;come greatwall 密钥&#xff1a;crypto首先&#xff0c;对密钥进行填充使其长…

【算法】普里姆算法解决修路问题

应用场景——修路问题 1.某地有 7 个村庄&#xff08;A&#xff0c;B&#xff0c;C&#xff0c;D&#xff0c;E&#xff0c;F&#xff0c;G&#xff09;&#xff0c;现在需要修路把 7 个村庄连通 2.各个村庄的距离用边线表示&#xff08;权&#xff09;&#xff0c;比如 A - …

ORM工具之SQLAlchemy

SQLAlchemy是Python编程语言下的一款开源软件。提供了SQL工具包及对象关系映射&#xff08;ORM&#xff09;工具&#xff0c;使用MIT许可证发行。 SQLAlchemy“采用简单的Python语言&#xff0c;为高效和高性能的数据库访问设计&#xff0c;实现了完整的企业级持久模型”。SQL…

从 Pandas 到 Polars 四十四:Polars 和 数据可视化库Seaborn

在我对Matplotlib感到沮丧并发表帖子时&#xff0c;我的朋友让我试试Seaborn库。近年来我一直在使用Altair&#xff0c;因此并没有过多考虑Seaborn。然而&#xff0c;Seaborn的新界面给我留下了深刻印象&#xff0c;并且我很高兴地发现&#xff0c;Seaborn将直接接受Polars的Da…

【web安全】权限漏洞之未授权访问

一.Jenkins未授权访问漏洞 步骤一&#xff1a;使用以下fofa语法进行搜索 port"8080" && app"JENKINS" && title"Dashboard [Jenkins]" 步骤二&#xff1a;进入执行页面http://xxx.xxx.xxx.xxx:xxxx/manage/script/index.php 执…

Linux下自动监控进程运行状态

目录 背景应用举例1、使用crontab脚本监控服务2、使用shell脚本监控服务2.1 编写自定义监控脚本2.2 运行脚本 背景 假设有一个服务需要长期运行&#xff0c;但可能会由于某种原因导致服务意外停止&#xff0c;不能及时发现&#xff0c;某天来到公司后发现出问题了才意识到服务…

(Qt) QThread 信号槽所在线程

文章目录 &#x1f481;&#x1f3fb;前言&#x1f481;&#x1f3fb;Code&#x1f481;&#x1f3fb;‍♂️Code&#x1f481;&#x1f3fb;‍♂️环境 &#x1f481;&#x1f3fb;当前线程信号&#x1f481;&#x1f3fb;‍♂️默认效果&#x1f481;&#x1f3fb;‍♂️Qt::…

最新CSS3伪类和伪元素详解

第4章 伪类和伪元素 4.1结构伪类 E:first-child{},第一个元素 样式&#xff1a; p:first-child {color: red; } <div><p>Lorem ipsum</p><p>Dolor sit amet.</p> </div> 4.1.1nth-*伪类 以计数为基础的&#xff0c;默认情况下&…

探索下一代互联网协议:IPv6的前景与优势

探索下一代互联网协议&#xff1a;IPv6的前景与优势 文章目录 探索下一代互联网协议&#xff1a;IPv6的前景与优势**IPv6 的特点****IPv6的基本首部****IPv6的地址****总结** 互联网的核心协议&#xff1a;从IPv4到IPv6 互联网的核心协议IP&#xff08;Internet Protocol&#…

Docker Deskpot出现Docker Engine Stopped的解决历程

前提&#xff1a;我的操作系统是Win11家庭版, Docker Descktop下载的是最新版&#xff08;此时是4.30.0&#xff09; 出现了如图所示的问题“Docker Engine Stopped”,个人认为解决问题的关键是第四点&#xff0c;读者可以直接看第四点&#xff0c;如果只看第四点就成功解决&am…

python开发上位机 - PyCharm环境搭建、安装PyQt5及工具

目录 简介&#xff1a; 一、安装PyCharm 1、下载 PyCharm 2、PyCharm安装 1&#xff09;配置安装目录 2&#xff09;安装选项 3、问题及解决方法 二、安装PyQt5 1、打开 Pycharm&#xff0c;新建 Project 2、安装 pyqt5 3、安装很慢怎么办&#xff1f; 4、安装 pyq…

RHCSA第三次作业

磁盘管理及分区&#xff1a; [rootMYyyy ~]# fdisk /dev/sda [rootMYyyy ~]# lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS sda 8:0 0 10G 0 disk └─sda1 8:1 0 9G 0 part sdb 8:16 0 30G 0 disk sdc …

docker 部署 mysql8

命令 docker run --restartalways --name mysql8 -v /data/mysql/conf:/etc/mysql -v /data/mysql/data:/var/lib/mysql -v /data/mysql/log:/var/log -v /data/mysql/mysql-files:/var/lib/mysql-files -p 3308:3306 -e MYSQL_ROOT_PASSWORD123456 -d mysql:8 \解释 --rest…

基于SpringBoot框架的企业财务管理系统设计与实现(论文+源码)_kaic

摘 要 在快速增长的信息时代&#xff0c;每个企业都在紧随其后&#xff0c;不断改进其办公模式。与此同时&#xff0c;各家企业的传统管理模式也逐步发生变化&#xff0c;政府和企业都将需要一个更加自动化和现代化的财务管理系统。这能够便利员工之间的信息交流和公司的工作…

day22回溯学习记录第一天- - -代码随想录

77.组合 给定两个整数 n 和 k&#xff0c;返回范围 [1, n] 中所有可能的 k 个数的组合。 你可以按 任何顺序 返回答案。 思路:回溯的经典题目&#xff0c;回溯的整体结构类似于二叉树&#xff0c;如下图所示。据此图可知&#xff0c;采用递归是一种解决方法&#xff0c;在此引入…

定点数的运算

目录 1.定点数的移位运算 1.1算数移位 数学含义&#xff1a; 规律总结&#xff1a; 1.2逻辑移位 1.3循环移位 不带进位位 带进位位 2.定点数的加减运算 3.定点数的乘除运算 3.1原码 一位乘法 除法 3.2补码 一位乘法 除法 1.定点数的移位运算 1.1算数移位 数学…

Java日志框架

笔记学习原视频&#xff08;B站&#xff09;&#xff1a;全面深入学习多种java日志框架 目前常见日志框架有&#xff1a; JULLogbacklog4jlog4j2 目前常见的日志门面&#xff08;统一的日志API&#xff09;&#xff1a; JCLSlf4j 一、 老技术&#xff08;基本都弃用了&…

STM32——外部中断(EXTI)

目录 前言 一、外部中断基础知识 二、使用步骤 三、固件库实现 四、STM32CubeMX实现 总结 前言 外部中断&#xff08;External Interrupt&#xff0c;简称EXTI&#xff09;是微控制器用于响应外部事件的一种方式&#xff0c;当外部事件发生时&#xff08;如按键按下、传感器信号…