混沌演练状态下,如何降低应用的MTTR(平均恢复时间) | 京东云技术团队

news2024/11/23 11:50:27

在企业业务领域,锦礼是针对福利、营销、激励等员工采购场景的一站式解决方案,包含面向员工、会员等弹性激励SAAS平台。由于其直接面向公司全体员工,其服务的高可用尤其重要,本文将介绍锦礼商城大促前夕,通过混沌工程实战演习,降低应用的MTTR。

MTTR(平均恢复时间)是从产品或系统故障中恢复所需的平均时间。 这包括整个中断时间——从系统或产品出现故障到其恢复完全运行为止。

如何在混沌演练的场景中降低应用的MTTR,必须需要根据监控定位,然后人工进行反馈进行处理吗?是否可以自动化,是否有方案可以降低混沌演练过程中的影响?以此达到快速止血,进一步提高系统的稳定性。

本篇文章将根据一些思考和实践来解答以上问题。

故障无处不在,而且无法避免。

我们将从宿主机重启问题以及底层服务混沌演练的排查与举措说起。

背景

【客户端视角】:出现大量接口(包括提单)超时报错、可用率跳点,部分客户命中,产生客诉。

通过定位发现大促备战前期宿主机重启及底层服务混沌演练原因,较长时间影响我侧系统可用率及性能。尤其是核心接口的部署应用,会大范围的影响到多个接口的可用率,进一步影响采购端客户的体验问题。

特别在TOB领域,本身就存在大客户的口碑效应,如果恰好头部客户碰到该问题,那么极易被放大和激化。

临时举措

一方面协同运维组确认宿主机重启未及时通知的情况,另一方面与底层服务提供者同步演练影响,建议其遵守演练原则最小化爆炸半径,控制影响范围,保证演练是可控的。

除了以上协同外部的情况外,我们内部也产生了思考,首先情况故障本身就是不可控的,无论宿主机还是混沌演练,真实场景也是有概率发生的(并且已发生)。那么我们只能通过监控定位,然后手动摘除机器或者通知服务提供者处理吗?是否可以自动化,是否有方案可以降低影响?以此达到快速止血,进一步提高系统的稳定性。

长期方案——JSF中间件能力实践

既然无法避免故障,那么就拥抱故障,通过一些技术手段来构建获取应用故障的能力,从而保证应用的高可用。

由于内部的调用90+%为(JSF)RPC调用,所以我们还是把目光放到了JSF中间件的容错能力上,以下主要介绍通过JSF中间件的超时与重试、自适应负载均衡、服务熔断来进行故障转移的理论与实践。

实践是检验真理的唯一标准。

关于超时和重试

实际开发过程中,相信大家也见过太多由于超时未设置、设置有误导致的故障。当超时未设置或者设置不合理,会导致请求响应变慢,慢请求的不断累计叠加,就会引起连锁反应,甚至产生应用雪崩。

不仅我们自身的服务,还有外部的依赖服务,不仅HTTP服务,还是中间件服务,都应该设置合理的超时重试策略,并且重视起来。

首先读写服务的超时重试策略也是大不相同的,读服务天生适合重试(如设置合理超时时间后重试两次),但是写服务大多是不能重试的,不过如果均是幂等设计,也是可以的。

另外设置调用方的超时时间之前,需要先了解清楚依赖服务的TP99响应时间是多少(如果依赖服务性能波动大,也可以看TP95),调用方的超时时间可以在此基础上加50%Buff。当然服务的响应时间并不是恒定的,在某些长尾条件下可能需要更多的计算时间,所以为了有足够的时间等待这种长尾请求响应,我们需要把超时设置足够合理。

