总结/朱季谦

先前在测试环境遇到过一个问题,即Dubbo广播机制,在对各个提供者节点进行广播操作过程中,存在最前面的两个节点出现异常的情况,但后边的其他节点仍能正常同步的情况。我以前就知道Dubbo的Broadcast机制,先前概念里总以为这是一个当广播到某个节点若出现异常时,就会直接停止广播操作,但在Dubbo的广播机制里,却不是这样。它会先遍历所有的Invokers调用,若过程出现异常时,只会先将异常先类似日志一样记录下来,等到Invokers遍历完成后,最后才会将最后保留的异常进行抛出。

这就能解释了,为啥存在两个节点出现异常的情况下,后面的节点仍能正常被广播通知到。

接下来,我们简单看下Dubbo的Broadcast机制源码,这里的代码很好看懂——

接下来,我们简单看下Dubbo的broadcast机制源码——

public class BroadcastClusterInvoker<T> extends AbstractClusterInvoker<T> {

    private static final Logger logger = LoggerFactory.getLogger(BroadcastClusterInvoker.class);

    public BroadcastClusterInvoker(Directory<T> directory) {
super(directory);
} @Override
@SuppressWarnings({"unchecked", "rawtypes"})
public Result doInvoke(final Invocation invocation, List<Invoker<T>> invokers, LoadBalance loadbalance) throws RpcException {
//通过CollectionUtils.isEmpty(invokers)检查invokers集合是否为空,若为空,抛出异常
checkInvokers(invokers, invocation);
//类似上下文操作保存invokers
RpcContext.getContext().setInvokers((List) invokers);
RpcException exception = null;
Result result = null;
//遍历invoker远程调用接口服务
for (Invoker<T> invoker : invokers) {
try {
result = invoker.invoke(invocation);
} catch (RpcException e) {
//若出现异常,将异常信息进行保存
exception = e;
logger.warn(e.getMessage(), e);
} catch (Throwable e) {
exception = new RpcException(e.getMessage(), e);
logger.warn(e.getMessage(), e);
}
}
//等invokers遍历完成后,若存在异常,再对异常进行抛出
if (exception != null) {
throw exception;
}
return result;
} }

这里的遍历操作是单线程进行的,存在一个问题,若invokers数量很庞大,那么,将会出现广播耗时的情况,我觉得这里若invokers数据量过大时,可以通过选择有返回值的线程池并发执行。

