你真的懂服务的容错性设计吗(1)
什么是服务容错性
我们在工作中经常会遇到系统故障,服务异常等情况,尤其是在大型分布式系统中,随着微服务的数据量不断增多,服务出现异常的概率也在不断增加,想必没有一个老铁敢保证自己开发的服务不会出现异常。既然我们无法保证服务不会出现异常,那么在系统设计的时候,就要多花一点时间,来考虑系统出现异常时,如何进行异常处理,让异常对整个系统的影响降到最低,尽量让用户无感知,这也就是本篇文章讨论的重点内容,服务的容错性设计。
服务容错性策略有哪些
服务的容错性设计其实是提升服务可用性的一种手段,提升服务可用性的方案通常有两种:事前预防和事后处理。
事前预防:常用的事前预防手段是副本冗余机制,对副本机制不了解的小伙伴可以参考“副本机制在kafka中的实践”。很多公司的事前预防解决方案是这样的:给服务添加丰富的指标监控,如服务的负载监控,服务异常告警,同时给服务设置一些扩缩容的配置,比如cpu,内存负载超过70%时,会触发扩容操作,防止服务面临超过预期的突发请求时,导致大部分请求直至超时都无法完成处理,甚至导致服务崩溃,影响系统的可用性。
事后处理:更多的是在研究当服务出现异常时候该怎么做的问题,其目标主要是:当服务出现异常时,如何让异常的影响达到最小,如何让服务自动恢复尽量让用户无感知,这个也是服务容错性设计重点,对于常用的服务容错策略,主要有以下几种:
故障转移(Failover)
故障转移是指,如果被调用的服务器出现故障,系统不会立即向调用者返回失败结果,而是自动切换到其他服务副本,尝试其他副本能否返回成功调用的结果,从而保证了整体的高可用性。
故障转移的容错策略应该有一定的调用次数限制,比如允许最多重试三个服务,如果都发生报错,那还是会返回调用失败。引入调用次数的限制,不仅是因为重试有执行成本,更是因为过度的重试反而可能让系统处于更加不利的状况。
我们看一个例子。现在有 Service A → Service B → Service C 这么一条调用链。假设 A 的超时阈值为 100 毫秒,而 B 调用 C 需要 60 毫秒,然后不幸失败了,这时候做故障转移其实已经没有太大意义了。因为即使下一次调用能够返回正确结果,也很可能同样需要耗费 60 毫秒的时间,时间总和就已经超过了 Service A 的超时阈值。所以,在这种情况下故障转移反而对系统是不利的。
快速失败(Failfast)
有一些业务场景是不允许做故障转移的,因为故障转移策略能够实施的前提,是服务具有幂等性。那对于非幂等的服务,重复调用就可能产生脏数据,引起的麻烦远大于单纯的某次服务调用失败。这时候,就应该把快速失败作为首选的容错策略。
比如,在支付场景中,需要调用银行的扣款接口,如果该接口返回的结果是网络异常,那程序很难判断到底是扣款指令发送给银行时出现的网络异常,还是银行扣款后给服务返回结果时出现的网络异常。为了避免重复扣款,此时最恰当的方案就是尽快让服务报错并抛出异常,坚决避免重试,由调用者自行处理。
安全失败(Failsafe)
在一个调用链路中的服务,通常也有主路和旁路之分,并不见得每个服务都是不可或缺的,属于旁路逻辑的一个显著特点是,服务失败了也不影响核心业务的正确性。
比如,开发基于 Spring 管理的应用程序时,通过扩展点、事件或者 AOP 注入的逻辑往往就属于旁路逻辑,典型的有审计、日志、调试信息,等等。
属于旁路逻辑的另一个显著特征是,后续处理不会依赖其返回值,或者它的返回值是什么都不会影响后续处理的结果。比如只是将返回值记录到数据库,并不使用它参与最终结果的运算。
对这类逻辑,一种理想的容错策略是,即使旁路逻辑调用失败了,也当作正确来返回,如果需要返回值的话,系统就自动返回一个符合要求的数据类型的对应零值,然后自动记录一条服务调用出错的日志备查即可。这种容错策略,被称为安全失败。
故障恢复(Failback)
故障恢复是指,当服务调用出错了以后,将该次调用失败的信息存入一个消息队列中,然后由系统自动开始异步重试调用。
从这个定义中也可以看出,故障恢复策略尽力促使失败的调用最终能够被正常执行,故障恢复也要求服务必须具备幂等性。
由于它的重试是后台异步进行,即使最后调用成功了,原来的请求也早已经响应完毕,所以,故障恢复策略一般用于对实时性要求不高的主路逻辑,也适合处理那些不需要返回值的旁路逻辑。为了避免在内存中的异步调用任务堆积,故障恢复与故障转移一样,也应该有最大重试次数的限制。
并行调用(Forking)
并行调用策略,是指一开始就同时向多个服务副本发起调用,只要有其中任何一个返回成功,那调用便宣告成功。
这种策略是在一些关键场景中,使用更高的执行成本换取执行时间和成功概率的策略。这种处理思路,其实对应的就是,咱们在日常生活中,对一些重要环节采取的“双重保险”或者“多重保险”的处理思路。
以上这些容错策略,可以指导我们更好的进行服务容错设计,在下一篇文章中,我们一起学习一下如何使用上面这些容错策略,来帮助我们在业务开发中进行服务容错性设计,以及常用的服务容错设计模式。
你真的懂服务的容错性设计吗(1)相关推荐
- 程序猿修仙之路--数据结构之你是否真的懂数组? c#socket TCP同步网络通信 用lambda表达式树替代反射 ASP.NET MVC如何做一个简单的非法登录拦截...
程序猿修仙之路--数据结构之你是否真的懂数组? 数据结构 但凡IT江湖侠士,算法与数据结构为必修之课.早有前辈已经明确指出:程序=算法+数据结构 .要想在之后的江湖历练中通关,数据结构必不可少.数据 ...
- 关于Spring底层原理面试的那些问题,你是不是真的懂Spring?
转载自 关于Spring底层原理面试的那些问题,你是不是真的懂Spring? 1.什么是 Spring 框架?Spring 框架有哪些主要模块? Spring 框架是一个为 Java 应用程序的开发 ...
- “三次握手,四次挥手”你真的懂吗?
来源:码农桃花源 解读:"拼多多"被薅的问题出在哪儿?损失将如何买单? 之前有推过一篇不错的干货<TCP之三次握手四次挥手>,前几天有兄弟投稿,开始还以为是同一篇,后经 ...
- 网站的容错性设计原则
互联网技术的飙升,网络技术的大量使用,郑州网站建设公司的职责也变得非常的高大上和沉重.如今市场上越来越多的B2C和C2C产品的用户体验越来越重要了,但是站在用户的角度上面,并不是每次搜索都是对的,我们 ...
- 【原创】“三次握手,四次挥手”你真的懂吗?
记得刚毕业找工作面试的时候,经常会被问到:你知道"3次握手,4次挥手"吗?这时候我会"胸有成竹"地"背诵"前期准备好的"答案&qu ...
- 你真的懂Redis的5种基本数据结构吗?
摘要: 你真的懂Redis的5种基本数据结构吗?这些知识点或许你还需要看看. 本文分享自华为云社区<你真的懂Redis的5种基本数据结构吗?这些知识点或许你还需要看看>,作者:李子捌. 一 ...
- ❤『面试知识集锦100篇』1.面试技巧篇丨HR的小心思,你真的懂吗?
作者:不吃西红柿 简介:CSDN博客专家.蓝桥签约作者.大数据&Python领域优质创作者. 目录 一.企业考察要点 技巧一:了解自己的专业技能与 JD 中的匹配点 技巧二.把控好企业「味道」 ...
- 可以用于云原生中Skywalking框架原理你真的懂吗
可以用于云原生中Skywalking框架原理你真的懂吗 ✨博主介绍 全链路监控 什么是全链路监控,为什么我们需要全链路监控? OpenTracing OpenTracing定位 OpenTracing ...
- 3G、4G、5G有何不同之处,你真的懂吗?
3G.4G.5G有何不同之处,你真的懂吗? 3G技术还未远去,4G技术方兴未艾,5G技术已蓄势待发.本文从技术层面全面解析了关于3G.4G.5G的不同之处:1.无线通信传递媒介:电磁波,2.无线通信传 ...
最新文章
- c语言程序设计歌手大奖赛,C语言二维数组怎么做:设计青年歌手参加歌曲大奖赛计分系统: 共...,怎样用c语言程序设计? 青年歌手参加歌曲大奖赛,有10个评委...
- 美团某程序员爆料:绩效背c的都要签pip!网友:pip就是变相劝退!
- ubuntu下编译安装PHP
- centos中如何找出系统中 load 高时处于运行队列的进程
- android java显示_Android Studio没有显示java类源代码
- concurrenthashmap_ConcurrentHashMap是如何保证线程安全的
- 关于table的中元素对齐方式的注意点
- python中pop用法_Python dict pop()用法及代码示例
- Hbase Memstore刷新方式与Region的数目上限
- 数据源管理 | 分布式NoSQL系统,Cassandra集群管理
- 前端开发 元素的浮动 文字环饶效果 横向排列效果 0229
- 结构体,文件操作,指针,简单练习
- 《阿里感悟》- 技术人员的职业规划
- java读取字符串分离单词_从Java中的字符串中提取第一个单词的最佳方法是什么?...
- php设计器中文版,PhpDesigner
- mysql获取姓名拼音首字母_C# 汉字获取拼音首字母,给数据库中的姓名添加首字母...
- 树莓派python调用摄像头拍照
- 怎么在删除计算机里面搜索记录,Win7如何删除我的电脑搜索栏里面的搜索记录介绍三种删除win7搜索记录的方法...
- 苹果笔记本怎么查看计算机基本信息,怎么区分查找苹果电脑笔记本macBook pro的年份、型号及序列号...
- USB摄像头测试网址