tomcat 8.x NioEndpoint核心組件淺析1

1. Nio初始化階段

  • 1.1 NioEndpoint 實(shí)現(xiàn)了建立連接、處理連接、和關(guān)閉連接等操作,在看NioEndpoint之前先看一下下面的uml圖

    image.png

    以上圖把整個(gè)NioEndpoint的核心關(guān)系展示出來了,我們?cè)诳聪聢Dtomcat中 nio的網(wǎng)絡(luò)模型借用了網(wǎng)上的圖片
    image.png

  • 1.2 acceptor 顧名思義用來處理鏈接 我們來看一下他在NioEndpoint中的實(shí)現(xiàn)

 /**
     * Start the NIO endpoint, creating acceptor, poller threads.
     */
    @Override
    public void startInternal() throws Exception {

        if (!running) {
            running = true;
            paused = false;

            processorCache = new SynchronizedStack<>(SynchronizedStack.DEFAULT_SIZE,
                    socketProperties.getProcessorCache());
            eventCache = new SynchronizedStack<>(SynchronizedStack.DEFAULT_SIZE,
                            socketProperties.getEventCache());
            //申請(qǐng)nioChannel 默認(rèn)128個(gè) 為什么有這個(gè)東西 
            //其實(shí)這個(gè)東西就是申請(qǐng)了系統(tǒng)內(nèi)存io讀寫直接使用系統(tǒng)內(nèi)存的效率比堆內(nèi)存好快很多
            //當(dāng)然申請(qǐng)系統(tǒng)內(nèi)存會(huì)有很大的開銷,所以直接初始一些出來,這樣要用的時(shí)候直接可以使用、當(dāng)socket關(guān)閉的時(shí)候、nioChannel并不會(huì)被銷毀、而是重新放入這個(gè)隊(duì)列中、重復(fù)被使用
            //總之可以理解內(nèi)核復(fù)用技術(shù)、類似netty的內(nèi)核復(fù)用技術(shù)
            nioChannels = new SynchronizedStack<>(SynchronizedStack.DEFAULT_SIZE,
                    socketProperties.getBufferPool());

            if ( getExecutor() == null ) {
              //構(gòu)建線程池對(duì)應(yīng)上圖的executor 它是用來處理SocketProcessor
              //換句話主要是用來對(duì)socket進(jìn)行讀寫封裝成request對(duì)象然后做業(yè)務(wù)處理
              //我們常常用的controller也是使用這個(gè)線程來執(zhí)行的 
                createExecutor();
            }

            initializeConnectionLatch();

            // Start poller threads
            // 初始化poller默認(rèn)是兩個(gè)poller
            // poller主要循環(huán)掃描PollerEvent隊(duì)列是否存在待處理請(qǐng)求
            // 如果存在PollerEvent待處理,進(jìn)行請(qǐng)求解析封裝
            // 啟動(dòng)Executor線程進(jìn)行請(qǐng)求讀處理
            pollers = new Poller[getPollerThreadCount()];
            for (int i=0; i<pollers.length; i++) {
                pollers[i] = new Poller();
                Thread pollerThread = new Thread(pollers[i], getName() + "-ClientPoller-"+i);
                pollerThread.setPriority(threadPriority);
                pollerThread.setDaemon(true);
                pollerThread.start();
            }
            //啟動(dòng)Acceptor 默認(rèn)使用一單線程處理連接
            startAcceptorThreads();
        }
    }

來看一下startAcceptorThreads的源碼

protected final void startAcceptorThreads() {
       //acceptor連接池個(gè)數(shù) 默認(rèn)為一個(gè)
       int count = getAcceptorThreadCount();
       acceptors = new Acceptor[count];

       for (int i = 0; i < count; i++) {
           acceptors[i] = createAcceptor();
           String threadName = getName() + "-Acceptor-" + i;
           acceptors[i].setThreadName(threadName);
           Thread t = new Thread(acceptors[i], threadName);
           t.setPriority(getAcceptorThreadPriority());
           t.setDaemon(getDaemon());
           t.start();
       }
   }

以上就是Accetor、poller、Executor等核心組件初始化的過程

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 134,915評(píng)論 18 139
  • 從三月份找實(shí)習(xí)到現(xiàn)在,面了一些公司,掛了不少,但最終還是拿到小米、百度、阿里、京東、新浪、CVTE、樂視家的研發(fā)崗...
    時(shí)芥藍(lán)閱讀 42,366評(píng)論 11 349
  • 概述 Tomcat是一個(gè)JSP/Servlet容器。其作為Servlet容器,有三種工作模式:獨(dú)立的Servlet...
    jiangmo閱讀 2,256評(píng)論 0 13
  • 如果我還會(huì)遠(yuǎn)行 我會(huì)帶上我的母親 避風(fēng)來、避雨淋、避開時(shí)光的約定 看清晨太陽 喝午后清茶 守望夜晚的月亮,星星 我...
    燕返樓蘭閱讀 221評(píng)論 0 2
  • 一個(gè)個(gè)的 ...
    喜歡詩詞的女孩閱讀 9,363評(píng)論 0 2