Dubbo

Dubbo 基础

Dubbo角色

  • provider:服务提供方
  • consumer:服务消费方
  • registry:注册中心
  • moniotr:监控中心
  • container: 服务运行容器

协议

  • dubbo: 单一长连接,NIO异步通信
  • rmi: 阻塞式短连接

负载均衡机制

  • random: 随机选择,默认
  • round robin: 轮询
  • constant hash: 一致性Hash策略,用虚拟节点解决热点节点的问题
  • least active: 最不活跃

集群容错方案

  • failover: 失败自动切换,默认
  • failfast: 失败直接报错
  • failback: 失败自动恢复,定时重发
  • failsafe: 失败安全,忽略异常
  • forking: 并行调用多个,有一个成功就行
  • broadcast: 广播逐个调用,忽略每个节点的异常

读操作采用failover, 默认重试两次
写操作采用failfast, 失败就报错

当一个接口有多个实现

  • 通过group来分组,provider和consumer配置相同的group

版本兼容

  • 通过version, 多个不同的版本可以注册到注册中心

调用方式

  • 默认同步
  • 支持异步调用,Reference(async = true)

服务降级

Dubbo 线程模型

原理

  • Netty提供io线程处理请求,Dubbo提供业务/工作线程池
  • SPI接口Dispatcher,提供方法dispatch(ChannelHandler)
  • 默认采用AllDispatcher

AllDispatcher

  • 全部放入工作线程池

DirectDispatcher

  • 全部不放入工作线程池,在IO线程上处理

ConnectionOrderedDispatcher

  • Connected/Disconnected放入有序队列(线程池),Request和Response放入工作线程池

MessageOnlyDispatcher

  • 只有Request和Response事件放入工作线程池

ExecutionDispatcher

  • 只有Request事件放入工作线程池

Dubbo 线程池

ThreadPool

  • 定义SPI接口ThreadPool
  • 提供方法getExecutor获取线程池
  • 默认采用FixedThreadPool,其他:LimitedThreadPool, CachedThreadPool, EagerThreadPool

FixedThreadPool

  • 线程池中线程的数量固定不变;线程池满了就放队列,队列满了就拒绝;
  • 线程数通过参数threads配置,默认200;
  • 等待队列大小通过参数queues配置,默认0,使用SynchronousQueue;正数使用固定容量的LinkedBlockingQueue;负数使用无容量限制的LinkedBlockingQueue;
  • 拒绝策略是Abort,抛出异常;
  • 拒绝策略有4种:Abort, CallerRuns, Discard, DiscardOldest

LimitedThreadPool

  • 线程池中线程的数量只能增加不能减少,但是有一个上限;先放队列,队列满了新建线程;线程池满了就拒绝;
  • core线程数通过corethreads配置,默认为0;最大线程数通过threads配置,默认200;
  • keepAlive无穷大,线程被创建之后就不会被回收;
  • 等待队列与拒绝策略与FixedThreadPool相同;

CachedThreadPool

  • 线程池的容量无穷大,但是空闲线程会被过期回收;先放队列,队列满了新建线程;
  • core线程数通过corethreads配置,默认为0;最大线程数通过threads配置,默认无穷大;
  • keepAlive通过alive配置,默认1分钟;
  • 等待队列与拒绝策略与FixedThreadPool相同;

EagerThreadPool

  • core线程都busy时,新建线程来处理task,而不是放入等待队列;有空闲线程时则放入等待队列,等待线程处理;
  • 扩展出EagerThreadPoolExecutor和TaskQueue;
  • core线程数通过corethreads配置,默认为0;最大线程数通过threads配置,默认无穷大;
  • keepAlive通过alive配置,默认1分钟;
  • 等待队列大小通过queues配置,默认为1;

EagerThreadPoolExecutor

  • 重载execute方法;
  • 统计已提交的task数量;
  • 被拒绝了,尝试直接放入等待队列;

TaskQueue

  • 重载offer方法;
  • 如果有空闲线程(已提交的task数量小于线程池中线程的数量),则把task插入队列,等待空闲线程来处理;
  • 如果线程池中线程的数量小于线程池的上限,则task不插入队列,而是新建线程来处理;
  • 如果线程池中线程的数量已经达到线程池的上限,则把task插入队列;

Dubbo SPI

Dubbo 自适应拓展机制原理与实例

Dubbo的拓展类(Extension)是通过SPI机制加载的:

  • 对于某个SPI接口,加载指定目录下(META-INF/dubbo)名称为SPI接口全限名的配置文件
  • 对于配置文件里的每一行键值对,加载SPI接口的实现类,也就是拓展类,然后创建实例

有时候我们不希望在Dubbo启动阶段就加载所有的拓展类,而是希望在用到某个拓展类时才加载,这就需要借助于自适应拓展机制。

  • 对于某个SPI接口Car,生成一个自适应拓展类Car$Adaptive,并创建实例
  • 调用该实例的方法时(SPI接口中包含Adaptive注解),会加载拓展类并创建拓展实例,然后调用它的方法

Dubbo Filter 原理

Dubbo的Filter职责链有点绕:

  • 在Invoker#invoke方法里调用Filter#invoke
  • 在Filer#invoke方法的最后一步调用下一个Invoker的inovke方法
  • 如此递归调用
  • 在Invoker#invoke的最后一步调用Filter#onResponse
  • 如此递归返回

Filter#invoke:调用的准备工作,需要执行inovker.inovke(invocation)
Filter#onRespone:调用的结束工作,需要返回result

Dubbo 反射和代理

Dubbo Wrapper

Dubbo Wrapper 可以认为是一种反射机制。它既可以读写目标实例的字段,也可以调用目标实例的方法。比如

  • Car 是接口;RaceCar 是实现类,实现了 Car;ferrari 和 porsche 是 RaceCar 的实例
  • 我们可以为接口 Car 生成一个 Warpper 子类,比如 Wrapper0;然后创建 Wrapper0 的实例 wrapper0
  • 可以通过 wrapper0#getPropertyValue 来读取 ferrari 的字段,也可以读取 porsche 的字段
  • 可以通过 wrapper0#setPropertyValue 来修改 ferrari 的字段,也可以修改 porsche 的字段
  • 可以通过 wrapper0#invokeMethod 来调用 ferrari 的方法,也可以调用 porsche 的方法
  • 优点:通过一个 Wrapper 实例就可以操作目标接口的所有实例

Dubbo Proxy 原理与实例

Dubbo代理机制与JDK的代理机制不同。比如我们有一个接口Car,

  • JDK通过 Proxy#newProxyInstance(ClassLoader, Class[], InvocationHandler) 创建Car的一个实例,所有的方法都要通过InvocationHandler

Dubbo则是分成了两个步骤:

  • 首先生成了Car的实现类proxy0。这是一个代理类,所有的方法都要通过InvocationHandler
  • 然后生成了Proxy的子类Proxy0,并创建了实例。通过newInstance可以创建代理类proxy0的实例。
  • 优点:Proxy类就像一个工厂类,可以创建N个接口的不同实例

谢谢阅读!

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,670评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,928评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,926评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,238评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,112评论 4 356
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,138评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,545评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,232评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,496评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,596评论 2 310
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,369评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,226评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,600评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,906评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,185评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,516评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,721评论 2 335

推荐阅读更多精彩内容