Jetty - Connector源碼分析
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源碼分析