tomcat建立连接

来源:互联网 发布:mac怎么装虚拟机win10 编辑:程序博客网 时间:2024/05/21 07:49

参考资料: Tomcat7.0源码分析——请求原理分析(上)


servlet应用放入tomcat中启动后就可以接受请求,那在tomcat中是怎么实现的呢?


1、ProtocolHandler接口是真正处理请求的地方,这个接口是在Connector中初始化的。在Connector中有两个方法用来初始化和启动ProtocolHandler

    @Override    protected void initInternal() throws LifecycleException {        super.initInternal();        // 构造Adapter对象,Adapter用来适配不同的网络协议        adapter = new CoyoteAdapter(this);        protocolHandler.setAdapter(adapter);        if (null == parseBodyMethodsSet) {            setParseBodyMethods(getParseBodyMethods());        }        try {            // 初始化ProtocolHandler,ProtocolHandler用来处理请求            protocolHandler.init();        } catch (Exception e) {            throw new LifecycleException(sm.getString("coyoteConnector.protocolHandlerInitializationFailed"), e);        }        // 初始化MapperListener,MapperListener注册host        mapperListener.init();    }    @Override    protected void startInternal() throws LifecycleException {        if (getPort() < 0) {            throw new LifecycleException(sm.getString("coyoteConnector.invalidPort", Integer.valueOf(getPort())));        }        // 设置Connector已经启动        setState(LifecycleState.STARTING);        try {            // 启动protocolHandler            protocolHandler.start();        } catch (Exception e) {            String errPrefix = "";            if (this.service != null) {                errPrefix += "service.getName(): \"" + this.service.getName() + "\"; ";            }            throw new LifecycleException(errPrefix + " " + sm.getString("coyoteConnector.protocolHandlerStartFailed"), e);        }        // 启动MapperListener        mapperListener.start();    }


2、我们来看看初始化ProtocolHandler的方法,ProtocolHandler默认使用Http11Protocol实例化,Http11Protocol直接继承了AbstractProtocol的init方法。

    @Override    public void init() throws Exception {        if (getLog().isInfoEnabled()) {            getLog().info(sm.getString("abstractProtocolHandler.init", getName()));        }        if (oname == null) {            oname = createObjectName();            if (oname != null) {                Registry.getRegistry(null, null).registerComponent(this, oname, null);            }        }        if (this.domain != null) {            try {                tpOname = new ObjectName(domain + ":type=ThreadPool,name=" + getName());                Registry.getRegistry(null, null).registerComponent(endpoint, tpOname, null);            } catch (Exception e) {                getLog().error(sm.getString("abstractProtocolHandler.mbeanRegistrationFailed", tpOname, getName()), e);            }            rgOname = new ObjectName(domain + ":type=GlobalRequestProcessor,name=" + getName());            Registry.getRegistry(null, null).registerComponent(getHandler().getGlobal(), rgOname, null);        }        String endpointName = getName();        endpoint.setName(endpointName.substring(1, endpointName.length() - 1));        try {            // 重点是这个方法,JIoEndpoint做为初始化的实现,创建服务器socket            endpoint.init();        } catch (Exception ex) {            getLog().error(sm.getString("abstractProtocolHandler.initError",                    getName()), ex);            throw ex;        }    }



3、JioEndpoint创建socket的方法

    @Override    public void bind() throws Exception {        // 初始化接受请求线程数量        if (acceptorThreadCount == 0) {            acceptorThreadCount = 1;        }        // 初始化socket最大连接数        if (getMaxConnections() == 0) {            setMaxConnections(getMaxThreads());        }        if (serverSocketFactory == null) {            if (isSSLEnabled()) {                // 创建Socket工厂                serverSocketFactory = handler.getSslImplementation().getServerSocketFactory(this);            } else {                serverSocketFactory = new DefaultServerSocketFactory(this);            }        }        if (serverSocket == null) {            try {                if (getAddress() == null) {                    // 创建服务器socket                    serverSocket = serverSocketFactory.createSocket(getPort(), getBacklog());                } else {                    serverSocket = serverSocketFactory.createSocket(getPort(), getBacklog(), getAddress());                }            } catch (BindException orig) {                String msg;                if (getAddress() == null)                    msg = orig.getMessage() + " <null>:" + getPort();                else                    msg = orig.getMessage() + getAddress().toString() + ":" + getPort();                BindException be = new BindException(msg);                be.initCause(orig);                throw be;            }        }    }



4、现在我们的服务端socket已经创建好了,接下来启动这个socket,启动和初始化相似,Http11Protocol直接继承了AbstractProtocol的start方法。

    @Override    public void start() throws Exception {        if (getLog().isInfoEnabled())            getLog().info(sm.getString("abstractProtocolHandler.start", getName()));        try {            // 还是交给JIoEndpoint来启动            endpoint.start();        } catch (Exception ex) {            getLog().error(sm.getString("abstractProtocolHandler.startError", getName()), ex);            throw ex;        }    }


5、JioEndpoint启动socket的方法

    @Override    public void startInternal() throws Exception {        if (!running) {            running = true;            paused = false;            if (getExecutor() == null) {                // 初始化线程池                createExecutor();            }            // 设置最大连接数,超过阻塞线程            initializeConnectionLatch();            // 启动接受请求的线程            startAcceptorThreads();            // 启动链接超时的线程            Thread timeoutThread = new Thread(new AsyncTimeout(), getName() + "-AsyncTimeout");            timeoutThread.setPriority(threadPriority);            timeoutThread.setDaemon(true);            timeoutThread.start();        }    }


6、初始化线程池

    public void createExecutor() {        internalExecutor = true;        // 创建任务队列        TaskQueue taskqueue = new TaskQueue();        // 创建线程工厂        TaskThreadFactory tf = new TaskThreadFactory(getName() + "-exec-", daemon, getThreadPriority());        // 初始化线程池        executor = new ThreadPoolExecutor(getMinSpareThreads(), getMaxThreads(), 60, TimeUnit.SECONDS,taskqueue, tf);        // 任务队列使用线程池产生        taskqueue.setParent( (ThreadPoolExecutor) executor);    }


7、启动接受请求的线程

    protected final void startAcceptorThreads() {        // 创建一个线程数组        int count = getAcceptorThreadCount();        acceptors = new Acceptor[count];        for (int i = 0; i < count; i++) {            // 实例化线程类            acceptors[i] = createAcceptor();            //  使用Thread 启动            Thread t = new Thread(acceptors[i], getName() + "-Acceptor-" + i);            t.setPriority(getAcceptorThreadPriority());            t.setDaemon(getDaemon());            t.start();        }    }


8、接受请求的线程类

    protected class Acceptor extends AbstractEndpoint.Acceptor {        @Override        public void run() {            int errorDelay = 0;            // 无限循环直接接受到shutdown后退出            while (running) {                // 收到线程暂停的命令后暂停50ms                while (paused && running) {                    state = AcceptorState.PAUSED;                    try {                        Thread.sleep(50);                    } catch (InterruptedException e) {                    }                }                if (!running) {                    break;                }                state = AcceptorState.RUNNING;                try {                    // 达到了最大连接数,线程阻塞                    countUpOrAwaitConnection();                    Socket socket = null;                    try {                        // 从服务端socket接受链接                        socket = serverSocketFactory.acceptSocket(serverSocket);                    } catch (IOException ioe) {                        errorDelay = handleExceptionWithDelay(errorDelay);                        throw ioe;                    }                    errorDelay = 0;                    if (running && !paused && setSocketOptions(socket)) {                        if (!processSocket(socket)) {                            closeSocket(socket);                        }                    } else {                        closeSocket(socket);                    }                } catch (IOException x) {                    if (running) {                        log.error(sm.getString("endpoint.accept.fail"), x);                    }                } catch (NullPointerException npe) {                    if (running) {                        log.error(sm.getString("endpoint.accept.fail"), npe);                    }                } catch (Throwable t) {                    ExceptionUtils.handleThrowable(t);                    log.error(sm.getString("endpoint.accept.fail"), t);                }            }            state = AcceptorState.ENDED;        }    }


到此为止,请求和服务器之间的链接已经建立好了。


原创粉丝点击