服务分级与容量规划
通过依赖的管理,我们能够知道,当前系统调用了哪些服务,被哪些服务调用。接下来,我们便可以根据当前系统所依赖的服务,以及系统的流程,判断依赖的服务是否影响应用的流程,以此来决定当前应用依赖的优先级。
对于服务提供者来说,需要清楚了解当前的服务到底被多少人调用,并建立应用白名单机制,服务调用需要事先申请,以便将调用方增加到白名单当中进行管理和容量规划。为保障系统稳定,对于未知的调用者,最好的方式便是直接拒绝,以免给系统带来不确定风险。如果没有事先的容量规划,当未知的调用者流量突增,很可能将系统拖垮。
服务提供者也需要对服务消费者的优先级进行区分,哪些调用将影响核心链路,哪些调用是非核心链路。当系统压力过大,无法承载的时候,必须 优先确保重要等级高的应用,核心的调用链路优先确保畅通,而对于重要性不那么高的应用,则可以暂时丢车保帅。
优雅降级
当依赖的服务出现不稳定,响应缓慢或者调用超时,或者依赖系统宕机,当前的系统需要能够及时感知到并进行相应处理,否则,大量超时的调用,有可能将当前系统的线程和可用连接数用完,导致新的请求进不来,服务僵死,这便是故障传递。如果处理不及时,故障的传递可将一个非核心链路的问题扩大,引起核心节点故障,最终形成多米诺骨牌效应,使得整个集群都不能对外提供服务。
这样,服务调用优雅降级的重要性便体现出来了。对于调用超时的非核心服务,可以设定一个阀值,如果调用超时的次数超过这个阀值,便自动将该服务降级。此时,服务调用者跳过对该服务的调用,并指定一个休眠的时间点,当时间点过了以后,再次对该服务进行重试,如果服务恢复,则取消降级,否则,继续保持该服务的降级状态,直到所依赖的服务故障恢复。这样,便可以一定程度上避免故障传递的现象发生。
开关
当系统负载较高,即将突破警戒水位的时候,如何通过实时地屏蔽一些非核心链路的调用,降低系统的负载呢?这个时候,需要系统预先定义一些开关,来控制程序的服务提供策略。开关通过修改一些预先定义好的全局变量,来控制系统的关键路径和逻辑,比如,可以定义一个是否允许某一个级别的应用调用当前服务的开关,当系统处于流量高峰期的时候,将非核心链路的调用屏蔽,等高峰期过去之后,再将相应的开关打开。
当然 ,同一个应用,可能也会对外提供多个服务,如果服务耗费系统资源较多,且又不影响系统核心链路,这时,也可以将一些非核心的服务关闭掉,以减轻系统的负担,有效的提高系统对核心应用的服务能力。
建立服务监控、统计、报表
服务运行期间,需要对服务器相应指标进行监控,如系统load、磁盘利用率、内存占用率、网络流量、QPS/TPS 等。
对于服务的调用,需要有统计的报表,按照小时/日/周/月 展示 ,并且通过设置异常情况监控,如流量突增突降,系统要能够及时报警。
应用预案
紧急情况(如双十一、双十二、热点事件等)并不是时时刻刻都发生,大部分人在第一次面对突发事件时,难免会显得手足无措。因此,要想在系统出现故障的情况下能够处变不惊,沉着应对,将损失降到最低,首先得准备一份应急预案,并且,得进行经常性的故障演练,以熟悉各种情况下对应的应急预案的操作流程和规范,避免紧急情况下错误的决策致使损失扩大,并且在实际操作中也能够积累经验。
应急预案中需要明确的规定服务的级别,梳理清楚核心应用的调用链路,对于每一种故障,都做出合理的假设和有针对性的处理方法,对于级别低的调用和功能,事先准备好屏蔽的开关和接口。
场景和问题
以下问题供大家思考
- 场景一:假设某服务最大承受10 000TPS,如果超出是排队等待还是保证10 000TPS范围内请求正常,其他请求直接拒绝?
- 场景二:非核心服务流量洪峰导致核心服务受到影响,如何解决?
- 场景三:某服务有几百个消费者,如果其中一个消费者要求升级,满足一个临时活动,是否要求所有服务同步升级?