你们想要的Dubbo,三歪搞来了
本文公众号来源:柳树的絮叨叨
作者:发型吃饭的柳树
本文已收录至我的GitHub
授人以鱼,不如授之以渔,其实这句话说的不只是如何教人。
从另一个角度看这句话,我们在学一样东西的时候,要找到这样东西的”渔“是什么。
对于一项技术来说,它背后的设计思想,就是学习它的”渔“,对于 Dubbo,”渔“,是微内核架构。
首先,我们以「保险索赔」为例,了解下什么是微内核架构。
保险索赔保险索赔的规则往往很复杂,不同保险产品、不同地区的索赔规则可能都不一样。举个例子,假设在纽约州(NY),汽车挡风玻璃被岩石击碎,是可以索赔的,但是在加利福尼亚州(CA)则不行。这时候如果直接把这个逻辑写到代码里去,就是这样:
if (在纽约) {
if (被岩石击碎) {
// 索赔...
}
} else if (在加利福尼亚) {
if (被岩石击碎) {
// 不索赔...
}
}
而且保险规则可不只这一条,到时候写出来就是这样:
if (在纽约) {
if (被岩石击碎) {
// 索赔...
}
if (被陨石击碎) {
// 索赔...
}
if (被流星击碎) {
// 索赔...
}
// more and more...
} else if (在加利福尼亚) {
if (被岩石击碎) {
// 不索赔...
}
if (被陨石击碎) {
// 不索赔...
}
if (被流星击碎) {
// 不索赔...
}
// more and more...
}
可以看到,我们把索赔规则的代码耦合到了索赔的核心系统中:

这会带来两个问题:
修改索赔规则需要重新发布整个系统
索赔规则的改动可能会影响整个系统,甚至导致整个系统不可用
于是我们把这些规则抽取出来,有个专门的地方去管理这些规则,简单说,就是「解耦」:

不同州的规则还是放到一起的,而我们在索赔处理的时候,每次只需要加载一个州的索赔规则,不存在既需要纽约州的规则,又需要加州规则的情况:


Oreilly 对于微内核架构的定义是这样的(纯英文,大家要再三细品):
The microkernel architecture pattern consists of two types of architecture components: a core system and plug-in modules.
Application logic is divided between independent plug-in modules and the basic core system, providing extensibility, flexibility, and isolation of application features and custom processing logic.

核心系统只包含让系统可以运作的最小功能,有点像 MVP(Minimum Viable Product ,最小可用产品)。而插件模块,则包含一些特殊处理逻辑、额外的功能、自定义代码,用于强化和扩展核心系统,提供更多的业务能力。这么讲还是比较抽象,所以,接下来,进入主题,来看看 Dubbo 这个 RPC 框架,是如何基于微内核架构进行设计的。什么是 RPC 系统的 core?
The core system of the microkernel architecture pattern traditionally contains only the minimal functionality required to make the system operational.
The plug-in modules are stand-alone, independent components that contain specialized processing, additional features, and custom code that is meant to enhance or extend the core system to produce additional business capabilities.
Dubbo 在本质上是在解决如何进行远程调用(rpc)的问题,通常一个 rpc 系统都长这个样子:


- 服务提供方,暴露服务时,只需要把自己注册到一个 map 里
- 服务消费方,引用服务时,则只需从 map 里获取到服务提供方的引用
- 当服务消费方调用服务提供方的方法时,其实是一次本地内存调用,不涉及什么网络传输、协议转换、序列化、反序列化

我们从系统的角度,看看 Dubbo 的整体设计图:

- proxy 层,解决的是:如何实现服务接口的透明代理;
- cluster 层,解决的是:当有多个服务提供者时,如何调用、如何负载均衡等等;
- 底下三层,也就是 remote 层,解决的是:如何进行远程调用;
- …


- 当你只需要一次 injvm 的 rpc 调用时,只用 Protocol ,足矣;
- 如果你需要远程调用,而且有多个服务提供方,那需要引入 remote、cluster 和 registry;
- 如果你还需要透明式的 rpc 调用,那就再引入 proxy 层
Protocol 层,其实就是上面提到的,一个最简化的 rpc 模型:

