本文介绍MSE微服务治理无损上下线的常见问题。
原先操作面板上的高级功能去哪了?对已经接入的应用有什么影响?我还想开启或关闭应该怎么操作?
应用新接入服务治理的情况下,无需关注本问题内容。
在旧版的无损上下线控制台交互中,提供了高级功能选项。而高级功能涉及比较多的微服务概念,所以新版交互从简化使用的角度考虑,在将其进行了隐藏。旧版的高级功能包含两个子功能:
通过就绪检查前完成服务注册。
新版中仍然提供并默认开启,如果您的应用原先未开启,当您在控制台无损上下线界面重新开启无损上线后会自动开启。如果您的应用原先已经开启了该功能,我们不推荐您关闭。该功能在默认开启的情况下,不会对应用带来负面影响。默认开启的情况下,可以规避发版时特定场景下流量跌零的风险,具体可以参考为什么配置55199/health。
通过就绪检查前完成服务预热。
新版不再提供,该功能最初的设计目的是用来保证预热效果达到预期状态,避免出现开启预热的服务QPS曲线出现陡升的情况。本质上是通过推迟K8s就绪检测通过的时间,来延长整体的发版时间,保障新节点可以有足够的时间进行预热,并且让老节点在这个过程中继续承担一部分流量,不会被快速下掉。这样就可以保证预热的QPS曲线呈现出是一个缓慢升高的状态。如果在发版过程中,新节点在预热时,老节点已经全部下线,那么新节点就需要承受所有的线上流量,从而无法实现“小流量”的预热。原先已经开启该功能的应用不会受到影响,但是新应用设置规则时无法再对该功能进行开启,如果您之前开启了该功能,我们也不推荐您关闭。该功能在开启的情况下,不会对应用带来负面影响。在新版交互中,想要服务小流量预热达到预期效果,可参见小流量预热的最佳实践。
小流量预热的原理是什么?为什么小流量预热需要提供者、消费者都接入服务治理?
当消费者对某个服务进行调用时,会对该服务的提供者进行选择。在提供者应用开启小流量预热的情况下,服务治理对这里“选择提供者”的过程进行了增强。在消费者选择提供者时,会计算每个提供者的权重大小(0%~100%),权重越大的提供者节点,被选择和调用的概率就会越高。开启小流量预热的提供者在刚启动时,消费者对其计算的权重很低,因此预热的节点被调用的概率也会变低,随着时间增加,这个权重计算结果会不断增大,最终达到100%,达到100%时,预热流程就结束了,开始和正常节点一样接收流量。提供者会在服务注册的元数据中,带上自身启动的时间,以供消费者进行权重计算。这个过程需要提供者、消费者双方都开启服务治理才能实现。
小流量预热的“开始”会在应用收到第一笔请求后触发,当预热过程已经达到配置的预热时长后(默认120秒),小流量预热结束。如果应用一直没有收到外部流量,则不会触发预热的开始。
小流量预热触发的前提是有外部流量进来,这就要求服务已经完成了注册。如果您发现应用还未进行服务注册,却已经开始了小流量预热(即您在控制台观察到预热开始事件出现在服务注册事件之前),您可以参考为什么应用先出现预热事件后出现服务注册事件?来解决。
为什么我的预热曲线不符合预期?该如何解决?
阅读该问题之前,建议您先了解一下服务小流量预热的原理。
正常情况下小流量预热时,应用的QPS曲线图如下:
但是有些时候由于不合理或不支持的使用场景,进行小流量预热的应用,其QPS曲线图形状会不太符合预期(缓慢上升),下面是两种常见的不符合预期的情况:
QPS 曲线中途出现陡升现象
这种现象一般发生在服务发布的场景,如果在服务发布时,新节点的预热还没有达到指定时长,老节点就被下线了,那么消费者端在选择提供者时,就无法实现控制新节点被“低概率”调用到了。所以会在 QPS 曲线图中看到,某个新节点的 QPS 曲线在前半段时缓慢上线的态势,达到某个时间节点后,老节点被全部下线,QPS 曲线就出现陡升现象了。您可以参考小流量预热的最佳实践,来解决QPS曲线陡升的问题。
QPS 曲线未呈现缓升趋势
出现这种现象,建议检查对该应用发起请求的消费者应用已经接入服务治理,如果消费者端没接入,则考虑将消费者应用都接入服务治理,就可以解决该问题。如果您需要预热的应用,其流量来自外部(比如Java网关),这种场景下消费者是没有接入服务治理的,小流量预热也无法支持这种场景。
小流量预热的最佳实践是什么?
在滚动发布的情况下,经常会出现预热不充分的问题。您可以参考以下实践,来保证服务预热达到预期效果:
配置最小准备时间(推荐):您可以为工作负载配置
.spec.minReadySeconds
来控制pod就绪后达到可用状态时的时间间隔,并且设置该参数的值大于pod的小流量预热时长,以使得K8s等待 pod 预热完毕后再继续滚动发布。 如果您使用的是ACK,您可以直接在容器平台上找到您的应用,在 更多 > 升级策略 > 滚动升级 > 最小准备时间(minReadySeconds) 中直接设置。(设置 minReadySeconds可以在发布时,让新启动的pod状态达到ready并维持固定时长之后,才会继续发布)使用分批发布(推荐):您可以考虑使用OpenKruise等方式,实现工作负载的分批发布,并且控制每个批次发布时的时间间隔大于小流量预热时长,保证批次内的新节点预热充分后,再继续发布一下次批次的节点。
此外,延长Readiness就绪检测的初始探测时间(不推荐),也是一种方式,您可以增加工作负载Readiness 的首次探测延迟时长(initialDelaySeconds),并且大于小流量预热时长、延迟注册时长、应用启动时间三者之和。注意,应用启动时间一般需要观测实际日志输出来得出,并且随着业务发展,应用的启动时间也会随之变化;此外,延迟 Readiness 通过的时间,也会导致新启动的节点迟迟无法被加入到 K8s Service的Endpoint中,因此我们不推荐您使用这种方式来保证预热效果达到最佳。
如果您按照最佳实践进行操作后,发现预热QPS曲线仍然不符合预期,可以考虑应用接收的流量,是否都来自于已经接入服务治理的消费者应用,如果有消费者没有接入服务治理,或者存在来自于外部负载均衡的调用流量,那么应用预热时的QPS曲线图也会不符合预期。
55199/health是做什么的?为什么不配置55199/health会有流量跌0的风险?
55199/health
是MSE微服务治理提供的一套内置的、HTTP类型的就绪检查端口,当应用的K8s就绪检查配置成55199/health
时,在新节点上线阶段,如果该节点尚未完成服务注册,则就绪检查返回500;如果该节点已经完成服务注册,则就绪检查返回 200。
按照 K8s 默认的发布策略,新节点没有就绪,老节点就不会下线。当就绪检查配置了55199/health
之后,新节点完成服务注册之后,才会进入就绪状态,即只有在新节点完成服务注册的情况下,老节点才会下线。这样就会保证注册中心上该服务一直会有可用的节点。如果您不配置55199/health
,可能会在服务发布时,新节点尚未注册,老节点就被下线,进而导致注册中心上该服务没有可用节点,进而导致该服务的所有消费者在调用时因为没有提供者而发生报错,从而产生该服务的流量跌0。因此我们强烈建议您开启无损上线,并为应用配置55199/health
就绪检测。
为什么应用先出现预热事件后出现服务注册事件?如何解决?
在当前版本下,服务收到了第一笔外部请求时,就会开始预热流程,并且上报预热开始事件。而有些时候,应用收到的第一笔请求,未必是微服务调用请求,因此这种请求也不会触发业务逻辑的预热。比如应用的工作负载配置了K8s的Liveness探针,在新节点上线时,即便还没有进行服务注册操作,只要K8s对Liveness进行了探测,就会判定预热已经开始。
为了避免这种情况, 您可以在提供者应用工作负载的环境变量中,配置如下参数,来忽略这些请求对预热逻辑的触发:
# 忽略路径为 /xxx、/yyy/zz 的请求对预热流程的触发
profile_micro_service_record_warmup_ignored_path="/xxx,/yyy/zz"
该参数也支持 Jvm 启动参数的方式进行配置。
该参数的值不支持正则匹配。
主动通知是做什么的?什么时候需要开启主动通知?
主动通知是无损下线功能模块提供的一种进阶能力,该功能可以在SpringCloud提供者下线时,让提供者主动发起一次网络请求到服务消费者,告知其自身已经下线。消费者收到通知后,不会再对该节点进行调用。一般情况下,当提供者消费者都使用SpringCloud框架时,消费者本地会缓存提供者节点列表。在某些场景下,即便消费者收到注册中心的通知,也可能没有及时刷新本地缓存,进而导致消费者对下线的节点仍然发起调用。主动通知则很好地解决了这个问题。
主动通知功能默认关闭,因为开启服务治理之后,默认的无损下线方案中,下线阶段的提供者收到请求时,会在响应中加入一个特殊的header
,消费者收到响应时会识别该header
,并且不再调用该提供者节点。因此,只要在提供者下线时,消费者有流量到达下线的提供者,就会感知到该提供者已经下线,并且会自动将其“拉黑”。而如果在提供者下线的这段时间内(一般30秒左右),消费者没有请求到达正在下线的提供者,消费者就有可能未感知到该提供者节点已经下线,有可能会在提供者刚好走完下线流程、即将停机时,消费者请求正好过来,此时就会出现请求报错的问题。这个时候,就需要开启主动通知。换句话说,如果消费者的流量非常“稀疏”,就建议您为提供者开启主动通知的功能。
为什么已经看到无损下线事件后,流量还是没有快速降为0?
一般情况下,看到无损下线事件后,流量会在短时间内快速降为0。如果没有降为0,可能的原因和解决方案如下:
该应用收到了非微服务方式的调用,比如收到来自外部负载均衡器的流量,或者存在本地脚本、定时任务等调用方式产生了流量。
目前无损上下线只支持治理内部微服务调用的流量,上述场景并不在无损上下线功能支持的范围之内。建议您根据这些基础设施、框架提供的优雅下线特性来定制相应的解决方案。
该应用需要开启主动通知,但是没有开启。(您可以参考本文了解主动通知)
建议您开启主动通知后再次观测下线曲线是否符合预期。
该应用使用的框架版本不在支持的范围之内,服务治理无损上下线支持的框架可以参考:微服务治理支持的Java框架。
如果您发现应用使用的框架版本不在支持版本之中,可以考虑对应用的框架版本进行升级。