又到了面試的時(shí)間 為了應(yīng)付面試 得準(zhǔn)備些干貨
provider示例
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://code.alibabatech.com/schema/dubbo
http://code.alibabatech.com/schema/dubbo/dubbo.xsd
">
<!-- 用dubbo協(xié)議在20880端口暴露服務(wù) -->
<dubbo:protocol name="dubbo" port="20952"/>
<!-- 聲明需要暴露的服務(wù)接口 -->
<dubbo:service interface="com.***.workorder.facade.exports.ApplyTaskFacade" ref="applyTaskFacadeImpl" version="1.0.0" delay="-1"/>
<dubbo:service interface="com.***.workorder.facade.exports.TaskFacade" ref="taskFacadeImpl" version="1.0.0" delay="-1"/>
</beans>
以上是基本的provider配置
dubbo無(wú)縫接入了spring 我們看看是如何實(shí)現(xiàn)的
從上面的配置文件看到dubbo使用了自定義標(biāo)簽 那么肯定實(shí)現(xiàn)了NamespaceHandlerSupport用于解析自己的標(biāo)簽
可以找到NamespaceHandlerSupport的實(shí)現(xiàn)DubboNamespaceHandler
通過(guò)META-INF/spring.handlers注冊(cè)當(dāng)前handler,這是spring的拓展機(jī)制
這里不多說(shuō)
這里DubboNamespaceHandler將解析工作委托給了DubboBeanDefinitionParser 這里不過(guò)多敘述
DubboBeanDefinitionParser 可以看到dubbo對(duì)于各個(gè)自定義標(biāo)簽解析所用到的類 這里做個(gè)整理
標(biāo)簽 | 解析類 | 作用 |
---|---|---|
application | ApplicationConfig | 應(yīng)用配置音半,用于配置當(dāng)前應(yīng)用信息蜜徽,不管該應(yīng)用是提供者還是消費(fèi)者伐蒂。 |
module | ModuleConfig | 模塊配置驶悟,用于配置當(dāng)前模塊信息械媒,可選。 |
registry | RegistryConfig | 注冊(cè)中心配置词爬,用于配置連接注冊(cè)中心相關(guān)信息镐躲。 |
monitor | MonitorConfig | 監(jiān)控中心配置,用于配置連接監(jiān)控中心相關(guān)信息岖常,可選驯镊。 |
provider | ProviderConfig | 提供方的缺省值,當(dāng)ProtocolConfig和ServiceConfig某屬性沒(méi)有配置時(shí),采用此缺省值板惑,可選橄镜。 |
consumer | ConsumerConfig | 消費(fèi)方缺省配置,當(dāng)ReferenceConfig某屬性沒(méi)有配置時(shí)冯乘,采用此缺省值洽胶,可選。 |
protocol | ProtocolConfig | 協(xié)議配置裆馒,用于配置提供服務(wù)的協(xié)議信息姊氓,協(xié)議由提供方指定,消費(fèi)方被動(dòng)接受喷好。 |
service | ServiceBean | 服務(wù)配置翔横,用于暴露一個(gè)服務(wù),定義服務(wù)的元信息梗搅,一個(gè)服務(wù)可以用多個(gè)協(xié)議暴露禾唁,一個(gè)服務(wù)也可以注冊(cè)到多個(gè)注冊(cè)中心。 |
reference | ReferenceBean | 引用配置无切,用于創(chuàng)建一個(gè)遠(yuǎn)程服務(wù)代理荡短,一個(gè)引用可以指向多個(gè)注冊(cè)中心。 |
annotation | AnnotationBean | 注解識(shí)別處理器 |
這里具體的標(biāo)簽屬性解析過(guò)程暫不分析 有興趣可以自己查看原發(fā)
DubboBeanDefinitionParser完成了對(duì)xml配置的解析 并裝載至spring容器的過(guò)程
本人對(duì)spring的解析機(jī)制不是很了解,不過(guò)通過(guò)DubboBeanDefinitionParser可以看出,最終spring容器加載到的是一個(gè)BeanDefinition,可以理解spring中對(duì)對(duì)象的抽象實(shí)現(xiàn)
當(dāng)provider對(duì)象解析 裝載完成理所當(dāng)然是根據(jù)配置生成服務(wù)
我們看ServiceBean代碼的實(shí)現(xiàn)
public class ServiceBean<T> extends ServiceConfig<T> implements
InitializingBean, DisposableBean, ApplicationContextAware, ApplicationListener, BeanNameAware
服務(wù)暴露
可以看到最終調(diào)用到Protocol對(duì)象的export()方法暴露服務(wù).
到這里就完成了流程上的服務(wù)暴露.具體暴露細(xì)節(jié)由各個(gè)協(xié)議自己實(shí)現(xiàn).
服務(wù)引用
通過(guò)Protocol的refer()拿到了一個(gè)Invoker對(duì)象,再通過(guò)動(dòng)態(tài)代理生成接口的代理對(duì)象,實(shí)現(xiàn)rpc通信
總結(jié): 通過(guò)Protocol接口的exporter()和refer()接口,完成流程上的服務(wù)暴露和服務(wù)引用
dubbo-protocol層介紹
Protocol接口在dubbo屬于Protocol層.Protocol層中主要有Exporter,Invoker,Protocol三大對(duì)象
- Exporter: 暴露器,可通過(guò)其獲得Invoker對(duì)象
- Invoker:(通訊)執(zhí)行器,實(shí)現(xiàn)與遠(yuǎn)端的通信
- Protocol: 抽象協(xié)議,暴露服務(wù)和引用服務(wù)
Protocol層是dubbo的核心層,只要有Protocol + Invoker + Exporter就可以完成非透明的RPC調(diào)用.
來(lái)看Protocol,Exporter,Invoker接口定義
@SPI("dubbo")
public interface Protocol {
/**
* 獲取缺省端口哆键,當(dāng)用戶沒(méi)有配置端口時(shí)使用掘托。
*
* @return 缺省端口
*/
int getDefaultPort();
/**
* 暴露遠(yuǎn)程服務(wù):<br>
* 1. 協(xié)議在接收請(qǐng)求時(shí),應(yīng)記錄請(qǐng)求來(lái)源方地址信息:RpcContext.getContext().setRemoteAddress();<br>
* 2. export()必須是冪等的洼哎,也就是暴露同一個(gè)URL的Invoker兩次烫映,和暴露一次沒(méi)有區(qū)別。<br>
* 3. export()傳入的Invoker由框架實(shí)現(xiàn)并傳入噩峦,協(xié)議不需要關(guān)心锭沟。<br>
*
* @param <T> 服務(wù)的類型
* @param invoker 服務(wù)的執(zhí)行體
* @return exporter 暴露服務(wù)的引用,用于取消暴露
* @throws RpcException 當(dāng)暴露服務(wù)出錯(cuò)時(shí)拋出识补,比如端口已占用
*/
@Adaptive
<T> Exporter<T> export(Invoker<T> invoker) throws RpcException;
/**
* 引用遠(yuǎn)程服務(wù):<br>
* 1. 當(dāng)用戶調(diào)用refer()所返回的Invoker對(duì)象的invoke()方法時(shí)族淮,協(xié)議需相應(yīng)執(zhí)行同URL遠(yuǎn)端export()傳入的Invoker對(duì)象的invoke()方法。<br>
* 2. refer()返回的Invoker由協(xié)議實(shí)現(xiàn)凭涂,協(xié)議通常需要在此Invoker中發(fā)送遠(yuǎn)程請(qǐng)求祝辣。<br>
* 3. 當(dāng)url中有設(shè)置check=false時(shí),連接失敗不能拋出異常切油,并內(nèi)部自動(dòng)恢復(fù)蝙斜。<br>
*
* @param <T> 服務(wù)的類型
* @param type 服務(wù)的類型
* @param url 遠(yuǎn)程服務(wù)的URL地址
* @return invoker 服務(wù)的本地代理
* @throws RpcException 當(dāng)連接服務(wù)提供方失敗時(shí)拋出
*/
@Adaptive
<T> Invoker<T> refer(Class<T> type, URL url) throws RpcException;
/**
* 釋放協(xié)議:<br>
* 1. 取消該協(xié)議所有已經(jīng)暴露和引用的服務(wù)。<br>
* 2. 釋放協(xié)議所占用的所有資源澎胡,比如連接和端口孕荠。<br>
* 3. 協(xié)議在釋放后娩鹉,依然能暴露和引用新的服務(wù)。<br>
*/
void destroy();
}
public interface Exporter<T> {
Invoker<T> getInvoker();
void unexport();
}
**
* Invoker. (API/SPI, Prototype, ThreadSafe)
* 分三種:
* 1.AbstractInvoker 通過(guò)網(wǎng)絡(luò)調(diào)用遠(yuǎn)程服務(wù) (客戶端用)
* 2.AbstractProxyInvoker 調(diào)用本地實(shí)現(xiàn) (服務(wù)端用)
* 3.ClusterInvoker 提供集群服務(wù) (客戶端用)
*/
public interface Invoker<T> extends Node {
Class<T> getInterface();
Result invoke(Invocation invocation) throws RpcException;
}