JBossWeb/Tomcat 初始化連接器和處理 Http 請求過程

來源:互聯網
上載者:User

標籤:tomcat   jbossweb   io   socket   

概述

JBossWeb 是JBoss 中的 Web 容器,他是對 Tomcat 的封裝,本文以 Http 連接器為例,簡單說明 JBossWeb/Tomcat 初始化連接器和處理 Http 請求過程 。本文內容提要:

  • Connector 初始化開始過程
  • 如何理解 max-connections
  • JIoEndpoint 處理 Socket 請求
Connector 初始化開始過程

如所示:


  1. WebConnectorService 指的是 `org.jboss.as.web.WebConnectorService`
  2. Connector 指的是 `org.apache.catalina.connector.Connector`
  3. Http11Protocol 指的是 `org.apache.coyote.http11.Http11Protocol`
  4. JIoEndpoint 指的是 `org.apache.tomcat.util.net.JIoEndpoint`
Connector init() 

Connector 可以是 HTTP Connector,也可以是 AJP Connector,Connector 中有 ProtocolHandler 和 Adapter 屬性,Connector 初始化主要包括:初始化 Adapter,且將初始化的 Adapter 的 設定給 ProtocolHandler,然後調運 ProtocolHandler 的初始化方法,如下面程式碼片段所示:

        // Initializa adapter        adapter = new CoyoteAdapter(this);        protocolHandler.setAdapter(adapter);        IntrospectionUtils.setProperty(protocolHandler, "jkHome", System.getProperty("catalina.base"));        try {            protocolHandler.init();        } catch (Exception e) {            throw new LifecycleException(MESSAGES.protocolHandlerInitFailed(e));        }

Http11Protocol init()

Http11Protocol 它有一個 Http11ConnectionHandler Handler,該 Handler 實現 `org.apache.tomcat.util.net.JIoEndpoint.Handler` 介面,Http11Protocol 同樣有一個 JIoEndpoint 屬性,該屬性用來處理 incoming TCP connections,如下程式碼片段所示:

    protected Http11ConnectionHandler cHandler = new Http11ConnectionHandler(this);    protected JIoEndpoint endpoint = new JIoEndpoint();

Http11Protocol 初始化主要包括:

  • 給 JIoEndpoint 設定名字,預設設定的名字為 http-/127.0.0.1:8080
  • 給 JIoEndpoint 設定 socket handler,設定的 handler 為 Http11ConnectionHandler,該 handler 的作用是 Handling of accepted sockets
  • 調運 JIoEndpoint 的初始化方法
JIoEndpoint init()

JIoEndpoint,關於此類的作用之前我們有說,對該類最直接的總結如下:

