美文网首页
tomcat 8.x NioEndpoint核心组件浅析1

tomcat 8.x NioEndpoint核心组件浅析1

作者: 杭州_mina | 来源:发表于2017-06-26 23:00 被阅读0次

    1. Nio初始化阶段

    • 1.1 NioEndpoint 实现了建立连接、处理连接、和关闭连接等操作,在看NioEndpoint之前先看一下下面的uml图

      image.png
      以上图把整个NioEndpoint的核心关系展示出来了,我们在看下图tomcat中 nio的网络模型借用了网上的图片
      image.png
    • 1.2 acceptor 顾名思义用来处理链接 我们来看一下他在NioEndpoint中的实现

     /**
         * 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());
                //申请nioChannel 默认128个 为什么有这个东西 
                //其实这个东西就是申请了系统内存io读写直接使用系统内存的效率比堆内存好快很多
                //当然申请系统内存会有很大的开销,所以直接初始一些出来,这样要用的时候直接可以使用、当socket关闭的时候、nioChannel并不会被销毁、而是重新放入这个队列中、重复被使用
                //总之可以理解内核复用技术、类似netty的内核复用技术
                nioChannels = new SynchronizedStack<>(SynchronizedStack.DEFAULT_SIZE,
                        socketProperties.getBufferPool());
    
                if ( getExecutor() == null ) {
                  //构建线程池对应上图的executor 它是用来处理SocketProcessor
                  //换句话主要是用来对socket进行读写封装成request对象然后做业务处理
                  //我们常常用的controller也是使用这个线程来执行的 
                    createExecutor();
                }
    
                initializeConnectionLatch();
    
                // Start poller threads
                // 初始化poller默认是两个poller
                // poller主要循环扫描PollerEvent队列是否存在待处理请求
                // 如果存在PollerEvent待处理,进行请求解析封装
                // 启动Executor线程进行请求读处理
                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();
                }
                //启动Acceptor 默认使用一单线程处理连接
                startAcceptorThreads();
            }
        }
    

    来看一下startAcceptorThreads的源码

    protected final void startAcceptorThreads() {
           //acceptor连接池个数 默认为一个
           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等核心组件初始化的过程

    相关文章

      网友评论

          本文标题:tomcat 8.x NioEndpoint核心组件浅析1

          本文链接:https://www.haomeiwen.com/subject/ahzjcxtx.html