- exporter:对应服务提供方,负责把服务暴露到某个地方
- invoker:对应服务消费方,从某个地方引用服务,并调用服务
- protocol:使用什么样的 protocol,决定了会有什么样的 invoker 和 exporter
injvm 协议,那就会生成 InjvmInvoker 和 InjvmExporter:
dubbo 协议,则会生成 DubboInvoker 和 DubboExporter:
dubbo 协议的 refer 方法,会把 invoker 放进一个 invokers 集合里,injvm 协议的 refer 方法,则直接 new 一个 invoker 后就返回了,说明前者是有可能存在多个服务提供者的,而后者只会有一个。而这些细节上的差异,追溯到根源,就是你用了什么样的协议(protocol)。
微内核架构的其他使用
在 RPC 中,Protocol 是核心层,也就是只要有 Protocol + Invoker + Exporter 就可以完成非透明的 RPC 调用。—— from Dubbo 框架设计
除了上面提到的保险索赔、Dubbo,微内核架构还被用到很多地方。
其实微内核架构的起源,是操作系统:
这里不展开讲,大家可以前往维基百科了解下。后来,这种思想逐渐被演变成一种架构设计模式,于是有了「微内核架构」。它被用在了许多客户端应用,像 Chrome 浏览器:


Eclipse 也一样,核心就是一个编辑器,和记事本没什么区别,给它添加各种各样的插件,像代码高亮、java 代码编译等等,就成了一个好用的开发工具;第三方开发者同样可以给它开发各种插件。之后它又被进一步用在了一些软件框架、业务系统上,比如今天讲到的 Dubbo 和保险索赔系统。甚至在之后的「六边形架构」、DDD 上,都可以看到「微内核架构」的影子,这两种设计思想被大量用到各种框架、中间件的设计上,比如有赞的 MAXIM 全链路压测引擎:

作为一种架构设计的模式,通常都会考虑这些问题:
- 如何降低系统的复杂度
- 如何提高系统的可维护性
- 如何提高系统的可扩展性
- 如何提高系统的可配置性
- 核心系统和插件是低耦合的,插件可插拔
- 核心系统和插件之间是隔离的,改变也是隔离的
- 核心系统可以保持稳定
- 插件可支持动态添加(热部署)
- 插件可以独立测试
- 大部分实现都是基于产品的(product based),实现时不会考虑高可伸缩性,当然这同样取决于你的实现方式。
- 微内核架构需要深思熟虑的设计和契约的规划管理,因此实现起来比较复杂。
- 契约的版本机制、插件的注册机制、插件的粒度、插件连接方式的选择都使得实现起来是复杂的。

授人以鱼不如授人以渔,其实这句古话是有出处的:
人类历史上迸发过许多璀璨的思想,就像微内核架构其实来源于操作系统的微内核。我们在回过头去看的时候,可以嘲笑他们有些观念落伍了,但不要忘了一件事,慢一点,再慢一点,不要错过一些可能闪耀出来的那点星光。参考:
临河而羡鱼,不如归家织网。—— 《淮南子·说林训》
Microkernel Architecture
- Microkernel
- 微内核架构详解
- Dubbo 框架设计
- Dubbo 扩展点重构
各类知识点总结
下面的文章都有对应的原创精美PDF,在持续更新中,可以来找我催更~
- 92页的Mybatis
- 129页的多线程
- 141页的Servlet
- 158页的JSP
- 76页的集合
- 64页的JDBC
- 105页的数据结构和算法
- 142页的Spring
- 58页的过滤器和监听器
- 30页的HTTP
- 42页的SpringMVC
- Hibernate
- AJAX
- Redis
- ......
扫码或者微信搜Java3y 免费领取原创思维导图、精美PDF。在公众号回复「888」领取,PDF内容纯手打有任何不懂欢迎来问我。
原创电子书
原创思维导图

![]() |
|


