tomcat 并发 随笔 2-启动

0. 书接上回

	// org.apache.catalina.util.LifecycleBase#start
	@Override
    public final synchronized void start() throws LifecycleException {

        if (LifecycleState.STARTING_PREP.equals(state) || LifecycleState.STARTING.equals(state) ||
                LifecycleState.STARTED.equals(state)) {

            if (log.isDebugEnabled()) {
                Exception e = new LifecycleException();
                log.debug(sm.getString("lifecycleBase.alreadyStarted", toString()), e);
            } else if (log.isInfoEnabled()) {
                log.info(sm.getString("lifecycleBase.alreadyStarted", toString()));
            }

            return;
        }

        if (state.equals(LifecycleState.NEW)) {
			// 注意:因为tomcat组件均是LifecycleBase的子类,故需要区分当前类型
			// 当前还处于 tomcat.server.service.connect 初始化完成的阶段
            init();
        } else if (state.equals(LifecycleState.FAILED)) {
            stop();
        } else if (!state.equals(LifecycleState.INITIALIZED) &&
                !state.equals(LifecycleState.STOPPED)) {
            invalidTransition(Lifecycle.BEFORE_START_EVENT);
        }

        try {
            setStateInternal(LifecycleState.STARTING_PREP, null, false);
			
			// step into ...
			// 接下来即 tomcat.server.service.connect 启动阶段
            startInternal();
            if (state.equals(LifecycleState.FAILED)) {
                // This is a 'controlled' failure. The component put itself into the
                // FAILED state so call stop() to complete the clean-up.
                stop();
            } else if (!state.equals(LifecycleState.STARTING)) {
                // Shouldn't be necessary but acts as a check that sub-classes are
                // doing what they are supposed to.
                invalidTransition(Lifecycle.AFTER_START_EVENT);
            } else {
                setStateInternal(LifecycleState.STARTED, null, false);
            }
        } catch (Throwable t) {
            // This is an 'uncontrolled' failure so put the component into the
            // FAILED state and throw an exception.
            handleSubClassException(t, "lifecycleBase.startFail", toString());
        }
    }
	
	// org.apache.catalina.connector.Connector#startInternal
    @Override
    protected void startInternal() throws LifecycleException {

        // Validate settings before starting
        if (getPort() < 0) {
            throw new LifecycleException(sm.getString(
                    "coyoteConnector.invalidPort", Integer.valueOf(getPort())));
        }

        setState(LifecycleState.STARTING);

        try {
			// step into ...
			// 这里调用了 protocol 的启动方法
            protocolHandler.start();
        } catch (Exception e) {
            throw new LifecycleException(
                    sm.getString("coyoteConnector.protocolHandlerStartFailed"), e);
        }
    }
	
------------------------
	
	@Override
    public void start() throws Exception {
        if (getLog().isInfoEnabled()) {
            getLog().info(sm.getString("abstractProtocolHandler.start", getName()));
        }


		// step into ...
		// 现在的情况就是:protocol的启动过程调用了endpoint的启动方法
        endpoint.start();

        // Start async timeout thread
        asyncTimeout = new AsyncTimeout();
        Thread timeoutThread = new Thread(asyncTimeout, getNameInternal() + "-AsyncTimeout");
        int priority = endpoint.getThreadPriority();
        if (priority < Thread.MIN_PRIORITY || priority > Thread.MAX_PRIORITY) {
            priority = Thread.NORM_PRIORITY;
        }
        timeoutThread.setPriority(priority);
        timeoutThread.setDaemon(true);
        timeoutThread.start();
    }
	
------------------

	// org.apache.tomcat.util.net.AbstractEndpoint#start
    public final void start() throws Exception {
		// 我们前面初始化的时候已经执行过Bind()方法了,并且还设置了状态BOUND_ON_INIT
		// 故,这里不会再执行了
        if (bindState == BindState.UNBOUND) {
            bind();
            bindState = BindState.BOUND_ON_START;
        }
		
		// step into ...
        startInternal();
    }

1. 启动

  • 初始化线程池
  • 初始化poller(runnable),并启动
  • 初始化acceptor(runnable),并启动
	// org.apache.tomcat.util.net.NioEndpoint#startInternal
	/**
     * 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());
            nioChannels = new SynchronizedStack<>(SynchronizedStack.DEFAULT_SIZE,
                    socketProperties.getBufferPool());

            // Create worker collection
            if ( getExecutor() == null ) {
				// tomcat定制了1个线程池(也就是工作线程的线程池)
			    // TaskQueue taskqueue = new TaskQueue();
				// TaskThreadFactory tf = new TaskThreadFactory(getName() + "-exec-", daemon, getThreadPriority());
				// executor = new ThreadPoolExecutor(getMinSpareThreads(), getMaxThreads(), 60, TimeUnit.SECONDS,taskqueue, tf);
				// getMinSpareThreads() 获取最少的备用线程,默认10
				// taskqueue.setParent( (ThreadPoolExecutor) executor);
                createExecutor();
            }

			// 使用最大连接数构建1个栅栏
			// connectionLimitLatch = new LimitLatch(getMaxConnections());
            initializeConnectionLatch();

            // Start poller threads
			// Poller 居然是 endpoint 的内部类
			// public class Poller implements Runnable
			// poller构造干的好事: this.selector = Selector.open();
			// 即 1个poller 对应 1个java.nio.selector
            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);
				// 然后启动这个poller
                pollerThread.start();
            }

			// step into ...
			// 接下来就是 acceptor了
            startAcceptorThreads();
        }
    }
	
	// org.apache.tomcat.util.net.AbstractEndpoint#startAcceptorThreads
	protected final void startAcceptorThreads() {
        int count = getAcceptorThreadCount();
        acceptors = new ArrayList<>(count);

        for (int i = 0; i < count; i++) {
		
			// acceptor构造传入 endpoint,持有其引用
			// public class Acceptor<U> implements Runnable
			// acceptor 看来也是1个runnable
            Acceptor<U> acceptor = new Acceptor<>(this);
            String threadName = getName() + "-Acceptor-" + i;
            acceptor.setThreadName(threadName);
			
			// endpoint.acceptors.add(acceptor)
            acceptors.add(acceptor);
            Thread t = new Thread(acceptor, threadName);
            t.setPriority(getAcceptorThreadPriority());
            t.setDaemon(getDaemon());
			
			// 现在 acceptor 也被启动了
            t.start();
        }
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

肯尼思布赖恩埃德蒙

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值