这是why技术的第29篇原创文章

之前在写《这道Java基础题真的有坑!我求求你,认真思考后再回答。》这篇文章时,我在8.1小节提到了快速失败和失败安全机制。

但是我发现当我搜索"快速失败"或"失败安全"的时候,检索出来的结果百分之90以上都是在说Java集合中是怎么实现快速失败或失败安全的。

在我看来,说到快速失败、失败安全时,我们首先想到的应该是这是一种机制、一种思想、一种模式,它属于系统设计范畴,其次才应该想到它的各种应用场景和具体实现。而不是立马想到了集合,这样就有点本末倒置的感觉了。

可以看一下wiki上对于快速失败和失败安全的描述:

快速失败:http://en.wikipedia.org/wiki/Fail-fast

失败安全:http://en.wikipedia.org/wiki/Fail-safe

简而言之:系统运行中,如果有错误发生,那么系统立即结束,这种设计就是快速失败。系统运行中,如果有错误发生,系统不会停止运行,它忽略错误(但是会有地方记录下来),继续运行,这种设计就是失败安全。

本文就对比一下Java集合中的快速失败、失败安全和Dubbo框架中的快速失败、失败安全。

读完之后,你就知道Java集合中实现和Dubbo中的实现就大不一样。

没有谁比谁好,只有结合场景而言,谁比谁更合适而已。

Java集合-快速失败

现象:在用迭代器遍历一个集合对象时,如果遍历过程中对集合对象的内容进行了增加、删除、修改操作,则会抛出ConcurrentModificationException。

原理:迭代器在遍历时直接访问集合中的内容,并且在遍历过程中使用一个 modCount 变量。集合在被遍历期间如果内容发生变化,就会改变modCount的值。每当迭代器使用hashNext()/next()遍历下一个元素之前,都会检测modCount变量是否为expectedmodCount值,是的话就返回遍历;否则抛出ConcurrentModificationException异常,终止遍历。

注意:这里异常的抛出条件是检测到 modCount!=expectedmodCount 这个条件。如果集合发生变化时修改modCount值刚好又设置为了expectedmodCount值,则异常不会抛出。因此,不能依赖于这个异常是否抛出而进行并发操作的编程,这个异常只建议用于检测并发修改的bug。

场景:java.util包下的集合类都是快速失败的,不能在多线程下发生并发修改(迭代过程中被修改)。

上面的知识点我在《这道Java基础题真的有坑!我求求你,认真思考后再回答。》这篇文章中第三小节已经抽丝剥茧般的详细说明了,有兴趣的可以阅读一下:

Java集合-失败安全

现象:采用失败安全机制的集合容器,在遍历时不是直接在集合内容上访问的,而是先复制原有集合内容,在拷贝的集合上进行遍历。

原理:由于迭代时是对原集合的拷贝进行遍历,所以在遍历过程中对原集合所作的修改并不能被迭代器检测到,所以不会触发ConcurrentModificationException。

缺点:基于拷贝内容的优点是避免了ConcurrentModificationException,但同样地,迭代器并不能访问到修改后的内容,即:迭代器遍历的是开始遍历那一刻拿到的集合拷贝,在遍历期间原集合发生的修改迭代器是不知道的。这也就是他的缺点,同时,由于是需要拷贝的,所以比较吃内存。

场景:java.util.concurrent包下的容器都是安全失败,可以在多线程下并发使用,并发修改。

比如之前文章说到的CopyOnWriteArrayList:

集合部分涉及到的参考链接:https://www.cnblogs.com/ygj0930/p/6543350.html

Dubbo中的集群容错

在描述快速失败和失败安全在Dubbo中的体现之前,我们必须先说说Dubbo中的集群容错机制,因为快速失败和失败安全是其容错机制中的一种。

还是看之前出现的图片:

其中,集群 Cluster 用途是将多个服务提供者合并为一个 Cluster Invoker,并将这个 Invoker 暴露给服务消费者。这样一来,服务消费者只需通过这个 Invoker 进行远程调用即可,至于具体调用哪个服务提供者,以及调用失败后如何处理等问题,现在都交给集群模块去处理。

集群模块是服务提供者和服务消费者的中间层,为服务消费者屏蔽了服务提供者的情况,这样服务消费者就可以专心处理远程调用相关事宜。

对于容错方式官网上是这样的说的:

注意哦,官网说的是主要提供了这样几种,并没有完全列举,通过查看源码你可以看到:

org.apache.dubbo.rpc.cluster.support.AbstractClusterInvoker

有九个实现类,说明官方提供了九种容错方式供你选择:

而本文主要讨论的是:

org.apache.dubbo.rpc.cluster.support.FailfastClusterInvoker org.apache.dubbo.rpc.cluster.support.FailsafeClusterInvoker

搭建Demo项目

