会员服务优雅上下线实践
随着会员业务的快速发展,会员系统架构也不断演进迭代,拆分出了多个微服务,提升了系统的稳定性和扩展能力。在敏捷的开发模式下,业务迭代更加快速,那么势必会经常发布线上服务,在服务上线的过程中,我们发现接口成功率会出现一定程度的下降,对于敏感业务直接影响了用户的体验。为了解决这个问题,我们对微服务上下线流程进行了优化,本文将详细介绍方案的设计和实现。
01
问题分析
通过梳理服务流程发现,引起服务可用性降低、响应时间突增的原因有以下几点:
02
解决方案
系统以集群方式提供服务,实例的上下线状态对业务无感知,由组件封装实例的状态转换,通过优雅上线、优雅下线组合来保证服务的无损发布。
通过预热功能实现资源初始化,预热模块是可插拔的,可全使用或者仅使用其中一个模块:
优雅下线通过延迟下线和可靠负载功能组合实现,在下线过程中,服务实例需要先去取消注册并将自己标记为已下线,后续的接口请求都将获取到该实例的已下线标记。服务调用方根据下线标记把该实例从可用服务列表中剔除,保证在后续一定时间窗口内的请求都不会再打到这个实例上。具体交互流程见下图:
03
成果与总结
对接优雅上下线功能的服务在上线过程中,服务成功率可以提升到99.99%以上,有效解决了服务上线成功率的问题。对比数据见下图示例:
无优雅上下线(并行1台滚动上线)
开启优雅上下线(并行1台滚动上线)
参考阅读:
本文由高可用架构转载。技术原创及架构实践文章,欢迎通过公众号菜单「联系我们」进行投稿。
异常情况分析
业务系统当前使用的是 Spring Boot 和 Spring Cloud 框架,服务发布流程如下图所示:通过梳理服务流程发现,引起服务可用性降低、响应时间突增的原因有以下几点:
-
过早销毁对象: 服务正在处理请求,但此时对象被销毁导致请求报错。
-
服务未及时下线: 调用方不能及时感知服务已在下线中,仍会发送请求过来,但此时对象可能已经被销毁导致请求报错。
-
过早注册服务: 服务未初始化完成就被注册到了注册中心,导致接口响应时间突增甚至超时。
优化方向
基于上面的分析,可以通过以下方式解决相关的问题:- 在上线过程中,当服务把依赖的资源都初始化完成后,才将实例注册到注册中心。
- 在下线过程中,服务调用方可以排除正在下线的实例,保证在一定的时间窗口内请求不会打到这个实例上。
系统以集群方式提供服务,实例的上下线状态对业务无感知,由组件封装实例的状态转换,通过优雅上线、优雅下线组合来保证服务的无损发布。
优雅上线
通过预热功能实现资源初始化,预热模块是可插拔的,可全使用或者仅使用其中一个模块:
-
自定义预热: 由业务方自行扩展实现预热逻辑。
-
线上请求回放预热: 配置预热接口,拉取线上请求对本地服务预热,当接口调用达到配置的预热次数后,再将服务注册到注册中心。
- 预热
- VClientAutoConfiguration:服务注册配置类,负责初始化GracefulServiceRegistration
- GracefulServiceRegistration:服务注册类,触发服务预热逻辑执行
- WarmUp:预热组件,由业务方自行扩展实现预热逻辑。框架默认实现:延迟5s(可配置)再执行服务注册、线上请求回放预热
优雅下线
优雅下线通过延迟下线和可靠负载功能组合实现,在下线过程中,服务实例需要先去取消注册并将自己标记为已下线,后续的接口请求都将获取到该实例的已下线标记。服务调用方根据下线标记把该实例从可用服务列表中剔除,保证在后续一定时间窗口内的请求都不会再打到这个实例上。具体交互流程见下图:
-
延迟下线
- VClientAutoConfiguration:服务注册配置类,负责初始化 InvokePlugin、GracefulServiceRegistration 等组件
- GracefulServiceRegistration:服务注册类,负责延迟销毁对象、触发服务预热逻辑执行
- InvokePlugin:请求调用插件类,负责执行请求时检查服务实例状态是否在下线中,如果在下线中,直接返回下线标记
-
可靠负载
对接优雅上下线功能的服务在上线过程中,服务成功率可以提升到99.99%以上,有效解决了服务上线成功率的问题。对比数据见下图示例:
无优雅上下线(并行1台滚动上线)
开启优雅上下线(并行1台滚动上线)
—— 活动推荐——
参考阅读:
- 可视化服务编排在金融APP中的实践
- 长路漫漫, 从Blink-tree 到Bw-tree (上)
- Redis 定长队列的探索和实践
- 31个!Golang常用工具来啦(建议收藏)
- 京东科技埋点数据治理和平台建设实践