Dubbo广播机制源码解读的更多相关文章

  1. Dubbo SPI 机制源码分析(基于2.7.7)

    Dubbo SPI 机制涉及到 @SPI.@Adaptive.@Activate 三个注解,ExtensionLoader 作为 Dubbo SPI 机制的核心负责加载和管理扩展点及其实现.本文以 E ...

  2. Laravel 源码解读系列第四篇-Auth 机制

    前言 Laravel有一个神器: php artisan make:auth 能够快速的帮我们完成一套注册和登录的认证机制,但是这套机制具体的是怎么跑起来的呢?我们不妨来一起看看他的源码.不过在这篇文 ...

  3. 阿里P7终于讲完了JDK+Spring+mybatis+Dubbo+SpringMvc+Netty源码

    前言 这里普及一下,每个公司都有职别定级系统,阿里也是,技术岗以 P 定级,一般校招 P5, 社招 P6 起.其实阅读源码也是有很多诀窍的,这里分享几点心得: 首先要会用.你要知道这个库是干什么的,掌 ...

  4. etcd学习(6)-etcd实现raft源码解读

    etcd中raft实现源码解读 前言 raft实现 看下etcd中的raftexample newRaftNode startRaft serveChannels 领导者选举 启动并初始化node节点 ...

  5. SDWebImage源码解读 之 SDWebImageCompat

    第三篇 前言 本篇主要解读SDWebImage的配置文件.正如compat的定义,该配置文件主要是兼容Apple的其他设备.也许我们真实的开发平台只有一个,但考虑各个平台的兼容性,对于框架有着很重要的 ...

  6. AFNetworking 3.0 源码解读 总结(干货)(下)

    承接上一篇AFNetworking 3.0 源码解读 总结(干货)(上) 21.网络服务类型NSURLRequestNetworkServiceType 示例代码: typedef NS_ENUM(N ...

  7. AFNetworking 3.0 源码解读 总结(干货)(上)

    养成记笔记的习惯,对于一个软件工程师来说,我觉得很重要.记得在知乎上看到过一个问题,说是人类最大的缺点是什么?我个人觉得记忆算是一个缺点.它就像时间一样,会自己消散. 前言 终于写完了 AFNetwo ...

  8. AFNetworking 3.0 源码解读(八)之 AFImageDownloader

    AFImageDownloader 这个类对写DownloadManager有很大的借鉴意义.在平时的开发中,当我们使用UIImageView加载一个网络上的图片时,其原理就是把图片下载下来,然后再赋 ...

  9. AFNetworking 3.0 源码解读(五)之 AFURLSessionManager

    本篇是AFNetworking 3.0 源码解读的第五篇了. AFNetworking 3.0 源码解读(一)之 AFNetworkReachabilityManager AFNetworking 3 ...

  10. AFNetworking 3.0 源码解读 总结

    终于写完了 AFNetworking 的源码解读.这一过程耗时数天.当我回过头又重头到尾的读了一篇,又有所收获.不禁让我想起了当初上学时的种种情景.我们应该对知识进行反复的记忆和理解.下边是我总结的 ...

随机推荐

  1. three.js教程5-几何体顶点UV坐标、纹理贴图TextureLoader

    1.纹理贴图 纹理贴图,是给MeshLambertMaterial等材质一些纹理图片,以达到更好的视觉效果. 使用方法:通过纹理贴图加载器TextureLoader的load()方法加载一张图片可以返 ...

  2. C 语言编程 — 高级数据类型 — 枚举

    目录 文章目录 目录 前文列表 声明枚举类型 定义枚举类型的变量 枚举类型变量的枚举值 枚举在 switch 语句中的使用 将整型转换为枚举类型 前文列表 <程序编译流程与 GCC 编译器> ...

  3. 4G EPS 中建立 UE 和 MME 之间的 NAS(非接入服务)信令连接

    目录 文章目录 目录 前文列表 建立 NAS(非接入服务)信令连接 前文列表 <4G EPS 中的小区搜索> <4G EPS 中的 PLMN 选择> <4G EPS 中的 ...

  4. Swift 计算字符串展示的区域

    一.如果是普通文本,那么可以采用NSString的方法,代码如下: import UIKit import PlaygroundSupport class MyViewController : UIV ...

  5. iOS开发环境theos开发环境搭建与介绍

    iOS开发环境theos开发环境搭建与介绍 标签(空格分隔): 越狱开发-第一篇 1. 环境准备 一台Mac,本人的机器是MacBook Air (13-inch, Mid 2013),系统是10.1 ...

  6. 如何实现sm3加密

    SM3加密应用 何为sm3加密? SM3是由中国国家密码管理局设计的一种密码杂凑函数,类似于SHA-256和MD5等国际标准的散列算法.SM3算法是中国国家标准<GB/T 32905-2016 ...

  7. idea mapper xml 文件报红

    在使用 idea 打开 mapper 文件,出现一下报红错误: 可以看到数据表和字段都是红色的. 解决方案 打开设置,window版本是打开Settings: 找到 Languages & F ...

  8. vue带有参数的路由跳转 动态路由

    先定义好路由在router文件下面创建一个新的文件夹里面写上自己定义的路由 export default {   path: '/detail/:id',   component: () =>  ...

  9. Linux下,安装单机版Flink

    安装前准备 jdk环境 开始安装 下载安装包 地址1:https://archive.apache.org/dist/flink/flink-1.18.0/flink-1.18.0-bin-scala ...

  10. C#.NET WinForm 多个子Task嵌套 Task.WaitAll 阻塞UI线程

    C#.NET WinForm 多个子Task(子线程)嵌套  Task.WaitAll 阻塞UI线程 (界面) 情况: DoIt()方法内,开了2个Task 执行任务,子任务中会更新UI. DoIt( ...