引言

首先,之所以谈这个话题呢,是发现现在很多人对微服务的设计缺乏认识,所以写一篇扫盲文。当然,考虑到目前大多微服务的文章都是口水文,烟哥争取将实现方式讲透,点清楚,让大家有所收获!

OK,我要先说明一下,我有很长一段时间将服务降级和服务熔断混在一起,认为是一回事!

为什么我会有这样的误解呢?

针对下面的情形,如图所示

当Service A调用Service B,失败多次达到一定阀值,Service A不会再去调Service B,而会去执行本地的降级方法!

对于这么一套机制:在Spring cloud中结合Hystrix,将其称为熔断降级!

所以我当时就以为是一回事了,毕竟熔断和降级是一起发生的,而且这二者的概念太相近了!后面接触了多了,发现自己理解的还是太狭隘了,因此本文中带着点我自己的见解,大家如果有不同意见,请轻喷!毕竟还有很多人认为两者是一致的!

正文

服务雪崩

OK,我们从服务雪崩开始讲起!假设存在如下调用链

而此时,Service A的流量波动很大,流量经常会突然性增加!那么在这种情况下,就算Service A能扛得住请求,Service B和Service C未必能扛得住这突发的请求。

此时,如果Service C因为抗不住请求,变得不可用。那么Service B的请求也会阻塞,慢慢耗尽Service B的线程资源,Service B就会变得不可用。紧接着,Service A也会不可用,这一过程如下图所示

如上图所示,一个服务失败,导致整条链路的服务都失败的情形,我们称之为服务雪崩。

ps:谁发明的这个词,真是面试装13必备!

那么,服务熔断和服务降级就可以视为解决服务雪崩的手段之一。

服务熔断

那么,什么是服务熔断呢?

服务熔断:当下游的服务因为某种原因突然变得不可用或响应过慢,上游服务为了保证自己整体服务的可用性,不再继续调用目标服务,直接返回,快速释放资源。如果目标服务情况好转则恢复调用。

需要说明的是熔断其实是一个框架级的处理,那么这套熔断机制的设计,基本上业内用的是断路器模式,如Martin Fowler提供的状态转换图如下所示

最开始处于closed状态,一旦检测到错误到达一定阈值,便转为open状态;

这时候会有个 reset timeout,到了这个时间了,会转移到half open状态;

尝试放行一部分请求到后端,一旦检测成功便回归到closed状态,即恢复服务;

业内目前流行的熔断器很多,例如阿里出的Sentinel,以及最多人使用的Hystrix

在Hystrix中,对应配置如下

//滑动窗口的大小,默认为20

circuitBreaker.requestVolumeThreshold

//过多长时间,熔断器再次检测是否开启,默认为5000,即5s钟

circuitBreaker.sleepWindowInMilliseconds

//错误率,默认50%

circuitBreaker.errorThresholdPercentage

每当20个请求中,有50%失败时,熔断器就会打开,此时再调用此服务,将会直接返回失败,不再调远程服务。直到5s钟之后,重新检测该触发条件,判断是否把熔断器关闭,或者继续打开。

这些属于框架层级的实现,我们只要实现对应接口就好!

服务降级

那么,什么是服务降级呢?

这里有两种场景:

当下游的服务因为某种原因响应过慢,下游服务主动停掉一些不太重要的业务,释放出服务器资源,增加响应速度!

当下游的服务因为某种原因不可用,上游主动调用本地的一些降级逻辑,避免卡顿,迅速返回给用户!

其实乍看之下,很多人还是不懂熔断和降级的区别!

其实应该要这么理解:

服务降级有很多种降级方式!如开关降级、限流降级、熔断降级!

服务熔断属于降级方式的一种!

可能有的人不服,觉得熔断是熔断、降级是降级,分明是两回事啊!其实不然,因为从实现上来说,熔断和降级必定是一起出现。因为当发生下游服务不可用的情况,这个时候为了对最终用户负责,就需要进入上游的降级逻辑了。因此,将熔断降级视为降级方式的一种,也是可以说的通的!

我撇开框架,以最简单的代码来说明!上游代码如下

try{

//调用下游的helloWorld服务

xxRpc.helloWorld();

}catch(Exception e){

//因为熔断,所以调不通

doSomething();

}

注意看,下游的helloWorld服务因为熔断而调不通。此时上游服务就会进入catch里头的代码块,那么catch里头执行的逻辑,你就可以理解为降级逻辑!

什么,你跟我说你不捕捉异常,直接丢页面?

OK,那我甘拜下风,当我理解错误!

服务降级大多是属于一种业务级别的处理。当然,我这里要讲的是另一种降级方式,也就是开关降级!这也是我们生产上常用的另一种降级方式!

做法很简单,做个开关,然后将开关放配置中心!在配置中心更改开关,决定哪些服务进行降级。至于配置变动后,应用怎么监控到配置发生了变动,这就不是本文该讨论的范围。

那么,在应用程序中部下开关的这个过程,业内也有一个名词,称为埋点!

那接下来最关键的一个问题,哪些业务需要埋点?

一般有以下方法

(1)简化执行流程

自己梳理出核心业务流程和非核心业务流程。然后在非核心业务流程上加上开关,一旦发现系统扛不住,关掉开关,结束这些次要流程。

(2)关闭次要功能

一个微服务下肯定有很多功能,那自己区分出主要功能和次要功能。然后次要功能加上开关,需要降级的时候,把次要功能关了吧!

(3)降低一致性

假设,你在业务上发现执行流程没法简化了,愁啊!也没啥次要功能可以关了,桑心啊!那只能降低一致性了,即将核心业务流程的同步改异步,将强一致性改最终一致性!

可是这些都是手动降级,有办法自动降级么?

