dubbo源碼分析(一) 服務暴露--服務引用

又到了面試的時間 爲了應付面試 得準備些乾貨面試

##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

這裏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

###服務暴露

service服務暴露過程 能夠看到最終調用到Protocol對象的export()方法暴露服務. 到這裏就完成了流程上的服務暴露.具體暴露細節由各個協議本身實現.

###服務引用

服務引用過程

經過Protocol的refer()拿到了一個Invoker對象,再經過動態代理生成接口的代理對象,實現rpc通訊

總結: 經過Protocol接口的exporter()和refer()接口,完成流程上的服務暴露和服務引用

dubbo調用過程

###dubbo-protocol層介紹

Protocol接口在dubbo屬於Protocol層.Protocol層中主要有Exporter,Invoker,Protocol三大對象

  • Exporter: 暴露器,可經過其得到Invoker對象
  • 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;

}
相關文章
相關標籤/搜索