tomcat 分配請求之——socket獲取請求

首先,安裝,調試tomcat的源碼:

http://smiky.iteye.com/blog/613151

寫得很全。

=========================================================
     主要描述下 tomcat如何接收請求,並分發處理的,裏面有一些線程處理的細節。挺值得品味的

 

tomcat 等待用戶請求的類:

 protected class Acceptor implements Runnable {

        /**
         * The background thread that listens for incoming TCP/IP connections and hands them off to an appropriate
         * processor.
         */
        public void run() {

            // Loop until we receive a shutdown command
            while (running) {

                // Loop if endpoint is paused
                while (paused) {
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        // Ignore
                    }
                }

                // Accept the next incoming connection from the server socket
                try {
                    // 這裏等待用戶的請求進入,線程會阻塞,直到等到用戶的請求爲止
                    Socket socket = serverSocketFactory.acceptSocket(serverSocket);
                    serverSocketFactory.initSocket(socket);
                    // Hand this socket off to an appropriate processor
                    if (!processSocket(socket)) {
                        // Close socket right away
                        try {
                            socket.close();
                        } catch (IOException e) {
                            // Ignore
                        }
                    }
                } catch (IOException x) {
                    if (running) log.error(sm.getString("endpoint.accept.fail"), x);
                } catch (Throwable t) {
                    log.error(sm.getString("endpoint.accept.fail"), t);
                }

                // The processor will recycle itself when it finishes

            }

        }

    }

 

processSocket方法:

    /**
     * Process given socket.
     */
    protected boolean processSocket(Socket socket) {
        try {
            if (executor == null) {
                // 沒有線程池隊列,從WorkStack中獲取一個,並分配給他做操作(WorkStack相當於線程池的作用)
                getWorkerThread().assign(socket);
            } else {
                // 有線程池隊列,直接new 一個SocketProcessor對這個socket連接做處理
                executor.execute(new SocketProcessor(socket));
            }
        } catch (Throwable t) {
            // This means we got an OOM or similar creating a thread, or that
            // the pool and its queue are full
            log.error(sm.getString("endpoint.process.fail"), t);
            return false;
        }
        return true;
    }

 

工人類:

 protected class Worker implements Runnable {

        protected Thread  thread    = null;
        protected boolean available = false;
        protected Socket  socket    = null;

        /**
         * Process an incoming TCP/IP connection on the specified socket. Any exception that occurs during processing
         * must be logged and swallowed. <b>NOTE</b>: This method is called from our Connector's thread. We must assign
         * it to our own thread so that multiple simultaneous requests can be handled.
         * 
         * @param socket TCP socket to process
         */
        synchronized void assign(Socket socket) {

            // Wait for the Processor to get the previous Socket
            while (available) {
                // 當前Worker是否處於可用狀態
                try {
                    wait();
                } catch (InterruptedException e) {
                }
            }

            // Store the newly available Socket and notify our thread
            this.socket = socket;
            available = true;
            notifyAll();

        }

        /**
         * Await a newly assigned Socket from our Connector, or <code>null</code> if we are supposed to shut down.
         */
        private synchronized Socket await() {

            // 如果處於閒置狀態,就等待新的任務分配
            while (!available) {
                try {
                    wait();
                } catch (InterruptedException e) {
                }
            }

            // Notify the Connector that we have received this Socket
            Socket socket = this.socket;
            available = false;
            notifyAll();

            return (socket);

        }

        /**
         * The background thread that listens for incoming TCP/IP connections and hands them off to an appropriate
         * processor.
         */
        public void run() {

            // Process requests until we receive a shutdown signal
            while (running) {

                // Wait for the next socket to be assigned
                Socket socket = await();
                if (socket == null) continue;

                // 處理該次請求
                if (!setSocketOptions(socket) || !handler.process(socket)) {
                    // Close socket
                    try {
                        socket.close();
                    } catch (IOException e) {
                    }
                }

                // Finish up this request
                socket = null;
                // 回收該線程池的使用
                recycleWorkerThread(this);

            }

        }

 

 以上代碼的大致示意圖:

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章