欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Tomcat认知

程序员文章站 2022-07-14 11:18:14
...

Tomcat认识

Tomcat是由Apache软件基金会下属的Jakarta项目开发的一个Servlet容器,按照Sun Microsystems提供的技术规范,实现了对Servlet和JavaServer Page(JSP)的支持,并提供了作为Web服务器的一些特有功能,如Tomcat管理和控制平台、安全域管理和Tomcat阀等。由于Tomcat本身也内含了一个HTTP服务器,它也可以被视作一个单独的Web服务器。——来自维百科

下载安装Tomcat

  1. 下载Tomcat
  2. 解压下载好的zip到指定工作目录(注意安装目录不能包含空格和中文)
  3. 配置支持Tomcat运行的环境变量JAVA_HOME(到jdk的安装目录即可)
  4. 其它注意问题:
    • 端口占用问题:可以在cmd下输入netstat -ano命令查看端口占用信息
    • Catalina_Home环境变量: 点击startup.bat启动哪个tomcat由此环境变量指定,如果不配置则启动当前tomcat,推荐不要配置此环境变量

Tomcat文件目录结构

  1. bin :Tomcat启动/关闭等批处理文件所在位置
  2. conf:Tomcat相关配置文件所在位置(重要)
  3. lib:支持Tomcat运行所需jar包所在位置
  4. logs:Tomcat运行时产生的日志文件所在位置
  5. temp:Tomcat运行时所产生的临时文件所在位置
  6. webapps:web应用部署位置(重要)
  7. work:Tomcat工作目录

Tomcat容器的结构(server.xml)

注意:某些结构本身并不是容器,所以不存在包含关系,建议用调度的角度去理解

Tomcat认知

  1. server element

    代表整个容器,是Tomcat实例的顶层元素

  2. service element

    代表包含一个管理Host的Engine和多个监听器Connector的集合,负责监听并安排处理客户端的请求

  3. Connector element

    代表与客户程序实际交互的给件,它负责接收客户请求,以及向客户返回响应结果.

    • Coyote Http/1.1 Connector 在端口处侦听来自客户浏览器的http请求
    • Coyote JK2 Connector 在端口处侦听来自其它WebServer(Apache)的servlet/jsp代理请求
  4. Engine element

    Engine代表Connector接收请求后的入口,分析包含在请求中的http头消息,然后匹配对应的主机,若没有匹配到,使用默认主机
    px:在该元素下可以配置多台虚拟主机

  5. Host element

    代表虚拟主机,它可以解析对应的应用路径,每个虚拟主机下可部署一个或多个web应用

  6. Context element

    代表了运行在Host主机下的当个web应用

Tomcat配置文件

server.xml

<?xml version="1.0" encoding="UTF-8"?>

<!-- 父级元素
     监听8005端口等待关闭命令
     接收到SHOUTDOWN关闭服务器 
     -->

<Server port="8005" shutdown="SHUTDOWN">

   <!-- 各种对服务的监听器 -->

   <Listener className="org.apache.catalina.startup.VersionLoggerListener" />
   <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
   <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
   <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
   <Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />

  <!-- 全局资源 -->
  <GlobalNamingResources>
  <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集合 -->
  <Service name="Catalina">

  <!-- HTTP报文监听器
       监听8080端口
       redirectport : 当客户请求是https时,把该请求转发到端口8443去 
       minProcessors : 最小线程数,开始时创建的保持常态的线程数  
       maxProcessors : 最大线程数,当现有的线程不够服务客户请求时,若线程总数不足该数个数,则创建新线程来处理请求
       connectionTimeout:连接超时时间  
       -->
  <Connector port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" />

  <!-- AJP报文监听器
       监听8009端口 
       -->
  <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />

  <!-- Engine
       defauletHost:默认主机
       -->
  <Engine name="Catalina" defaultHost="localhost">

  <!-- 虚拟主机localhost  
           appBase : 该虚拟主机的根目录是webapps/  
           它将匹配请求和自己的Context的路径,并把请求转交给对应的Context来处理
           autoDeploy:设置自动部署  
           --> 
  <Host name="localhost"  appBase="webapps"
            unpackWARs="true" autoDeploy="true">
  <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
               prefix="localhost_access_log" suffix=".txt"
               pattern="%h %l %u %t &quot;%r&quot; %s %b" />

   <!-- Context,WebApp  
             path : 该Context的路径名,若为""则该Context为默认Context  
             docBase : 该Context的根目录是webapps/test/  
             -->  
   <Context path="" docBase="test" debug="0"/>  
      </Host>
    </Engine>
  </Service>
</Server>

context.xml

<?xml version="1.0" encoding="UTF-8"?>
<Context>

