1. 程式人生 > >Jetty - Connector源碼分析

Jetty - Connector源碼分析

緩沖 conf erl 對象 ann 高速 基本 信息 can

1. 描述

基於Jetty-9.4.8.v20171121。

Connector接受遠程機器的連接和數據,允許應用向遠程機器發送數據。

1.2 類圖

從類圖看出AbstractConnector繼承ContainerLifeCycle,所以具有Container和LifeCycle特性。

此外有一個ServerConnector,這個是整個Jetty中很重要的連接器,目前該連接器負責HTTP和HTTPS協議等連接。

ConnectionFactory負責為連接器創建連接對象,不同的連接(HTTP)創建不同的連接對象。

技術分享圖片

1.3 API能力

主要都是一些getter方法,獲取該連接器相關的信息。

@ManagedObject("Connector Interface")
public interface Connector extends LifeCycle, Container, Graceful
{
    // 與這個連接器關聯的服務器
    public Server getServer();

    // 返回執行任務的執行器
    public Executor getExecutor();

    // 返回調度任務的調度器
    public Scheduler getScheduler();

    // 數據緩沖區
    public ByteBufferPool getByteBufferPool();

    // 返回與協議名稱對應的ConnectionFactory對象
    public ConnectionFactory getConnectionFactory(String nextProtocol);
    

    public <T> T getConnectionFactory(Class<T> factoryType);
    
    // 返回默認ConnectionFactory對象
    public ConnectionFactory getDefaultConnectionFactory();
    // 返回所有Connection工廠
    public Collection<ConnectionFactory> getConnectionFactories();
    
    public List<String> getProtocols();
    
    // 返回最大空閑連接時間
    @ManagedAttribute("maximum time a connection can be idle before being closed (in ms)")
    public long getIdleTimeout();

    // 返回這個對象底層的socket,channel,buffer等
    public Object getTransport();
    
    /**
     * @return immutable collection of connected endpoints
     */
    // 返回連接端的不可變集合
    public Collection<EndPoint> getConnectedEndPoints();

    public String getName();
}

2. AbstractConnector

2.1 描述

AbstractConnector利用ConnectionFactory工廠機制為不同協議(HTTP,SSL等)創建Connection實例。  

AbstractConnector管理著連接器必須的幾個基本服務:

(1)Executor:Executor服務用於運行該連接器所需的所有活動任務,(例如接受連接,處理HTTP請求),默認使用Server.getThreadPool作為Executor;

(2)Scheduler:調度器服務用於監視所有連接的空閑超時,並且也可用於監控連接時間,例如異步請求超時,默認使用ScheduledExecutorScheduler實例;

(3)ByteBufferPool:ByteBufferPool服務提供給所有連接,用於從池中獲取和釋放ByteBuffer實例。

這些服務作為bean被Container管理,可以是托管或未托管。

連接器有一個ConnectionFactory集合,每個ConnectionFactory有對應的協議名稱。協議名稱可以是現實的協議比如https/1.1 或http2,甚至可以是私有協議名稱。比如SSL-http/1.1標示SslConnectionFactory,它是由HttpConnectionFactory實例化並且作為HttpConnectionFactory下一個協議。

ConnectionFactory集合可以通過構造函數註入,通過addConnectionFactory,removeConnectionFactory和setConnectionFactories修改。每個協議名稱只能對應一個ConnectionFactory實例,如果兩個ConnectionFactory對應一個協議名稱,那麽第二個將替換第一個。

最新ConnectionFactory通過setDefaultProtocol方法設置,或則第一次配置的協議工廠。

每個ConnectionFactory類型負責它所接受的協議配置。為了配置HTTP協議,你需要傳遞HttpConfiguration實例到HttpConnectionFactory(或者其他支持HTTP的ConnectionFactory);相似地,SslConnectionFactory需要SslContextFactory對象和下一個協議名稱。

(1)ConnectionFactory可以簡單創建Connection對象去支持特定協議。比如HttpConnectionFactory能創建HttpConnection處理http/1.1,http/1.0和http/0.9;

(2)ConnectionFactory也可以通過其他ConnectionFactory創建一系列Connection對象。比如SslConnectionFactory配置了下一個協議名稱,一旦接受了請求創建了SslConnection對象。然後可以通過連接器的getConnectionFactory獲取下一個ConnectionFactory,這個ConnectionFactory產生的Connection可以處理從SslConnection獲取的未加密的數據。

(3)ConnectionFactory也可以創建一個臨時Connection,用於在連接上交換數據,以確定下一個使用的協議。例如,ALPN(Application Layer Protocol Negotiation)協議是SSL的擴展,允許在SSL握手期間指定協議,ALPN用於HTTP2在客戶端與服務器之間通信協商協議。接受一個HTTP2連接,連接器會配置SSL-ALPN, h2,http/1.1。一個新接受的連接使用“SSL-ALPN”,它指定一個帶有“ALPN”的SSLConnectionFactory作為下一個協議。因此,一個SSL連接實例被鏈接到一個ALPN連接實例。ALPN然後與客戶端協商下一個協議,可能是http2,或則http/1.1。一旦決定了下一個協議,ALPN連接調用getConnectionFactory創建連接實例,然後替換ALPN連接。

連接器在運行中並且重復調用accept(int)方法,acceptor任務運行在一個循環中,

accept方法實現必須滿足如下幾點:

(1)阻塞等待新連接;

(2)接受連接(比如socket accept);

(3)配置連接;

(4)調用getDefaultConnectionFactory->ConnectionFactory.newConnection去創建一個新Connection。

acceptor默認的數量是1,數量可以是CPU的個數除以8。具有更多的acceptor可以減少服務器延遲而且可以獲得一個高速的連接(比如http/1.0沒有keepalive)。對於現代持久連接協議(http/1.1,http/2)默認值是足夠的。

2.2 類圖

技術分享圖片

Jetty - Connector源碼分析