/** * Handle incoming TCP connections. * * This class implement a simple server model: one listener thread accepts on a socket and * creates a new worker thread for each incoming connection. * * More advanced Endpoints will reuse the threads, use queues, etc. * * @author James Duncan Davidson * @author Jason Hunter * @author James Todd * @author Costin Manolache * @author Gal Shachor * @author Yoav Shapira * @author Remy Maucherat */public class JIoEndpoint {

JIoEndpoint 初始化包括:

  • 初始化 Acceptor thread count,預設初始設定的 Acceptor thread count 為 1
  • 初始化 ServerSocketFactory,並通過初始化的 ServerSocketFactory 建立 ServerSocket
Connector start()

Connector 開始方法驗證更新當前的狀態,並調運 Http11Protocol 的開始方法

Http11Protocol start()

Http11Protocol 的開始方法中直接調運 JIoEndpoint 的開始方法。

JIoEndpoint start()

JIoEndpoint 的開始方法主要包括:

如果外部基於 Executor 的線程池為空白,則初始化內部的 workers 棧,該棧儲存Worker,初始化的棧大小定義如下:

 protected int maxThreads = (org.apache.tomcat.util.Constants.LOW_MEMORY) ? 64 : ((Constants.MAX_THREADS == -1) ? 512 * Runtime.getRuntime().availableProcessors() : Constants.MAX_THREADS);

如上:

  • 如果通過系統參數 -Dorg.apache.tomcat.util.LOW_MEMORY=true,則初始化的棧大小為 64 
  • 如果通過系統參數 -Dorg.apache.tomcat.util.net.MAX_THREADS=XXX 指定最大值,則初始化的棧大小為系統參數指定的最大值
  • 如果沒有通過系統參數指定 MAX_THREADS,則初始化的棧大小為Runtime.getRuntime().availableProcessors()
啟動 Poller 線程,預設線程的名字為 http-/127.0.0.1:8080-Poller。

啟動 Acceptor 線程,預設線程的名字為 http-/127.0.0.1:8080-Acceptor-0

如下程式碼片段顯示如上邏輯

public void start()        throws Exception {        // Initialize socket if not done before        if (!initialized) {            init();        }        if (!running) {            running = true;            paused = false;            // Create worker collection            if (executor == null) {                workers = new WorkerStack(maxThreads);            }            // Start event poller thread            eventPoller = new Poller();            eventPoller.init();            Thread pollerThread = new Thread(eventPoller, getName() + "-Poller");            pollerThread.setPriority(threadPriority);            pollerThread.setDaemon(true);            pollerThread.start();            // Start acceptor threads            for (int i = 0; i < acceptorThreadCount; i++) {                Thread acceptorThread = new Thread(new Acceptor(), getName() + "-Acceptor-" + i);                acceptorThread.setPriority(threadPriority);                acceptorThread.setDaemon(daemon);                acceptorThread.start();            }        }    }

如何理解 max-connections

JBoss Web 中關於max-connections 的定義如下

<subsystem xmlns="urn:jboss:domain:web:1.4" default-virtual-server="default-host" native="false">            <connector name="http" protocol="HTTP/1.1" scheme="http" socket-binding="http" max-connections="200" />

如上,如果我們定義了 max-connections,WebConnectorService 開始方法中會有如下邏輯:

  • 設定 JIoEndpoint 中 pollerSize,如下代碼:
    protected int pollerSize = (org.apache.tomcat.util.Constants.LOW_MEMORY) ? 128 : (32 * 1024);    public void setPollerSize(int pollerSize) { this.pollerSize = pollerSize; }    public int getPollerSize() { return pollerSize; }

如上,預設的 pollerSize 如果沒有 -Dorg.apache.tomcat.util.LOW_MEMORY=true 設定,它的值為 32 * 1024。

  • 設定 JIoEndpoint 中 maxThreads,如下程式碼片段:
    protected int maxThreads = (org.apache.tomcat.util.Constants.LOW_MEMORY) ? 64 : ((Constants.MAX_THREADS == -1) ? 512 * Runtime.getRuntime().availableProcessors() : Constants.MAX_THREADS);    public void setMaxThreads(int maxThreads) { this.maxThreads = maxThreads; }    public int getMaxThreads() { return maxThreads; }

注意,該 maxThreads 用來初始化內部的 workers 棧的大小。

JIoEndpoint 處理 Socket 請求

JIoEndpoint 處理 Socket 請求如所示


如上,首先 Acceptor 線程(通常名字為 http-/127.0.0.1:8080-Acceptor-0)阻塞等待 Socket 串連,如下所示:

"http-/127.0.0.1:8080-Acceptor-0" daemon prio=10 tid=0x49ed5800 nid=0xbe9 runnable [0x49789000]   java.lang.Thread.State: RUNNABLE        at java.net.PlainSocketImpl.socketAccept(Native Method)        at java.net.AbstractPlainSocketImpl.accept(AbstractPlainSocketImpl.java:398)        at java.net.ServerSocket.implAccept(ServerSocket.java:522)        at java.net.ServerSocket.accept(ServerSocket.java:490)        at org.apache.tomcat.util.net.DefaultServerSocketFactory.acceptSocket(DefaultServerSocketFactory.java:61)        at org.apache.tomcat.util.net.JIoEndpoint$Acceptor.run(JIoEndpoint.java:309)        at java.lang.Thread.run(Thread.java:722)   Locked ownable synchronizers:        - None

//coming soon

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.