作者介绍
Wen,携程资深后端开发工程师,专注系统性能、稳定性、交易系统等领域。
一、背景
在现今的信息时代,微服务技术已成为一种重要的解决方案,微服务技术可以使系统的规模和功能变得更加灵活,从而获得更高的可扩展性和可用性。然而,微服务调用中出现的超时问题,却也成为系统可用性的一大隐患。超时会导致客户端的性能下降,甚至可能无法正常工作。本文针对超时问题,提出相关的优化手段,降低微服务调用超时的风险。
1.误区
当我们遇到超时或执行慢的问题时,我们往往会认为是依赖方出现了问题。
例如:访问 Redis、DB、 RPC 接口变慢、超时,第一时间找依赖方排查问题,对方反馈的结论是,我这边(服务端)没有问题,请检查一下你那边(客户端)是否有问题。
实际上,性能下降是一个非常复杂的问题,它可能涉及多个方面,包括服务端和客户端。例如:代码质量、硬件资源、网络状况等问题都会导致性能下降,从而引发响应慢、超时等问题。因此,我们需要全面地分析问题,找出影响性能的各种因素。
2.分享的目的
本文将详细介绍我们在生产环境中遇到的慢执行和超时等问题,并提出相关的优化手段,通过优化长尾性能,降低变慢或超时的风险,提升系统的稳定性。
二、超时的分类
常见的超时一般有两类:
- 连接超时(ConnectTimeout):指建立网络连接所需要的时间超出了设定的等待时间。
- Socket 超时(SocketTimeout):指在数据传输过程中,客户端等待服务端响应的时间超出了设定的等待时间。
如下图,①就是连接超时关注的时间,②就是 Socket 超时关注的时间,本文讲解的超时为 Socket 超时。
图1 客户端请求过程
三、超时问题分析与优化
1.设置合理的超时时间
根据实际情况设置合理的超时时间,避免因为超时时间设置不合理导致的接口超时。
1)分析
看下客户端设置的超时时间是否合理。比如调用服务端 P99.9 是100ms ,客户端设置的超时时间是 100ms ,就会有 0.1% 的请求会超时。
2)优化方案
我们在设置超时时间需要综合考虑网络延迟、服务响应时间、GC 等情况。
以门票活动查询引擎为例:
- 核心接口:最小值( P99.9*3 ,用户可接受的等待时间),核心会影响到订单,在用户可接受范围内尽可能出结果。
- 非核心接口:最小值( P99.9*1.5,用户可接受的等待时间),非核心不影响订单,不展示也没关系。
2.限流
当系统遇到突发流量时,通过限流的方式,控制流量的访问速度,避免系统崩溃或超时。
1)分析
看下超时时间点的请求量是否有突增,比如有某些突然的活动,这个时候应用没有提前扩容,面对突增流量会导致应用负载比较高,从而导致超时问题。
2)优化方案
评估当前应用最大可承载的流量,配置限流,维度可以是单机 集群。
- 单机限流:在面对突增流量时避免单机崩溃。
- 集群限流:在有限的资源下提供最大化的服务能力,保证系统稳定性,不会出现崩溃或故障。
3.提升缓存命中率
提升缓存命中率,可以提高接口的响应速度,降低接口的响应时间,从而减少超时的发生。
1)分析
分析调用链路,找到慢的地方对其进行优化,提升服务端的响应速度。
如下图所示,很明显可以看到服务端执行时间超过了客户端配置的超时时间 200ms 导致超时。
图2 客户端调用服务端超时链路
继续分析服务端执行链路,发现是因为缓存没有命中导致的。
图3 缓存未命中链路
2)优化方案
对于高并发系统来说,常见的是使用缓存来提升性能。
如下图是之前的缓存架构,这种缓存架构有两个风险。
- 缓存是固定过期的,会导致某个时间大量 key 失效直接击穿到数据库。
- 主动刷新机制是删除缓存,监听数据库 binlog 消息删除缓存,如果大批量刷数据会导致大量 key 失效。