为了方便演示快速失败和失败安全在Dubbo中的体现,我们需要先搭建一个简单的Demo项目,搭建过程我就不演示了,这一小节仅对Demo的关键地方进行说明:

服务端接口如下:

服务端接口实现如下:

休眠3秒,模拟业务超时。

服务端Dubbo xml配置如下:

消费端Dubbo xml配置如下:

消费端在Test类中消费如下:

Dubbo中的快速失败

快速失败对应的实现类是:

org.apache.dubbo.rpc.cluster.support.FailfastClusterInvoker

启用该实现类,只需要在Dubbo xml中指定cluster属性为failfast:

先看一下实现类上的注释是怎么写的:

Execute exactly once, which means this policy will throw an exception immediately in case of an invocation error. Usually used for non-idempotent write operations。

FailfastClusterInvoker 只会进行一次调用,失败后立即抛出异常。适用于幂等操作,比如新增记录。

实现类的源码如下:

执行结果如下:

Dubbo中的失败安全

失败安全对应的实现类是:

org.apache.dubbo.rpc.cluster.support.FailsafeClusterInvoker

启用该实现类,只需要在Dubbo xml中指定cluster属性为failsafe:

先看一下实现类上的注释是怎么写的:

When invoke fails, log the error message and ignore this error by returning an empty Result. Usually used to write audit logs and other operations

FailsafeClusterInvoker 是一种失败安全的 Cluster Invoker。所谓的失败安全是指,当调用过程中出现异常时,FailsafeClusterInvoker 仅会打印异常,而不会抛出异常。适用于写入审计日志等操作。

实现类的源码如下:

执行效果如下,首先可以看到超时异常被捕获:

所以虽然超时了,但是在Test类中,还是打印出了returnStr:

文章背后的故事

本周输出这篇文章实属不易。

由于周六公司年会与运动会,我有幸当选了某队队长,所以本周周一到周五工作之外的时间都在忙碌着运动会的物质筹备、数据统计等相关工作。仅仅有早起的一小会空挡时间能随手翻翻书,但是写文章时间是不够的。

周六活动开始,从早上6点30分起床,到晚上23点做完最后的收尾工作,忙碌了整整一天。所幸的是我所在的小队在10支队伍中脱颖而出,勇夺第一。

在战况异常激烈的拔河环节,在所有拉拉队员整齐划一,嘶声呐喊的口号声中,参赛队员体现出的那种坚韧不拔、咬牙死撑的精神,深深的打动了我。一共有两次轮空的机会,我们队伍都与之擦肩而过,但是我们一次又一次的击败了实力强劲的对手,还是握住了总决赛拔河的绳子。由于对手轮空一轮,所以体力充沛,我们遗憾告负。但是在裁判没有吹哨之前,我们永不言弃。

所有项目比完之后,我所在队伍最终的总积分排名第一。在最终结果没有宣布之前,我们永不言弃。

周日,和我从小一起长大的表姐结婚,早上7点多去现场帮忙。中午吃饭时我都没敢喝太多酒,因为我想着这周的文章还没写,我得保持清醒。但是看到姐姐和姐夫站在大荧幕下的那一刻,我还是感动的热泪盈眶。下午陪家人玩了一下午。晚上到家之后已经非常疲倦了,但是我还是输出了这篇文章。

女朋友问我这周能不能不写,我想了一下说:不能。因为那一瞬间我想到了,路遥先生在《早晨从中午开始》中的一句话:只有初恋般的热情和宗教般的意志,人才有可能成就某种事业。

这也和年会中的一页PPT非常的符合:把你的全部,奉献给你热爱的一切。

我是一个普通的程序员,但是我热爱这个行业。

最后说一句

如果把Java集合的实现和Dubbo框架的实现分开来看,感觉这是两个不同的知识点,但是再往上抽离,可以发现它们都是快速失败机制与失败安全机制的实现方式。还是有着千丝万缕的联系。

还是之前说的,快速失败机制与失败安全机制,没有谁比谁好,只有结合场景而言,谁比谁更合适而已。

与本文相关的文章还有下面两篇,欢迎阅读:

《这道Java基础题真的有坑!我求求你,认真思考后再回答。》

《这道Java基础题真的有坑!我也没想到还有续集。》

才疏学浅,难免会有纰漏,如果你发现了错误的地方,还请你留言给我指出来,我对其加以修改。

如果你觉得文章还不错,你的转发、分享、赞赏、点赞、留言就是对我最大的鼓励。

感谢您的阅读,我坚持原创,十分欢迎并感谢您的关注。

以上。

欢迎关注公众号【why 技术】,坚持输出原创。愿你我共同进步。

http://weixin.qq.com/r/xES9pXLEOS9GrTbG9xHW (二维码自动识别)

