1. 程式人生 > >Dubbo服務框架解析(二)

Dubbo服務框架解析(二)

換行符 spi track .net int apt thread exce -i

本節介紹dubbo-common,dubbo-common是公共邏輯模塊,包含Util類、通用模型,是其他模塊的基礎。


擴展機制

技術分享

SPI

SPI是擴展點的註解。標註在類型上。全部的擴展點須要通過SPI來標註。

約定:

在擴展類的jar包內。放置擴展點配置文件:META-INF/dubbo/接口全限定名,內容為:配置名=擴展實現類全限定名,多個實現類用換行符分隔。

1) 自己主動Wrap擴展點的Wrapper類

ExtensionLoader會在載入擴展點時(通過擴展點配置文件裏內容)。假設該實現有拷貝構造函數。則判定為擴展點Wrapper類。

2) 自己主動註入關聯擴展點

載入擴展點時,擴展點實現類的成員假設為其他擴展點類型,ExtensionLoader在會自己主動註入依賴的擴展點。

3) 缺省獲得的的擴展點是一個Adaptive Instance

假設ExtensionLoader註入的依賴擴展點是一個Adaptive實例,直到擴展點方法運行時才決定調用是一個擴展點實現。

Adaptive

實現擴展點的自適應,能夠標註在類型和方法上。在ExtensionLoader生成Extension的Adaptive Instance時。為ExtensionLoader提供擴展點信息。

以下是Dubbo的Transporter擴展點的代碼:

@SPI("netty")

publicinterfaceTransporter{

/**

* Bind a server.

*

* @seecom.alibaba.dubbo.remoting.Transporters#bind(URL, Receiver, ChannelHandler)

* @param url serverurl

* @param handler

* @return server

* @throws RemotingException

*/

@Adaptive({Constants.SERVER_KEY, Constants.TRANSPORTER_KEY})

Server bind(URL url, ChannelHandlerhandler)throws RemotingException;

/**

* Connect to a server.

*

* @seecom.alibaba.dubbo.remoting.Transporters#connect(URL, Receiver, ChannelListener)

* @param url serverurl

* @param handler

* @return client

* @throws RemotingException

*/

@Adaptive({Constants.CLIENT_KEY, Constants.TRANSPORTER_KEY})

Client connect(URL url, ChannelHandlerhandler)throws RemotingException;

}

對於bind方法,Adaptive實現先查找"server"key,假設該Key沒有值則找"transport"key值。來決定代理到哪個實際擴展點。

ExtensionFactory

ExtensionFactory本身也是一種SPI。屬於擴展點本身的載入容器,可從不同容器載入擴展點。

技術分享

當中AdaptiveExtensionFactory標註為Adaptive,支持擴展點的自己主動激活。當例如以下所看到的沒有參數時。屬於無條件自己主動激活。

@Adaptive

publicclass AdaptiveExtensionFactoryimplementsExtensionFactory

當有參數時,為有條件激活。

Logger

Logger也是一種擴展。

當中LoggerAdapter適配接口是一種SPI。

技術分享

在Dubbo中,實現了JCL、JDK、Log4J和Slf4J的多種實現。

例如以下圖所看到的我們經常使用的兩種。

技術分享

ThreadPool

ThreadPool也是一種擴展SPI。

服務提供方線程實現策略。當server收到一個請求時。須要在線程池中創建一個線程去運行服務提供方業務邏輯。

@SPI("fixed")

publicinterfaceThreadPool{

/**

* 線程池

*

* @param url線程參數

* @return線程池

*/

@Adaptive({Constants.THREADPOOL_KEY})

Executor getExecutor(URL url);

}

如上SPI的參數作為默認的線程池類型,getExecutor方法中,通過"threadpool"的key來做到自適應擴展。

在Dubbo中實現了Fixed、Cached和Limited多種線程池的實現。

技術分享

Serialize

Serialize是這裏的核心接口。將對象轉成字節流。用於網絡傳輸,以及將字節流轉為對象,用於在收到字節流數據後還原成對象。

下圖是Dubbo中定義的接口。

技術分享

下圖是Dubbo中定義的擴展實現。各自是:

  • NativeJavaSerialization:原生java序列化實現。
  • CompactedJavaSerialization:壓縮java序列化,主要是在原生java序列化基礎上,實現了自己定義的類描寫敘述符寫入和讀取。寫Object類型的類描寫敘述符僅僅寫入類名稱,而不是類的完整信息。這樣有非常多Object類型的情況下能夠降低序列化後的size。
  • JavaSerialization:僅僅是對原生java序列化和壓縮java序列化的封裝。

  • JsonSerialization:原生JSON序列化實現。

  • FastJsonSerialization:使用阿裏的FastJson實現的序列化。
  • Hessian2Serialization:使用Hessian2的IO機制實現的序列化。

  • DubboSerialization:Dubbo自己定義的序列化實現。

技術分享

Compiler

Compiler是SPI。Java代碼編譯器。用於動態生成字節碼,加速調用。

技術分享

實現了JDK和Javassist的實現。當中使用的Javassist是一個開源的分析、編輯和創建Java字節碼的類庫。Javassist是JBoss的一個子項目,其基本的長處,在於簡單。並且高速。


Dubbo服務框架解析(二)