<WatchedResource>WEB-INF/web.xml</WatchedResource>
                            <WatchedResource>${catalina.base}/conf/web.xml</WatchedResource>
    <!-- 设置JNDI -->
    <Environment name="hncu" value="hello welcome use jndi" type="java.lang.String" />
    <!-- 设置服务器托管数据源此处使用的是Tomcat的dbcp -->
    <Resource name="jdbc/dbcp" auth="Container" type="javax.sql.DataSource"
              maxTotal="30" maxIdle="20" maxWaitMillis="10000"
              username="root" password="root" driverClassName="com.mysql.jdbc.Driver"
              url="jdbc:mysql://localhost:3306/test"/>

    <resource-ref>
        <res-ref-name>jdbc/test</res-ref-name>
        <res-type>javax.sql.DataSource</res-type>
        <res-auth>Container</res-auth>
    </resource-ref>
    <!-- 托管c3p0 -->
    <Resource name="jdbc/c3p0" auth="Container"
              type="com.mchange.v2.c3p0.ComboPooledDataSource"
              factory="org.apache.naming.factory.BeanFactory"
              driverClass="com.mysql.jdbc.Driver"
              jdbcUrl="jdbc:mysql://localhost:3306/test?useUnicode=true&amp;characterEncoding=utf-8"
              user="root"
              password="root"
              minPoolSize="10"
              maxPoolSize="30"
              maxIdleTime="1800"
              acquireIncrement="2"
              maxStatements="0"
              initialPoolSize="20"
              idleConnectionTestPeriod="60"
              acquireRetryAttempts="30"
              acquireRetryDelay="1000"
              testConnectionOnCheckin="false"
              breakAfterAcquireFailure="false"
              testConnectionOnCheckout="false"/>
</Context>

tomcat-users.xml

<?xml version="1.0" encoding="UTF-8"?>
<tomcat-users xmlns="http://tomcat.apache.org/xml"
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xsi:schemaLocation="http://tomcat.apache.org/xml tomcat-users.xsd"
              version="1.0">
<!-- 配置账户密码 -->
<role rolename="tomcat"/>
<role rolename="role1"/>
<user username="tomcat" password="tomcat" roles="tomcat"/>
<user username="tomcat" password="tomcat" roles="tomcat,role1"/>
<user username="tomcat" password="tomcat" roles="role1"/>

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="h
  ttp://xmlns.jcp.org/xml/ns/javaee
                      http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
  version="3.1">
  <!-- 默认servlet,所有servlet都无法匹配时执行该servlet -->
  <servlet>
        <servlet-name>default</servlet-name>
        <servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>
        <!-- 初识servlet参数 -->
        <init-param>
            <param-name>debug</param-name>
            <param-value>0</param-value>
        </init-param>
        <init-param>
            <param-name>listings</param-name>
            <param-value>false</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <!--当请求的是一个JSP页面的时候(*.jsp)该servlet被调用  
           它是一个JSP编译器,将请求的JSP页面编译成为servlet再执行 
     -->
    <servlet>
        <servlet-name>jsp</servlet-name>
        <servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class>
        <init-param>
            <param-name>fork</param-name>
            <param-value>false</param-value>
        </init-param>
        <init-param>
            <param-name>xpoweredBy</param-name>
            <param-value>false</param-value>
        </init-param>
        <load-on-startup>3</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>default</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>jsp</servlet-name>
        <url-pattern>*.jsp</url-pattern>
        <url-pattern>*.jspx</url-pattern>
    </servlet-mapping>
    <!-- 配置session -->
    <session-config>
        <session-timeout>30</session-timeout>
    </session-config>
    <welcome-file-list>
        <welcome-file>index.html</welcome-file>
        <welcome-file>index.htm</welcome-file>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>

</web-app>

Tomcat处理Http请求

http://localhost:8080/test/test.jsp为例:
1. 请求到达服务器端口8080,被在那里侦听的Coyote HTTP/1.1 Connector获得,并把它转交给Engine,等待回应。
2. Engine获得请求http://localhost:8080/test/test.jsp,匹配它所拥有的所有虚拟主机Host,匹配名称为localhost的主机(若没有使用默认主机),把请求转发给该主机,并等待回应
3. localhost Host获得请求/test/test.jsp,匹配它所拥有的所有Context,若匹配到路径为/test的Context,将请求交给它(如没有交给路径为”“的Context处理)
4. Context获得请求/test.jsp,在它的映射表中查找该资源,找到后构造HttpServletRequest对象和HttpServletResponse对象,作为参数调用Servlet的doGet或doPost方法
5. Context把执行完了之后的HttpServletResponse对象返回给Host
6. Host把HttpServletResponse对象返回给Engine
7. Engine把HttpServletResponse对象返回给Connector
8. Connector把HttpServletResponse对象返回给客户browser

参考文章

http://www.infoq.com/cn/articles/zh-tomcat-http-request-1
http://blog.csdn.net/skp127/article/details/52026150