这里我摸着良心说,我们在生产上没弄自动降级!因为一般需要降级的场景,都是可以预见的,例如某某活动。假设,平时真的有突发事件,流量异常,也有监控系统发邮件通知,提醒我们去降级!

当然,这并不代表自动降级不能做,因此以下内容可以认为我在胡说八道,因为我在生产上没实践过,只是头脑大概想了下,如果让我来做自动降级我会怎么实现:

(1)自己设一个阈值,例如几秒内失败多少次,就启动降级

(2)自己做接口监控(有兴趣的可以了解一下Rxjava),达到阈值就走推送逻辑。怎么推呢?比如你配置是放在git上,就用jgit去改配置中心的配置。如果配置放数据库,就用jdbc去改。

(3)改完配置中心的配置后,应用就可以自动检测到配置的变化,进行降级!(这句不了解的,了解一下配置中心的热刷新功能)

java服务降级与服务熔断区别_【原创】谈谈服务雪崩、降级与熔断相关推荐

  1. java服务降级与服务熔断区别_服务降级和服务熔断

    服务熔断 在微服务架构中,微服务之间的数据交互通过远程调用完成,微服务A调用微服务B和微服务C,微服务B和微服务C又调用其它的微服务,此时如果链路上某个微服务的调用响应时间过长或者不可用,那么对微服务 ...

  2. java主线程和子线程区别_主线程异常– Java

    java主线程和子线程区别 Being a Java Programmer, you must have seen exception in thread main sometimes while r ...

  3. cinder与ceph的区别_配置cinder-volume服务使用ceph作为后端存储

    在ceph监视器上执行 CINDER_PASSWD='cinder1234!' controllerHost='controller' RABBIT_PASSWD='0penstackRMQ' 1.创 ...

  4. 微服务微应用的安全测试_提高微服务安全性的11个方法

    1.通过设计确保安全 设计安全,意味着从一开始就应该将安全性纳入软件设计中.关于安全,其中最常见的一个威胁就是恶意字符. 我问我的朋友罗伯·温奇(Rob Winch)他对删除恶意字符的想法.Rob是S ...

  5. java静态方法和非静态方法的区别_史上最全阿里 Java 面试题总结

    关注[ToBeTopJavaer],回复[答案],获取全套面试题答案,为明年的金三银四,做好充分的准备. JAVA基础 JAVA中的几种基本数据类型是什么,各自占用多少字节. String类能被继承吗 ...

  6. python 服务端与c++客户端通讯_[原创]python socket 服务端 与 c++客户端通讯,发包内容加密,支持大文件,并发...

    代码经过网络搜索,综合算是原创吧.py脚本为服务端 项目文件在 https://github.com/jinjie412/service_client_socket import socketserv ...

  7. java if和else if的区别_关于C语言中if,elseif和else的区别在哪里

    关于C语言中if,elseif和else的区别在哪里以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 关于C语言中if,e ...

  8. java中j 和 j啥区别_从字节码层次分析++j和j++的区别

    一.缘起 最近看到个面试题: int j = 0; for(int i = 0; i <100; i++) j = j++; System.out.println(j); 输出结果是0,如果换成 ...

  9. java接口vm和dto的区别_第十八节:详解Java抽象类和接口的区别

    前言 对于面向对象编程来说,抽象是它的特征之一. 在Java中,实现抽象的机制分两种,一为抽象类,二为接口. 抽象类为abstract class,接口为Interface. 今天来学习一下Java中 ...

最新文章

  1. dma接收双缓存 stm32_容易被大多数人忽视的STM32串口DMA问题
  2. c++/cli中System::Type::GetType的使用注意事项
  3. 60-200-072-使用-命令-MySQL使用mysqldumpslow分析慢查询日志文件
  4. PHP生成zip压缩包
  5. 小程序swiper效果高宽设置(微信小程序交流群:604788754)
  6. 大佬带路,用Java实现天天酷跑(附源码),网友:这也太TM屌了~
  7. 每天一道剑指offer-链表中第k个节点
  8. 剪贴板是计算机系统,剪贴板在哪里,手把手教你如何打开电脑剪贴板
  9. 运维、开发、测试等 IT 岗位薪酬体系大公开!你拖后腿了吗?
  10. CLC龍链:致力于打造支付生态系统
  11. html横向导航二级菜单代码,横向二级导航菜单
  12. 怎么看计算机电源型号,电脑电源铭牌怎么看?台式机电源铭牌知识扫盲 拒绝虚标!...
  13. CSS代码写一个网页,有留言板
  14. jq操作数组的常用方法
  15. 美团开源Graver框架:用“雕刻”诠释iOS端UI界面的高效渲染
  16. dom4j解析dom示例
  17. 数字IC前端笔试常见大题整理(简答+手撕)
  18. 龙门阵179期实录:技术专场之Android安全现状
  19. Exp3 免杀原理与实践 20164321 王君陶
  20. 固定资产管理软件的全球与中国市场2022-2028年:技术、参与者、趋势、市场规模及占有率研究报告

热门文章

  1. 解决:ipad mini4连接无线密码是对的,结果老是提示密码错误
  2. web初学经验:对于IOS不兼容 text-algin:justify
  3. 信仰之题——Codeforces Round 259(附题面完整翻译)
  4. 苹果cms如何添加播放器预加载和缓冲广告
  5. Android 系统 cpu0 目录查看 CPU 频率freq和策略policy
  6. Excel表格如何换行,Leo老师来教你!
  7. MT6735/mt8735 HDMI开发板资料介绍
  8. html5 手绘效果,10个超棒的HTML 5素描及绘画设计工具
  9. java http编码_JAVA中的http请求处理编码URLEncode
  10. 关键字 'order' 附近有语法错误,应为ID,QUOTED_ID,或','