Tomcat源码学习

之前一直都是只会用tomcat,也只是知道这是个调用各种各样bean的容器,但是却有不少疑问,比如一个http请求如何从客户端到最终处理的servlet手里。今天下了源码来初步学习下,以下为笔记,基于tomcat7.0.4的源码。

当tomcat启动时,调用catalina.bat,然后调用org.apache.catalina.startup.Bootstrap中的main(),再到catalina.java中的load()。

如下是load函数一部分:

Digester digester = createStartDigester();
file = configFile();
inputStream = new FileInputStream(file);
digester.parse(inputSource);//解析conf/server.xml文件
getServer().init();

server.xml中,有如下结构:

<Server port="8005" shutdown="SHUTDOWN">
  <Listener className="org.apache.catalina.startup.VersionLoggerListener" />
                             .............. 
  <!-- Global JNDI resources
       Documentation at /docs/jndi-resources-howto.html
  -->
  <GlobalNamingResources>
    <!-- Editable user database that can also be used by
         UserDatabaseRealm to authenticate users
    -->
    <Resource name="UserDatabase" auth="Container"
              type="org.apache.catalina.UserDatabase"
              description="User database that can be updated and saved"
              factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
              pathname="conf/tomcat-users.xml" />
  </GlobalNamingResources>

  <Service name="Catalina">

    <!--The connectors can use a shared executor, you can define one or more named thread pools-->
    <!--
    <Executor name="tomcatThreadPool" namePrefix="catalina-exec-"
        maxThreads="150" minSpareThreads="4"/>
    -->


    <Connector port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" />
                        ................ 
    <!-- Define an AJP 1.3 Connector on port 8009 -->
    <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />

    <!-- You should set jvmRoute to support load-balancing via AJP ie :
    <Engine name="Catalina" defaultHost="localhost" jvmRoute="jvm1">
    -->

  </Service>
</Server>

createStartDigester()中初始化了StandardServer/StandardService/StandardThreadExecutor/Connector等对象。

protected Digester createStartDigester() {
                     .........
        // Configure the actions we will be using
        digester.addObjectCreate("Server",
                                 "org.apache.catalina.core.StandardServer",
                                 "className");
        digester.addSetProperties("Server");
        digester.addSetNext("Server",
                            "setServer",
                            "org.apache.catalina.Server");

                      ........
         }

当Server起来后,StandardService就会被start,如下:

protected void startInternal() throws LifecycleException {


        // Start our defined Container first
        if (container != null) {
            synchronized (container) {
                container.start();
            }
        }

        synchronized (executors) {
            for (Executor executor: executors) {
                executor.start();
            }
        }

        // Start our defined Connectors second
        synchronized (connectors) {
            for (Connector connector: connectors) {
                try {
                    // If it has already failed, don't try and start it
                    if (connector.getState() != LifecycleState.FAILED) {
                        connector.start();
                    }
                } catch (Exception e) {
                    log.error(sm.getString(
                            "standardService.connector.startFailed",
                            connector), e);
                }
            }
        }
    }

Service会启动它的连接器和容器,一个Service包含一个容器和多个连接器。

由于server.xml中定义的协议不同,连接器一般用Http11Protocol或者AjpProtocol

Http11Protocol的构造函数中

public Http11Protocol() {
        endpoint = new JIoEndpoint();//初始化JIoEndpoint
        cHandler = new Http11ConnectionHandler(this);//指定处理每个请求的Handler
        ((JIoEndpoint) endpoint).setHandler(cHandler);
    }

会遇到JIoEndpoint这个东西,这是个处理socket请求的类。在他的类的注释中

This class implement a simple server model: one listener thread accepts on a socket and creates a new worker thread for each incoming connection.

说明了他的作用是接受客户端请求并且为每个请求单独建立新的线程来处理。

其中包含了三个子类:SocketProcessor(实际处理每个请求)、Acceptor(分发每个请求)、AsyncTimeout(看起来是超时机制)

我们来看下JIoEndpoint.startInternal()函数:

createExecutor();//建立一个线程池,可以定义最大并发数量
startAcceptorThreads();//建立一个监听线程,具体线程类为Acceptor
bind。。。。listen。。。

当用户发起请求后,Acceptor中的processSocket()会处理这个请求,调用线程池中的空闲资源:getExecutor().execute(new SocketProcessor(wrapper)); 由Http11Connector的构造函数中可以看到,具体的请求handler是Http11ConnectionHandler类。

鉴于后面都是按照debug的断点一步步的跟踪了,所以就不写了,总之最后就是会new到具体的cmdServlet对象并调用到具体的处理http请求的servlet。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值