微服务架构下服务故障处理解决方案

JavaEdge

共 2497字,需浏览 5分钟

 ·

2021-01-07 19:55


  点击上方“JavaEdge”,关注公众号

设为“星标”,好文章不错过!


微服务优势之一是可缩小故障影响范围,局限在某个服务中。那一个服务出现故障该如何处理?

1 集群故障


可能整个集群都会故障,无法再对外提供服务。



1.1 故障原因


  • 代码bug
    比如OOM

  • 突发的流量冲击,超出了系统的最大承载能力

    比如秒杀,会在某个时刻瞬间涌入大量流量,超出系统承载能力




1.2 解决方案


1.2.1 限流


系统所能承载流量根据集群规模是固定的,称为系统最大容量。当真实流量超过系统最大容量,系统响应就会变慢,服务调用出现大量超时,用户就会感觉卡顿、无响应。所以,应根据系统最大容量,给系统设置阈值,超过阈值的请求会被自动丢弃,便可保证系统服务正常。

通常一个微服务系统会同时提供多个服务,每个服务在同一时刻的请求量也不同,很可能系统中某服务的请求量激增,占用系统大部分资源,导致其他服务无资源可用。

因此,要针对系统中每个服务的请求量设置阈值,超过阈值的请求也要丢弃,不至于因为一个服务影响其他服务。

可用如下指标衡量服务的请求量:

  • QPS

  • 工作线程数

QPS因不同服务的响应快慢不同,所以系统能承载QPS相差大,所以一般选择工作线程数作为限流指标,给系统设置

  • 总的最大工作线程数

  • 单个服务的最大工作线程数

如此,无论是系统总请求量过大导致整体工作线程数量达到最大工作线程数,还是某服务的请求量超过单个服务的最大工作线程数,都会被限流。



1.2.2 降级




通过停止系统中的某些功能,保证系统整体的可用性,属一种被动防御方案,因为一般是系统已故障后所采取的一种止损操作。



如何实现


通过开关,在系统运行的内存中开辟一块区域,专门用于存储开关状态启还是关闭。并且需监听某端口,通过该端口可向系统下发命令以改变内存中开关状态。当开关开启时,业务的某段逻辑就不再执行,而正常情况下,开关是关闭的状态。



适用场景


  • 新增的业务逻辑
    因为新增的业务逻辑相对来说不成熟,充满风险,需加开关控制新业务逻辑是否执行

  • 依赖的服务或资源
    因依赖的服务或资源不总是可靠,最好有开关控制是否对依赖服务或资源发起调用,以保证即使依赖出现问题,也能降级避免影响




分级


  • 一级降级,对业务影响最小的

    故障时,先执行一级降级,所以一级降级也可设置成自动降级而无需人工

  • 二级降级,对业务有一定影响

    故障时,若一级降级起不了啥作用,可采取人工

  • 三级降级,对业务较大影响

    这种降级要么对重大影响金钱交易,要么严重影响用户体验


2 单IDC故障


为保证业务的高可用,部署在不止一个IDC。整个IDC脱网的事情时有发生,多半是因为不可抗力比如机房着火、光缆被挖断。

如果业务全部部署在这个IDC,那就完全不可访问,所以采用多IDC部署。

  • 有的采用同城双活,也就是在一个城市的两个IDC内部署

  • 有的采用异地多活,一般是在两个城市的两个IDC内部署

  • 支付宝这种金融级别的应用采用“三地五中心”部署,这种部署成本显然高比两个IDC要高得多,但可用性的保障要更高

采用多IDC部署的最大好处就是当有一个IDC发生故障时,可以把原来访问故障IDC的流量切换到正常的IDC,来保证业务的正常访问。



流量切换方案


基于DNS解析的流量切换


通过把请求访问域名解析的VIP从一个IDC切换到另外一个IDC。
比如访问“www.baidu.com”,正常情况下北方用户会解析到联通机房的VIP,南方用户会解析到电信机房的VIP,如果联通机房发生故障的话,会把北方用户访问也解析到电信机房的VIP,只不过此时网络延迟可能会变长。

基于RPC分组的流量切换


对于一个服务,如果是部署在多个IDC的话,一般每个IDC就是一个分组。假如一个IDC出现故障,那么原先路由到这个分组的流量,就可以通过向配置中心下发命令,把原先路由到这个分组的流量全部切换到别的分组,这样的话就可以切换故障IDC的流量了。

3 单机故障


集群中的个别机器出现故障,这种情况往往对全局没有太大影响,但会导致调用到故障机器上的请求都失败,影响整个系统的成功率。

发生概率最高的一种故障,尤其对于业务量大的互联网应用来说,上万台机器的规模也是很常见的。这种情况下,发生单机故障的概率就很高了,这个时候只靠运维人肉处理显然不可行,所以就要求有某种手段来自动处理单机故障。

处理单机故障一个有效的办法就是自动重启
你可以设置一个阈值,比如以某个接口的平均耗时为准,当监控单机上某个接口的平均耗时超过一定阈值时,就认为这台机器有问题,这个时候就需要把有问题的机器从线上集群中摘除掉,然后在重启服务后,重新加入到集群中。

注意,需要防止网络抖动造成的接口超时从而触发自动重启。一种方法是在收集单机接口耗时数据时,多采集几个点,比如每10s采集一个点,采集5个点,当5个点中有超过3个点的数据都超过设定的阈值范围,才认为是真正的单机问题,这时会触发自动重启策略。

为了防止某些特殊情况下,短时间内被重启的单机过多,造成整个服务池可用节点数太少,最好是设置一个可重启的单机数量占整个集群的最大比例,一般这个比例不要超过10%,因为正常情况下,不大可能有超过10%的单机都出现故障。

总结


故障时,往往多手段并用,比如单IDC故障,先要快速切换流量到正常IDC,但此时可能正常IDC不足以支撑两IDC流量,所以先要降级部分功能,保证正常的IDC顺利支撑切换过来的流量。

要尽量让故障处理自动化,可大大减少故障影响时间。

往期推荐


大厂如何解决数值精度/舍入/溢出问题

硬核干货:HTTP超时、重复请求必见坑点及解决方案

由于不知线程池的bug,某Java程序员叕被祭天

程序员因重复记录日志撑爆ELK被辞退!

拥抱Kubernetes,再见了Spring Cloud




目前交流群已有 800+人,旨在促进技术交流,可关注公众号添加笔者微信邀请进群


喜欢文章,点个“在看、点赞、分享”素质三连支持一下~

浏览 3
点赞
评论
收藏
分享

手机扫一扫分享

举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

举报