From a51b0616d2da66d906d863a97bf8a11172fa569d Mon Sep 17 00:00:00 2001 From: yanglbme Date: Wed, 28 Nov 2018 20:38:35 +0800 Subject: [PATCH] docs(dubbo): add dubbo-spi.md --- README.md | 4 +- docs/distributed-system/dubbo-spi.md | 88 +++++++++++++++++++++++++++ img/dubbo-spi.png | Bin 0 -> 26408 bytes 3 files changed, 90 insertions(+), 2 deletions(-) create mode 100644 docs/distributed-system/dubbo-spi.md create mode 100644 img/dubbo-spi.png diff --git a/README.md b/README.md index 1b21cf3..65191ca 100644 --- a/README.md +++ b/README.md @@ -14,9 +14,9 @@ ### 分布式服务框架 - [说一下 Dubbo 的工作原理?注册中心挂了可以继续通信吗?](/docs/distributed-system/dubbo-operating-principle.md) -- [Dubbo 支持哪些序列化协议?说一下 Hessian 的数据结构?PB知道吗?为什么 PB 的效率是最高的?](/docs/distributed-system/dubbo-serialization-protocol.md) +- [Dubbo 支持哪些序列化协议?说一下 Hessian 的数据结构?PB 知道吗?为什么 PB 的效率是最高的?](/docs/distributed-system/dubbo-serialization-protocol.md) - [Dubbo 负载均衡策略和集群容错策略都有哪些?动态代理策略呢?](/docs/distributed-system/dubbo-load-balancing.md) -- Dubbo 的 spi 思想是什么? +- [Dubbo 的 spi 思想是什么?](/docs/distributed-system/dubbo-spi.md) - 如何基于 Dubbo 进行服务治理、服务降级、失败重试以及超时重试? - 分布式服务接口的幂等性如何设计(比如不能重复扣款)? - 分布式服务接口请求的顺序性如何保证? diff --git a/docs/distributed-system/dubbo-spi.md b/docs/distributed-system/dubbo-spi.md new file mode 100644 index 0000000..6cb5ba1 --- /dev/null +++ b/docs/distributed-system/dubbo-spi.md @@ -0,0 +1,88 @@ +## 面试题 +dubbo 的 spi 思想是什么? + +## 面试官心理分析 +继续深入问呗,前面一些基础性的东西问完了,确定你应该都 ok,了解 dubbo 的一些基本东西,那么问个稍微难一点点的问题,就是 spi,先问问你 spi 是啥?然后问问你 dubbo 的 spi 是怎么实现的? + +其实就是看看你对 dubbo 的掌握如何。 + +## 面试题剖析 +### spi 是啥? +spi,简单来说,就是 `service provider interface`,说白了是什么意思呢,比如你有个接口,现在这个接口有 3 个实现类,那么在系统运行的时候对这个接口到底选择哪个实现类呢?这就需要 spi 了,需要**根据指定的配置**或者是**默认的配置**,去**找到对应的实现类**加载进来,然后用这个实现类的实例对象。 + +举个栗子。 + +你有一个接口A。A1/A2/A3 分别是接口A的不同实现。你通过配置 `接口A=实现A2`,那么在系统实际运行的时候,会加载你的配置,用实现A2实例化一个对象来提供服务。 + +spi 机制一般用在哪儿?**插件扩展的场景**,比如说你开发了一个给别人使用的开源框架,如果你想让别人自己写个插件,插到你的开源框架里面,从而扩展某个功能,这个时候 spi 思想就用上了。 + +### Java spi 思想的体现 +spi 经典的思想体现,大家平时都在用,比如说 jdbc。 + +Java 定义了一套 jdbc 的接口,但是 Java 并没有提供 jdbc 的实现类。 + +但是实际上项目跑的时候,要使用 jdbc 接口的哪些实现类呢?一般来说,我们要**根据自己使用的数据库**,比如 mysql,你就将 `mysql-jdbc-connector.jar` 引入进来;oracle,你就将 `oracle-jdbc-connector.jar` 引入进来。 + +在系统跑的时候,碰到你使用 jdbc 的接口,他会在底层使用你引入的那个 jar 中提供的实现类。 + +### dubbo 的 spi 思想 +dubbo 也用了 spi 思想,不过没有用 jdk 的 spi 机制,是自己实现的一套 spi 机制。 +```java +Protocol protocol = ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtension(); +``` + +Protocol 接口,在系统运行的时候,,dubbo 会判断一下应该选用这个 Protocol 接口的哪个实现类来实例化对象来使用。 + +它会去找一个你配置的 Protocol,将你配置的 Protocol 实现类,加载到 jvm 中来,然后实例化对象,就用你的那个 Protocol 实现类就可以了 + + +上面那行代码就是 dubbo 里大量使用的,就是对很多组件,都是保留一个接口和多个实现,然后在系统运行的时候动态根据配置去找到对应的实现类。如果你没配置,那就走默认的实现好了,没问题。 +```java +@SPI("dubbo") +public interface Protocol { + + int getDefaultPort(); + + @Adaptive + Exporter export(Invoker invoker) throws RpcException; + + @Adaptive + Invoker refer(Class type, URL url) throws RpcException; + + void destroy(); + +} +``` + +在 dubbo 自己的 jar 里,在`/META_INF/dubbo/internal/com.alibaba.dubbo.rpc.Protocol`文件中: +```xml +dubbo=com.alibaba.dubbo.rpc.protocol.dubbo.DubboProtocol +http=com.alibaba.dubbo.rpc.protocol.http.HttpProtocol +hessian=com.alibaba.dubbo.rpc.protocol.hessian.HessianProtocol +``` + +所以说,这就看到了 dubbo 的 spi 机制默认是怎么玩儿的了,其实就是 Protocol 接口,`@SPI(“dubbo”)` 说的是,通过 SPI 机制来提供实现类,实现类是通过 dubbo 作为默认 key 去配置文件里找到的,配置文件名称与接口全限定名一样的,通过 dubbo 作为 key 可以找到默认的实现类就是 `com.alibaba.dubbo.rpc.protocol.dubbo.DubboProtocol`。 + + +如果想要动态替换掉默认的实现类,需要使用 `@Adaptive` 接口,Protocol 接口中,有两个方法加了 `@Adaptive` 注解,就是说那俩接口会被代理实现。 + +啥意思呢? + +比如这个 Protocol 接口搞了俩 `@Adaptive` 注解标注了方法,在运行的时候会针对 Protocol 生成代理类,这个代理类的那俩方法里面会有代理代码,代理代码会在运行的时候动态根据 url 中的 protocol 来获取那个 key,默认是 dubbo,你也可以自己指定,你如果指定了别的 key,那么就会获取别的实现类的实例了。 + +### 如何自己扩展 dubbo 中的组件 +下面来说说怎么来自己扩展 dubbo 中的组件。 + +自己写个工程,要是那种可以打成 jar 包的,里面的 `src/main/resources` 目录下,搞一个 `META-INF/services`,里面放个文件叫:`com.alibaba.dubbo.rpc.Protocol`,文件里搞一个`my=com.bingo.MyProtocol`。自己把 jar 弄到 nexus 私服里去。 + +然后自己搞一个 `dubbo provider` 工程,在这个工程里面依赖你自己搞的那个 jar,然后在 spring 配置文件里给个配置: + + + +provider 启动的时候,就会加载到我们 jar 包里的`my=com.bingo.MyProtocol` 这行配置里,接着会根据你的配置使用你定义好的 MyProtocol 了,这个就是简单说明一下,你通过上述方式,可以替换掉大量的 dubbo 内部的组件,就是扔个你自己的 jar 包,然后配置一下即可。 + +![dubbo-spi](/img/dubbo-spi.png) + +dubbo 里面提供了大量的类似上面的扩展点,就是说,你如果要扩展一个东西,只要自己写个 jar,让你的 consumer 或者是 provider 工程,依赖你的那个 jar,在你的 jar 里指定目录下配置好接口名称对应的文件,里面通过 `key=实现类`。 + +然后对对应的组件,用类似 `` 用你的那个 key 对应的实现类来实现某个接口,你可以自己去扩展 dubbo 的各种功能,提供你自己的实现。 \ No newline at end of file diff --git a/img/dubbo-spi.png b/img/dubbo-spi.png new file mode 100644 index 0000000000000000000000000000000000000000..5c78eb9b5bd850d1057162a123decffd768c6b91 GIT binary patch literal 26408 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