又到了面試的時間 爲了應付面試 得準備些乾貨面試
##provider示例spring
<?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協議在20880端口暴露服務 --> <dubbo:protocol name="dubbo" port="20952"/> <!-- 聲明須要暴露的服務接口 --> <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無縫接入了spring 咱們看看是如何實現的app
從上面的配置文件看到dubbo使用了自定義標籤 那麼確定實現了NamespaceHandlerSupport用於解析本身的標籤 能夠找到NamespaceHandlerSupport的實現DubboNamespaceHandler框架
經過META-INF/spring.handlers註冊當前handler,這是spring的拓展機制 這裏很少說ide
這裏DubboNamespaceHandler將解析工做委託給了DubboBeanDefinitionParser 這裏不過多敘述url
DubboBeanDefinitionParser 能夠看到dubbo對於各個自定義標籤解析所用到的類 這裏作個整理spa
標籤 | 解析類 | 做用 |
---|---|---|
application | ApplicationConfig | 應用配置,用於配置當前應用信息,無論該應用是提供者仍是消費者。 |
module | ModuleConfig | 模塊配置,用於配置當前模塊信息,可選。 |
registry | RegistryConfig | 註冊中心配置,用於配置鏈接註冊中心相關信息。 |
monitor | MonitorConfig | 監控中心配置,用於配置鏈接監控中心相關信息,可選。 |
provider | ProviderConfig | 提供方的缺省值,當ProtocolConfig和ServiceConfig某屬性沒有配置時,採用此缺省值,可選。 |
consumer | ConsumerConfig | 消費方缺省配置,當ReferenceConfig某屬性沒有配置時,採用此缺省值,可選。 |
protocol | ProtocolConfig | 協議配置,用於配置提供服務的協議信息,協議由提供方指定,消費方被動接受。 |
service | ServiceBean | 服務配置,用於暴露一個服務,定義服務的元信息,一個服務能夠用多個協議暴露,一個服務也能夠註冊到多個註冊中心。 |
reference | ReferenceBean | 引用配置,用於建立一個遠程服務代理,一個引用能夠指向多個註冊中心。 |
annotation | AnnotationBean | 註解識別處理器 |
這裏具體的標籤屬性解析過程暫不分析 有興趣能夠本身查看原發 DubboBeanDefinitionParser完成了對xml配置的解析 並裝載至spring容器的過程代理
本人對spring的解析機制不是很瞭解,不過經過DubboBeanDefinitionParser能夠看出,最終spring容器加載到的是一個BeanDefinition,能夠理解spring中對對象的抽象實現code
當provider對象解析 裝載完成理所固然是根據配置生成服務 咱們看ServiceBean代碼的實現
public class ServiceBean<T> extends ServiceConfig<T> implements InitializingBean, DisposableBean, ApplicationContextAware, ApplicationListener, BeanNameAware
###服務暴露
能夠看到最終調用到Protocol對象的export()方法暴露服務. 到這裏就完成了流程上的服務暴露.具體暴露細節由各個協議本身實現.
###服務引用
經過Protocol的refer()拿到了一個Invoker對象,再經過動態代理生成接口的代理對象,實現rpc通訊
總結: 經過Protocol接口的exporter()和refer()接口,完成流程上的服務暴露和服務引用
###dubbo-protocol層介紹
Protocol接口在dubbo屬於Protocol層.Protocol層中主要有Exporter,Invoker,Protocol三大對象
Protocol層是dubbo的核心層,只要有Protocol + Invoker + Exporter就能夠完成非透明的RPC調用.
來看Protocol,Exporter,Invoker接口定義
@SPI("dubbo") public interface Protocol { /** * 獲取缺省端口,當用戶沒有配置端口時使用。 * * @return 缺省端口 */ int getDefaultPort(); /** * 暴露遠程服務:<br> * 1. 協議在接收請求時,應記錄請求來源方地址信息:RpcContext.getContext().setRemoteAddress();<br> * 2. export()必須是冪等的,也就是暴露同一個URL的Invoker兩次,和暴露一次沒有區別。<br> * 3. export()傳入的Invoker由框架實現並傳入,協議不須要關心。<br> * * @param <T> 服務的類型 * @param invoker 服務的執行體 * @return exporter 暴露服務的引用,用於取消暴露 * @throws RpcException 當暴露服務出錯時拋出,好比端口已佔用 */ @Adaptive <T> Exporter<T> export(Invoker<T> invoker) throws RpcException; /** * 引用遠程服務:<br> * 1. 當用戶調用refer()所返回的Invoker對象的invoke()方法時,協議需相應執行同URL遠端export()傳入的Invoker對象的invoke()方法。<br> * 2. refer()返回的Invoker由協議實現,協議一般須要在此Invoker中發送遠程請求。<br> * 3. 當url中有設置check=false時,鏈接失敗不能拋出異常,並內部自動恢復。<br> * * @param <T> 服務的類型 * @param type 服務的類型 * @param url 遠程服務的URL地址 * @return invoker 服務的本地代理 * @throws RpcException 當鏈接服務提供方失敗時拋出 */ @Adaptive <T> Invoker<T> refer(Class<T> type, URL url) throws RpcException; /** * 釋放協議:<br> * 1. 取消該協議全部已經暴露和引用的服務。<br> * 2. 釋放協議所佔用的全部資源,好比鏈接和端口。<br> * 3. 協議在釋放後,依然能暴露和引用新的服務。<br> */ void destroy(); } public interface Exporter<T> { Invoker<T> getInvoker(); void unexport(); } ** * Invoker. (API/SPI, Prototype, ThreadSafe) * 分三種: * 1.AbstractInvoker 經過網絡調用遠程服務 (客戶端用) * 2.AbstractProxyInvoker 調用本地實現 (服務端用) * 3.ClusterInvoker 提供集羣服務 (客戶端用) */ public interface Invoker<T> extends Node { Class<T> getInterface(); Result invoke(Invocation invocation) throws RpcException; }