最后重试次数不宜太多(高并发时可能引发一系列问题(一般2次,最多3次),虽然重试次数越大,服务可用性越高,但是高并发情况下会导致多倍的请求流量,类似模拟DDOS攻击,严重情况下甚至于加速故障的连锁发生。因此超时重试最好是和熔断、快速失败等机制配合使用,效果更佳,这个后面会提到。

除了引入手段,重要的是验证手段的有效性。

模拟场景(后续另两个手段也是用该场景)

方案:采用故障注入(50%机器网络延迟3000-5000ms)的方式模拟类似场景,并验证。

机器部署如下

压测接口(QPS-300)及故障接口监控Key值

1、压测接口:jdos_b2b2cplatform.B2b2cProductProviderImpl.queryProductBpMap

2、服务消费:jdos_b2b2cplatform.ActivityConfigServiceRPCImpl.queryActivityConfig

3、服务提供:jdos_b2b2cshop.com.jd.ka.b2b2c.shop.service.impl.sdk.ActivityConfigServiceImpl.queryActivityConfig

【注意】网络场景不支持如下情形:

1、应用容器所在机房:xxx

2、物理机的内核版本:xxx

正常情况(未注入故障)

注入故障——超时设置不合理情况下(超时2000ms,重试2)

注入故障——超时设置合理情况下(超时10ms,重试2)

该接口TP99在6ms,设置超时10ms,重试2。即:jsf:methodname="queryActivityConfig"timeout="10"retries=“2”/

超时重试小结

通过合理的超时重试,整体请求平稳,重试后的故障转移,大幅提升接口可用率。

超时重试补充

在接口维度拆分不合理的情况下,我们可以更细粒度的使用方法维度的超时重试配置,不过这里有一个注意项JSF当前注解方式不支持方法维度的超时重试设置,仅支持接口维度,如已使用注解类,可进行迁移XML方式进行配置使用,

关于自适应负载均衡

对于shortestresponse自适应负载均衡设计目的是解决在 provider 节点能力不均的场景下,让处理能力较弱的provider少接受些流量,不会因个别性能较差的 provider 影响到 consumer 整体调用的请求耗时和可用率。

能者多劳拙者闲,智者多忧愚者无所虑。

但是该策略下也是存在一些问题的:

  1. 流量的过度集中高性能实例,服务提供者的单机限流或成为瓶颈。
  2. response的时间长短有时也并不能代表机器的吞吐能力。
  3. 大多数的场景下,不同provider的response时长在没有非常明显的区别时,shortestresponse同random(随机)。

现有的shortestresponse的实现机制,类似P2C(Power of Two Choice)算法,不过计算方式不是采用当前正在处理的连接数,而是默认随机选择两个服务提供者参与最快响应比较计算,即:统计请求每个provider的请求耗时、访问量、异常量、请求并发数,比较平均响应时间 * 当前请求数,用于最快响应负载计算。选取优胜者来避免羊群效应。以此自适应的衡量 provider 端机器的吞吐能力,然后将流量尽可能分配到吞吐能力高的机器上,提高系统整体服务的性能。

    <jsf:consumer id="activityConfigService"
                  interface="com.jd.ka.b2b2c.shop.sdk.service.ActivityConfigService"
                  alias="${jsf.activityConfigService.alias}" timeout = "3000" filter="jsfLogFilter,jsfSwitchFilter"
                  loadbalance="shortestresponse">
        <jsf:method name="queryActivityConfig" timeout="10" retries="2"/>
    </jsf:consumer>

注入故障(设置自适应负载均衡)

自适应负载均衡小结

通过引入自适应负载均衡,从接口最初调用就开始了”能者多劳“模式,选举出的机器承载着更高的流量,故障注入后,接口可用率短时间窗口消失,变成可用率跳点,进一步保障了服务的高可用及性能。

关于服务熔断

当电路发生短路或严重过载时,熔断器中的熔断体将自动熔断,对电路进行保护。避免对设备产生重大影响,甚至火灾。

服务熔断是面向不稳定服务场景的一种链路保护机制。

其背后的基本思想非常简单,将受保护的函数调用包装在熔断对象中,该对象会监视故障。当调用链路的某个服务不可用或者响应时间太长导致故障达到设定阈值时,会进行服务熔断,熔断窗口内不再有该节点服务的调用,以此来最大限度避免下游服务不稳定对上游服务带来的影响。

<!-- 服务熔断策略配置 -->
<jsf:reduceCircuitBreakerStrategy id="demoReduceCircuitBreakerStrategy"
    enable="true"   <!-- 熔断策略是否开启 -->
    rollingStatsTime="1000" <!-- 熔断器指标采样滚动窗口时长,单位 ms,默认 5000ms -->
    triggerOpenMinRequestCount="10" <!-- 单位时间内触发熔断的最小访问量,默认 20 -->
    triggerOpenErrorCount="0"   <!-- 单位时间内的请求异常数达到阀值,默认 0,小于等于0 代表不通过异常数判断是否开启熔断  -->
    triggerOpenErrorPercentage="50" <!-- 单位时间内的请求异常比例达到阀值,默认 50,即 默认 50% 错误率  -->
    <!-- triggerOpenSlowRT="0" 判定请求为慢调用的请求耗时,单位 ms,请求耗时超过 triggerOpenSlowRT 则认为是慢调用 (默认为 0,即默认不判定)-->
    <!-- triggerOpenSlowRequestPercentage="0"  采样滚动周期内触发熔断的慢调用率(默认为 0,即默认不触发慢调用熔断 -->
    openedDuration="10000"   <!-- 熔断开启状态持续时间,单位 ms,默认  5000ms -->
    halfOpenPassRequestPercentage="30"  <!-- 半闭合状态,单位时间内放行流量百分比,默认 40-->
    halfOpenedDuration="3000"   <!-- 半闭合状态持续时间设置,需要大于等于 rollingStatsTime ,默认为 rollingStatsTime  -->
    <!-- failBackType="FAIL_BACK_EXCEPTION" failBack策略, 取值:FAIL_BACK_EXCEPTION抛出异常、FAIL_BACK_NULL返回null、FAIL_BACK_CUSTOM配置自定义策略,配合 failBackRef 属性 -->
    <!-- failBackRef="ref" 如果 failBackStrategy 配置为 FAIL_BACK_CUSTOM 则必填,用户自定义的failback策略com.jd.jsf.gd.circuitbreaker.failback.FailBack<Invocation> 接口实现类 -->
/>

<jsf:consumerid="activityConfigService"interface="com.jd.ka.b2b2c.shop.sdk.service.ActivityConfigService"
                alias="${consumer.alias.com.jd.ka.b2b2c.shop.sdk.service.ActivityConfigService}" timeout="2000"check="false"
                serialization="hessian"loadbalance="shortestresponse"
                connCircuitBreakerStrategy="demoCircuitBreakerStrategy">
      <jsf:methodname="queryActivityConfig"timeout="10"retries="2"/>
</jsf:consumer>

这里来了一个小插曲,由于JSF本身的心跳机制,检测故障后,自动(30s检测一次,三次均异常则摘除)摘除了对应的机器,我们自身设置的熔断机制并不明显,因此重新设置故障(网络延迟800-1500ms)进行重新演练。

注入故障(服务熔断)

服务熔断小结

从可用率上看,确实在窗口内会关闭对异常机器节点的访问,不过由于并没有实现failback策略以及熔断开启窗口时间较短,可用率还是会在窗口打开后,直接返回了调用失败信息,因此影响了可用率。所以相比于熔断后失败,最好的方式是配合服务降级能力,通过调用预先设置好的服务降级逻辑,以降级逻辑的结果作为最终调用结果,以更优雅的返回给服务调用方。

服务熔断补充

  1. 集团已搭建了统一的熔断组件,并且在泰山上建立了对应的平台能力。如果团队需要引入熔断能力,可以直接接入使用,避免重复建设
 一种机制可能会击败另一种机制。

其实为了增强系统的弹性和鲁棒性,以应对各种故障和不可预测的情况,在分布式系统中,通常会设计成能够部分故障(partially fail),即使不能满足全量客户,但是仍然可以向某些客户提供服务。但是熔断旨在将部分故障转化为完全故障,以此防止故障进一步扩散。因此服务熔断和分布式系统的设计原则中存在一种相互制约的关系,所以,在使用前,要进行仔细的分析和思考,以及后续的调优。

结论

能力只是手段,稳定性才是目的。

无论采用什么手段,进行稳定性建设,我们需要时刻思考的是如何在业务需求和稳定性建设中寻找平衡,以建设支持业务长期增长的高可用架构。


本次就写到这,如有问题,欢迎交流。希望文章中的一些经验,给大家带来一些收获,或者说,大家不妨思考一下你们会采用何种技术方案和手段来解决类似问题。欢迎留言交流,也希望能和更多志同道合的伙伴沟通交流。

最后老样子,欢迎大家一键三连点赞收藏+关注。

参考文档

The power of two random choices : https://brooker.co.za/blog/2012/01/17/two-random.html

负载均衡:https://cn.dubbo.apache.org/zh-cn/overview/core-features/load-balance/#shortestresponse

作者:京东零售 李孟冬

来源:京东云开发者社区

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/648879.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

vue3 项目部署,Nginx配置https,重定向,详细流程

文章目录 前情提要应用场景安装使用 实战解析最后 前情提要 一个web项目完成后&#xff0c;我们需要打包部署上线&#xff0c;关于打包的实战在我的vite专栏里已经有过一些实践&#xff0c;今天我们来实践一些部署的过程&#xff0c;当然部署也可以由后端来完成&#xff1b; 应…

去面腾讯了(社招两年面试经验)

之前很多同学嚷嚷有没有社招经验&#xff0c;正好&#xff0c;我有个朋友去腾讯社招面试了。 他的面的是全栈开发岗位&#xff0c;工作两年&#xff0c;后端是Go&#xff0c;前端是 JavaScript Vue。 因为工作也没多久&#xff0c;就两年时间&#xff0c;所以大概率可能还是…

Linux:用户和用户组

Linux系统中可以&#xff1a; 配置多个用户配置多个用户组用户可以加入多个用户组 Linux系统关于权限的管控级别有两个&#xff0c;即&#xff1a; 针对用户的权限控制针对用户组的权限控制 1、用户组管理 创建用户组&#xff0c;语法&#xff1a; groupadd 用户组名 删除用户组…

NLP——Summarization

文章目录 Extractive summarisationSingle-documentcontent selectionTFIDF MethodLog Likelihood Ratio Method对数似然比Sentence Centrality Method 句子中心法 RST Parsing Multi-documentContent selectionMaximum Marginal Relevance 最大边际相关性Information Ordering…

详细介绍ROS中通过shell文件依次启动多个launch文件

本文主要介绍如何在ROS中通过shell文件依次启动多个launch文件&#xff0c;并介绍如何在同一个窗口的不同选项卡中依次启动多个launch文件。 一、先来看一个简单的示例&#xff1a; #!/bin/bashgnome-terminal -- bash -c "roslaunch bringup racecar_gazebo_rviz_znc.la…

Word控件Spire.Doc 【其他】教程(9):从 Word 文档中提取 OLE 对象

Spire.Doc for .NET是一款专门对 Word 文档进行操作的 .NET 类库。在于帮助开发人员无需安装 Microsoft Word情况下&#xff0c;轻松快捷高效地创建、编辑、转换和打印 Microsoft Word 文档。拥有近10年专业开发经验Spire系列办公文档开发工具&#xff0c;专注于创建、编辑、转…

NestJs 管道(Pipe)

&#x1f384;Hi~ 大家好&#xff0c;我是小鑫同学&#xff0c;资深 IT 从业者&#xff0c;InfoQ 的签约作者&#xff0c;擅长前端开发并在这一领域有多年的经验&#xff0c;致力于分享我在技术方面的见解和心得 &#x1f680;技术&代码分享 我在 94Code 总结技术学习&…

Windows下安装运行Kafka(最底下有遇到的坑与解决方法)

注&#xff1a;安装kafka需要提前安装Zookeeper 一、Zookeeper安装 1. 下载安装包 https://zookeeper.apache.org/releases.html 注意&#xff1a;要下载带bin的安装包 2. 解压并进入ZooKeeper目录&#xff0c;如&#xff1a;D:\onworking\apache-zookeeper-3.7.0-bin&…

ansible剧本模式特殊模块使用

Nginx安装剧本 ansible-playbook test1.yaml //补充参数 -k&#xff08;-ask-pass&#xff09;&#xff1a;用来交互输入ssh密码 -K&#xff08;-ask-become-pass&#xff09;&#xff1a;用来交互输入sudo密码 -u&#xff1a;指定用户 -e:命令行指定变量 --syntax-check…

【服务器数据恢复】HP LeftHand存储raid5不可用的数据恢复案例

HP LeftHand存储简介&#xff1a; HP LeftHand存储支持搭建RAID5、RAID6、RAID10磁盘阵列&#xff0c;支持卷快照&#xff0c;卷动态扩容等。服务端和客户端分别如下&#xff1a; LeftHand存储共有三个级别&#xff1a;物理磁盘、基于多个物理磁盘组成的逻辑磁盘&#xff08;ra…

广东电信突发故障,手机没信号,对讲机的重要性再次凸显

当我们常用的通信网络出现故障时&#xff0c;就会面临全网瘫痪的情况&#xff0c;这个时候无线电通信就显得尤为重要了&#xff01; 在6月8日下午两点左右&#xff0c;有多位广东电信的用户发现&#xff0c;自己的手机突然出现了打不出去电话&#xff0c;及上不了网的情况&…

Unity编辑器扩展-第四集-获取物体的方法

第三集链接&#xff1a;Unity编辑器扩展-第三集-添加按钮到组件菜单并且重置组件_菌菌巧乐兹的博客-CSDN博客 一、本节目标效果展示 1.改选中单个物体的名字 2.改选中所有物体的名字 3.选中了所有的物体&#xff0c;但只改第一层物体的名称 4.来个有用的&#xff08;选中的所有…

Python进阶语法之列表推导式

Python进阶语法之列表推导式 Python列表推导式是Python中最有魅力的特性之一&#xff0c;它提供了一种优雅、简洁的方式来创建列表。这种语法不仅使得代码更加简洁&#xff0c;易读&#xff0c;而且在某些情况下还可以提高代码的执行效率。接下来&#xff0c;我们将一起深入探…

SpringBoot中@ControllerAdvice的三种使用场景

一、全局异常处理 代码示例如下: /*** author qinxun* date 2023-06-14* Descripion: 业务层异常枚举*/ public enum ServiceExceptionEnum {SUCCESS(0, "成功"),ERROR(1, "失败"),SYS_ERROR(1000, "服务端发生异常"),MISSING_REQUEST_PARAM_E…

使用同步信号量和互斥信号量解决生产者和消费者问题

生产者和消费者问题 生产者和消费者问题是一个经典的进程同步问题。在这个问题中&#xff0c;生产者不断地向缓冲区中写入数据&#xff0c;而消费者则从缓冲区中读取数据。生产者进程和消费者进程对缓冲区的操作是互斥的&#xff0c;即任意时刻只能有一个进程对这个缓冲区进行…

RTU电流采集上传

RTU电流采集上传 案例说明器件 物联网平台开发代码修改三元组 测试 案例说明 本案例使用HD1&#xff08;RTU&#xff09;检测外部电流&#xff0c;并将电流上传阿里云端。 压力传感器输出电流信号&#xff0c;读取压力传感器数值时需要检测电流大小。haasHD1(RTU)有两路ADC—…

深度学习应用篇-元学习[16]:基于模型的元学习-Learning to Learn优化策略、Meta-Learner LSTM

【深度学习入门到进阶】必看系列&#xff0c;含激活函数、优化策略、损失函数、模型调优、归一化算法、卷积模型、序列模型、预训练模型、对抗神经网络等 专栏详细介绍&#xff1a;【深度学习入门到进阶】必看系列&#xff0c;含激活函数、优化策略、损失函数、模型调优、归一化…

[C语言实现]数据结构堆之《害怕二叉树所以天赋全点到堆上了》

&#x1f970;作者: FlashRider &#x1f30f;专栏: 数据结构 &#x1f356;知识概要&#xff1a;详解堆的概念、小根堆与大根堆的区别、以及代码实现。 目录 什么是堆&#xff1f; 如何实现堆&#xff1f; 代码实现堆(小根堆) 定义堆以及堆的初始化和销毁。 堆的插入 堆…

LeetCode·每日一题·1177. 构建回文串检测·前缀和

作者&#xff1a;小迅 链接&#xff1a;https://leetcode.cn/problems/can-make-palindrome-from-substring/solutions/2309940/qian-zhui-he-zhu-shi-chao-ji-xiang-xi-by-n3ps/ 来源&#xff1a;力扣&#xff08;LeetCode&#xff09; 著作权归作者所有。商业转载请联系作者获…

最新水文水动力模型在城市内涝、城市排水、海绵城市规划设计中深度应用

随着计算机的广泛应用和各类模型软件的发展&#xff0c;将排水系统模型作为城市洪灾评价与防治的技术手段已经成为防洪防灾的重要技术途径。本次培训将聚焦于综合利用GIS及CAD等工具高效地进行大规模城市排水系统水力模型的建立&#xff0c;利用SWMM实现排水系统水力模拟。讲解…