高可用架构设计——服务接口高可用
引言
接口级故障的典型表现就是系统并没有宕机,网络也没有中断,但业务却出现问题了。例如,业务响应缓慢、大量访问超时、大量访问出现异常(给用户弹出提示“无法连接数据库”),这类问题的主要原因在于系统压力太大、负载太高,导致无法快速处理业务请求,由此引发更多的后续问题。例如,最常见的数据库慢查询将数据库的服务器资源耗尽,导致读写超时,业务读写数据库时要么无法连接数据库、要么超时,最终用户看到的现象就是访问很慢,一会访问抛出异常,一会访问又是正常结果。导致接口级故障的原因一般有下面几种:
- 内部原因:程序 bug 导致死循环,某个接口导致数据库慢查询,程序逻辑不完善导致耗尽内存等。
- 外部原因:黑客攻击、促销或者抢购引入了超出平时几倍甚至几十倍的用户,第三方系统大量请求,第三方系统响应缓慢等。
1.分级管理
运维将服务器进行分级管理,核心应用和服务优先使用更好的硬件,在运维响应速度上也格外迅速。显然用户及时付款购物比能不能评价商品更重要,所以订单服务比评价服务有更高的优先权。
同时在服务部署上进行必要的隔离,避免故障的连锁反应。低优先级的服务通过启动不同的县城或者部署在不同的虚拟机进行隔离,而高优先级的服务则需要部署在不同的物理机上,核心服务和数据甚至需要部署在不同地域的数据中心。
2.超时
针对服务调用都要设置一个超时时间,以避免依赖的服务迟迟没有返回调用结果,把服务消费者拖死。这其中,超时时间的设定也是有讲究的,不是越短越好,因为太短可能会导致有些服务调用还没有来得及执行完就被丢弃了;当然时间也不能太长,太长有可能导致服务消费者被拖垮。找到比较合适的超时时间需要根据正常情况下,服务提供者的服务水平来决定。具体来说,就是按照服务提供者线上真实的服务水平,取 P999 或者 P9999 的值,也就是以 99.9% 或者 99.99% 的调用都在多少毫秒内返回为准。
3.排队与异步调用
排队指的是,当并发请求很多的时候系统根据请求的先后将请求放到一个队列中进行排队。由于排队需要临时缓存大量的业务请求,单个系统内部无法缓存这么多数据,一般情况下,排队需要用独立的系统去实现,例如使用 Kafka 这类消息队列来缓存用户请求。
- 【排队模块】。负责接收用户的抢购请求,将请求以先入先出的方式保存下来。每一个参加秒杀活动的商品保存一个队列,队列的大小可以根据参与秒杀的商品数量(或加点余量)自行定义。
- 【调度模块】。负责排队模块到服务模块的动态调度,不断检查服务模块,一旦处理能力有空闲,就从排队队列头上把用户访问请求调入服务模块,并负责向服务模块分发请求。这里调度模块扮演一个中介的角色,但不只是传递请求而已,它还担负着调节系统处理能力的重任,可以根据服务模块的实际处理能力,动态调节排队系统拉取请求能力。
- 【服务模块】。负责调用真正业务来处理服务,并返回处理结果,调用排队模块的接口回写业务处理结果。
4.跨公网调用第三方高可用
调用失败后直接返回异常还是重试?
当有一个接口跨公网第三方调用超时时,可能导致所有接口都不可用,即使大部分接口不依赖于跨公网第三方调用。
内部服务对业务方提供的N个接口,会共用服务容器内的工作线程(假设有100个工作线程)。假设这N个接口的某个接口跨公网依赖于第三方的接口,发生了网络抖动,或者接口超时(不妨设超时时间为5秒)。潜台词是,这个工作线程会被占用5秒钟,然后超时返回业务调用方。假设这个请求的吞吐量为20qps,言下之意,很短的时间内,所有的100个工作线程都会被卡在这个第三方超时等待上,而其他N-1个原本没有问题的接口,也得不到工作线程处理。
(1)第三方接口备份与切换
业务场景:调用第三方短信网关,或者电子合同等。
解决方案:同时使用(或者备份)多个第三方服务。
- 业务调用方调用内部service;
- 内部service调用第一个三方接口;
- 超时后,调用第二个备份服务,未来都直接调用备份服务,直到超时的服务恢复;
- 内部service返回结果给业务调用方;
优点:公网抖动,第三方接口超时,不影响内部接口调用(初期少数几个请求会超时)。
缺点:不是所有公网调用都能够像短信网关,电子合同服务一样有备份接口的,像微信、支付宝等就只此一家。
(2)异步调用法
业务场景:本地结果,同步第三方服务,例如用户在58到家平台下单,58到家平台需要通知平台商家为用户提供服务。
解决方案:本地调用成功就返回成功,异步调用第三方接口同步数据(和异步代理有微小差别)。
本地流程
- 业务调用方调用内部service;
- 内部service写本地数据;
- 内部service返回结果给业务调用方成功;
异步流程
- 异步service定期将本地数据取出(或者通知也行,实时性好);
- 异步调用第三方接口同步数据;
优点:公网抖动,第三方接口超时,不影响内部接口调用。
缺点:不是所有业务场景都可以异步同步数据。