远程过程调用失败_快速失败机制amp;失败安全机制相关推荐

  1. 参数幂等性校验失败_快速入手 Spring Boot 参数校验

    1.背景介绍 2.Spring Boot文档中的Validation 3.Hibernate Validator 4.Spring Validator 5.示例 6.补充 <Netty 实现原理 ...

  2. 老滚5初始化python失败_快速开始 - Python - 掘金量化

    快速开始 分享 阅读 19473 更新 2021-01-13 09:43:05 常见的策略结构主要包括3类,如下图所示. 用户可以根据策略需求选择相应的策略结构,具体可以参考经典策略. 定时任务示例 ...

  3. matplotlib安装成功但import失败_统信UOS安装失败,deepinv20.1国产操作系统安装成功...

    我一直在等着uos成熟,当我知道这个消息之后,我就赶紧下载了. 但是安装到63%的时候,会卡死不动. 无论是硬盘安装还是u盘安装都不行. 我去网上找教程,官方教程居然让我用虚拟机装? 教程好像在对我说 ...

  4. python显示安装失败_关于python:安装失败并显示Requirements.txt,但可用于pip安装...

    与使用pip直接安装时相比,在使用requirements.txt时出现一些奇怪的行为. 希望您能对此有所了解. 这可能与未解决的问题相同:pip install -r requirements.tx ...

  5. c# 再次尝试 连接失败_和平精英ios充值失败该怎么办

    和平精英ios充值失败该怎么办?近期有小伙伴说自己用苹果手机充值却显示充值失败,这种情况该怎么解决呢?其实这不是大问题,看看下面的解决办法. 和平精英ios充值失败 和平精英ios充值失败只需要重新填 ...

  6. 初始化mysql的数据库失败_初始化mysql的数据库失败怎么办

    初始化mysql数据库失败的解决办法:首先找到并打开my.ini文件:然后注释掉my.ini文件中的datadir:最后根据提示把UTF8换成UTF8MB4即可. 安装MySQL8,安装时初始化数据库 ...

  7. 读取配置文件失败_还在为Find_Package失败而烦恼吗?

    在学习ubuntu的过程中,经常会遇到以下问题: Could not find a package configuration file provided by "xxx" wit ...

  8. null导入失败_当null检查非常失败时

    null导入失败 免责声明 在继续之前,我必须指出,当我们对Java进行编程时,本文中描述的技术没有实际目的. 就像填字游戏或拼图. 它主要训练您的大脑进行逻辑思维,可能发展您的Java语言知识甚至您 ...

  9. php mysql 失败_在php中插入失败的数据mysql

    我需要将记录添加到表'文字'中.正如您在下面的代码中看到的那样,失败会导致消息data insert failed.在php中插入失败的数据mysql 我已经试图改变一切,在线论坛建议,但它没有帮助. ...

最新文章

  1. 理财周报,致歉还远远不够
  2. vs2003不能正常调试或运行!
  3. Kali 远程登陆SSH
  4. Python学习笔记6(列表生成式)
  5. 卷积网络和卷积神经网络_卷积神经网络的眼病识别
  6. 偷梁换柱做自己的封装系统
  7. 传360以原彩虹QQ研发团队为班底拟强推IM
  8. 使用Office 365抓取PM2.5数据
  9. Laravel的CURD操作
  10. vofuria的开发(1)
  11. 小程序使用腾讯API定位的全过程(详细)
  12. 用MATLAB 读写各种文件 ∈ Matlab 使用笔记
  13. 高频JMeter软件测试面试题
  14. 微信支付(1)---功能测试点
  15. 如何利用计算机换算16进制,16进制怎么转换10进制?计算机进制转换方法汇总
  16. display的值和作用
  17. Python 错误重试库 tenacity retry
  18. 一加手机可以刷鸿蒙系统吗,朋友想把1+手机安装鸿蒙系统,老板收费350,大家千万别被骗了!...
  19. win10安装usb转serial驱动(或Prolific USB-to-Serial Comm Port驱动)
  20. android 高仿糯米团购 摇一摇 摇奖 效果

热门文章

  1. 华为高管揭秘公司不上市的原因;微信回应「花钱就能查到聊天记录」;马斯克删除「超苹果只要几个月」评论 | 极客头条...
  2. 被遗忘的 Mozilla?
  3. 都说人工智能入门难?但80%的人都错了……
  4. 乘“峰”而上,聚生态之力共创软件产业新未来
  5. 数字智能新时代,IT基础设施,Are you ready?
  6. 百行代码解读阿里 AloT 芯片平台无剑 100!
  7. 携程回应突发故障:「bug已修复」;罗永浩再嘲iPhone11浴霸相机;React 16.10.0发布|极客头条...
  8. 5G 时代,AI 如何破竹而出? | AI ProCon
  9. 跳槽失败到月薪50K,AI工程师是这样炼成的!
  10. 华为顶尖应届生最高年薪超 200 万;抖音服务器宕机;GitLab 12.1 发布 | 极客头条...