zoukankan      html  css  js  c++  java
  • Tomcat

    什么是Tomcat

    Tomcat是一款开源轻量级Web应用服务器,是一款优秀的Servlet容器实现

    ServletServer Applet)是Java Servlet的简称,称为小服务程序或服务连接器,用Java编写的服务器端程序,具有独立于平台和协议的特性,主要功能在于交互式地浏览和生成数据,生成动态Web内容

    Servlet严格来讲是指Java语言实现的一个接口,一般情况下我们说的Servlet是指任何实现了这个Servlet接口的类。

    • 实例化并调用init()方法初始化该 Servlet,一般 Servlet 只初始化一次(只有一个对象)
    • service()(根据请求方法不同调用doGet() 或者 doPost(),此外还有doHead()doPut()doTrace()doDelete()doOptions()destroy())
    • Server 不再需要 Servlet 时(一般当 Server 关闭时),Server 调用 Servlet destroy() 方法。

    典型的Servlet的处理流程

    1.第一个到达服务器的 HTTP 请求被委派到 Servlet 容器。

    2.Servlet 容器在调用 service() 方法之前加载 Servlet

    3.然后 Servlet 容器处理由多个线程产生的多个请求,每个线程执行一个单一的 Servlet 实例的 service() 方法。

    Tomcat版本介绍

     

    Servlet2.X项目目录结构必须要有WEB-INFweb.xml等文件夹和文件,在web.xml中配置servlet,filter,listener,以web.xmljava web项目的统一入口

     servlet 3.x规范项目中可以不需要WEB-INFweb.xml等文件夹和文件在没有web.xml文件的情况下,通过注解实现servletfilter, listener的声明当使用注解时,容器自动进行扫描。

    同时Tomcat8.5进行了大量的代码重构,对比与7.0的版本,也符合Tomcat未来的代码架构体系。但是Tomcat的核心和主体架构还是一直保持这样的。

    8.5版本特点

    支持Servlet3.1

    默认采用NIO,移除BIO

    支持NIO2(AIO)

    支持HTTP/2协议

    默认采用异步日志处理

    为什么要讲8.5的版本,首先这个版本比较新,因为太老的版本比如6.0的版本Servlet不支持3所以会导致部署SpringBoot等项目有问题,同时这个版本是在9.0出现以后发布的一个中间版本,主体架构延续8.0,同时又实现了部分9.0的新特性。

    Tomcat启动

    Tomcat下载地址:

    https://tomcat.apache.org/download-80.cgi

    一般启动

    startup.bat/sh

    启动成功的日志信息如下:

     

    启动成功可以访问到的Tomcat首页

    http://localhost:8080/

     

    为什么有这个默认首页:Tomcat“买一送一”的思想。默认Tomcat启动后加载webapps中的项目

     

    IDE中启动

    一个Sprei项目配置和打包

     

    IDE中启动成功后的只有项目的访问,没有首页的显示的

     

     

     

    嵌入式启动

    SpringBoot中一个main方法嵌入式启动Tomcat

     

    Debug启动

    在项目发布后,我们有时候需要对基于生产环境部署的应用进行调试,以解决在开发环境无法重现的BUG。这时我们就需要用到应用服务器的远程调试功能,这个主要是基于JDK提供的JPDAJava Platform Debugger Architecture,Java平台调试体系结构)。不过一般情况下用不到,这里简单讲一讲。

    使用DeBug启动可以对基于生产环境部署的应用进行调试,以解决在开发环境无法重现的BUG

    使用IDEA远程部署tomcat和调试

    1.catalina.sh文件中加入以下的配置

    内容:

    CATALINA_OPTS="-Dcom.sun.management.jmxremote

    -Dcom.sun.management.jmxremote.port=1099

    -Dcom.sun.management.jmxremote.ssl=false

    -Dcom.sun.management.jmxremote.authenticate=false

    -Djava.rmi.server.hostname=192.168.19.200

    -agentlib:jdwp=transport=dt_socket,address=15833,suspend=n,server=y"export CATALINA_OPTS

    • 以上端口可以随意改动,但是必要的是后续的设置必须保持一致,并且务必保证端口没有被占用,这些设置的端口在防火墙中是开放状态;
    • 其中1099的是tomcat远程部署连接端口;
    • 15833 是远程调试的端口;
    • 192.168.19.200是远程的服务器的Ip

    2.Linux启动tomcat,使用命令启动

    ./bin/catalina.sh run &

     

     

     

     

    debug启动测试

    这样就能够成功远程部署并且调试了。

    使用的技巧:

     

    容易出现的问题

    • 如果远程没有连接上,两个端口被占用或者防火墙屏蔽。除了JMX server指定的监听端口号外,JMXserver还会监听一到两个随机端口号,这个如果防火墙关闭了的话就不用考虑,如果使用了防火墙,还需要查看它监听的端口。
    • 账号的相应的读写权限一定要有;

    Tomcat项目部署及目录结构

    项目部署

    隐式部署

    直接丢文件夹、warjarwebapps目录tomcat会根据文件夹名称自动生成虚拟路径,简单,但是需要重启Tomcat服务器,包括要修改端口和访问路径的也需要重启。

    显式部署

    添加context元素

    server.xml中的Host加入一个Context(指定路径和文件地址),例如:

    <Host name="localhost">

    <Context path="/comet" docBase="D:work_tomcat ef-comet.war" />

    /comet 这个虚拟路径映射到了D:work_tomcat ef-comet目录下(war会解压成文件),修改完servler.xml需要重启tomcat 服务器。

    创建xml文件

    conf/Catalina/localhost中创建xml文件,访问路径为文件名,例如:

    localhost目录下新建demo.xml,内容为:

    <Context docBase="D:work_tomcat ef-comet" />

    不需要写path,虚拟目录就是文件名demopath默认为/demo,添加demo.xml不需要重启 tomcat服务器。

    三种方式比较:

    隐式部署:可以很快部署,需要人手动移动Web应用到webapps下,在实际操作中不是很人性化

    添加context元素 : 配置速度快,需要配置两个路径,如果path为空字符串,则为缺省配置,每次修改server.xml文件后都要重新启动Tomcat服务器,重新部署.

    创建xml文件:服务器后台会自动部署,修改一次后台部署一次,不用重复启动Tomcat服务器,该方式显得更为智能化。

    目录结构:

    Bin执行脚本目录

    startup文件主要是检查catalina.bat/sh 执行所需环境,并调用catalina.bat 批处理文件。启动tomcat

    catalina文件真正启动Tomcat文件,可以在里面设置jvm参数。

    shutdown文件关闭Tomcat

    脚本version.shstartup.shshutdown.shconfigtest.sh都是对catalina.sh的包装,内容大同小异,差异在于功能介绍和调用catalina.sh时的参数不同。

    Version:查看当前tomcat的版本号

    Configtest:校验tomcat配置文件server.xml的格式、内容等是否合法、正确。

    Service:安装tomcat服务,可用net start tomcat 启动

    web.xml

    Tomcat中所有应用默认的部署描述文件,主要定义了基础的ServletMIME映射(mime-mapping 文件类型,其实就是Tomcat处理的文件类型),如果部署的应用中不包含Web.xml,那么Tomcat将使用此文件初始化部署描述,反之,Tomcat会在启动时将默认描述与定义描述配置进行合并。

    加载一些tomcat内置的servlet

    DefaultServlet默认的,加载静态文件 html,js,jpg等静态文件。

    JspServlet专门处理jsp

    context.xml

    用于自定义所有Web应用均需要加载的Context配置,如果Web应用指定了自己的context.xml,那么该文件的配置将被覆盖。

    context.xmlserver.xml中配置context的区别

    server.xml是不可动态重加载的资源,服务器一旦启动了以后,要修改这个文件,就得重启服务器才能重新加载。而context.xml文件则不然,tomcat服务器会定时去扫描这个文件。一旦发现文件被修改(时间戳改变了),就会自动重新加载这个文件,而不需要重启服务器。

    catalina.policy

    权限相关 Permission Tomcat是跑在jvm上的,所以有些默认的权限

    tomcat-users.xml

    配置Tomcatservermanager信息

    <?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="manager-gui"/>

    <user username="manager" password="manager" roles="manager-gui"/>

    </tomcat-users>

    logging.properties

    设置tomcat日志

    控制输出不输出内容到文件,不能阻止生成文件,阻止声文件可用注释掉

    webapps目录

    存放web项目的目录,其中每个文件夹都是一个项目;如果这个目录下已经存在了目录,那么都是tomcat自带的。项目。其中ROOT是一个特殊的项目,在地址栏中没有给出项目目录时,对应的就是ROOT项目。http://localhost:8080/examples,进入示例项目。其中examples就是项目名,即文件夹的名字。

    lib目录

    Tomcat的类库,里面是一大堆jar文件。如果需要添加Tomcat依赖的jar文件,可以把它放到这个目录中,当然也可以把应用依赖的jar文件放到这个目录中,这个目录中的jar所有项目都可以共享之,但这样你的应用放到其他Tomcat下时就不能再共享这个目录下的Jar包了,所以建议只把Tomcat需要的Jar包放到这个目录下;

    work目录

    运行时生成的文件,最终运行的文件都在这里。通过webapps中的项目生成的!可以把这个目录下的内容删除,再次运行时会生再次生成work目录。当客户端用户访问一个JSP文件时,Tomcat会通过JSP生成Java文件,然后再编译Java文件生成class文件,生成的javaclass文件都会存放到这个目录下。

    temp目录

    存放Tomcat的临时文件,这个目录下的东西可以在停止Tomcat后删除!

    logs目录

    这个目录中都是日志文件,记录了Tomcat启动和关闭的信息,如果启动Tomcat时有错误,那么异常也会记录在日志文件中

    localhost-xxx.log Web应用的内部程序日志,建议保留

    catalina-xxx.log 控制台日志

    host-manager.xxx.log Tomcat管理页面中的host-manager的操作日志,建议关闭

    localhost_access_log_xxx.log 用户请求Tomcat的访问日志(这个文件在conf/server.xml里配置),建议关闭

    Conf 配置文件目录

    server.xml

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

     

    <!-- Server代表一个 Tomcat 实例。可以包含一个或多个 Services,其中每个Service都有自己的Engines和Connectors。

           port="8005"指定一个端口,这个端口负责监听关闭tomcat的请求

      -->

    <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" />

    <!-- 全局命名资源,定义了UserDatabase的一个JNDI(java命名和目录接口),通过pathname的文件得到一个用户授权的内存数据库 -->

    <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它包含一个<Engine>元素,以及一个或多个<Connector>,这些Connector元素共享用同一个Engine元素 -->

    <Service name="Catalina">

    <!--

             每个Service可以有一个或多个连接器<Connector>元素,

             第一个Connector元素定义了一个HTTP Connector,它通过8080端口接收HTTP请求;第二个Connector元素定

             义了一个JD Connector,它通过8009端口接收由其它服务器转发过来的请求.

         -->

    <Connector port="8080" protocol="HTTP/1.1"

                    connectionTimeout="20000"

                    redirectPort="8443" />

    <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />

    <!-- 每个Service只能有一个<Engine>元素 -->

    <Engine name="Catalina" defaultHost="localhost">

    <Realm className="org.apache.catalina.realm.LockOutRealm">

    <Realm className="org.apache.catalina.realm.UserDatabaseRealm"

                    resourceName="UserDatabase"/>

    </Realm>

    <!-- 默认host配置,有几个域名就配置几个Host,但是这种只能是同一个端口号 -->

    <Host name="localhost"  appBase="webapps"

                 unpackWARs="true" autoDeploy="true">

           <!-- Tomcat的访问日志,默认可以关闭掉它,它会在logs文件里生成localhost_access_log的访问日志 -->

    <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"

                    prefix="localhost_access_log" suffix=".txt"

                    pattern="%h %l %u %t "%r" %s %b" />

    </Host>

    <Host name="www.hzg.com"  appBase="webapps"

                 unpackWARs="true" autoDeploy="true">

    <Context path="" docBase="/myweb1" />

    <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"

                    prefix="hzg_access_log" suffix=".txt"

                    pattern="%h %l %u %t "%r" %s %b" />

    </Host>

    </Engine>

    </Service>

    </Server>

     

    server.xml中日志的patter解释

    有效的日志格式模式可以参见下面内容,如下字符串,其对应的信息由指定的响应内容取代:
    a - 远程IP地址
    A - 本地IP地址
    b - 发送的字节数,不包括HTTP头,或“ - ”如果没有发送字节
    B - 发送的字节数,不包括HTTP
    h - 远程主机名
    H - 请求协议
    l (小写的L)- 远程逻辑从identd的用户名(总是返回' - '
    m - 请求方法
    p - 本地端口
    q - 查询字符串(在前面加上一个如果它存在,否则是一个空字符串
    r - 第一行的要求
    s - 响应的HTTP状态代码
    S - 用户会话ID
    t - 日期和时间,在通用日志格式
    u - 远程用户身份验证
    U - 请求的URL路径
    v - 本地服务器名
    D - 处理请求的时间(以毫秒为单位)
    T - 处理请求的时间(以秒为单位)
    I (大写的i- 当前请求的线程名称

    Tomcat组件及架构

     

    Server

    Server是最顶级的组件,它代表Tomcat的运行实例,它掌管着整个Tomcat的生死大权;

    • 提供了监听器机制,用于在Tomcat整个生命周期中对不同时间进行处理
    • 提供Tomcat容器全局的命名资源实现,JNDI
    • 监听某个端口以接受SHUTDOWN命令,用于关闭Tomcat

    Service

    一个概念,一个Service维护多个Connector和一个Container

    Connector组件

    链接器:监听转换Socket请求,将请求交给Container处理,支持不同协议以及不同的I/O方式

    Container

    表示能够执行客户端请求并返回响应的一类对象,其中有不同级别的容器:EngineHostContextWrapper

    Engine

    整个Servler引擎,最高级的容器对象

    Host

    表示Servlet引擎中的虚拟机,主要与域名有关,一个服务器有多个域名是可以使用多个Host

    Context

    用于表示ServletContext,一个ServletContext表示一个独立的Web应用

    Wrapper

    用于表示Web应用中定义的Servlet

    Executor

    Tomcat组件间可以共享的线程池

    Tomcat的核心组件

    解耦:网络协议与容器的解耦。

    Connector链接器封装了底层的网络请求(Socket请求及相应处理),提供了统一的接口,使Container容器与具体的请求协议以及I/O方式解耦。

    ConnectorSocket输入转换成Request对象,交给Container容器进行处理,处理请求后,Container通过Connector提供的Response对象将结果写入输出流。

    因为无论是Request对象还是Response对象都没有实现Servlet规范对应的接口,Container会将它们进一步分装成ServletRequestServletResponse.

    Tomcat中的Connector

    三种传输协议

    1、HTTP:HTTP/1.1协议

    2、AJP协议:主要与Apache HTTP Server集成

    3、HTTP2:HTTP/2.0协议,下一代HTTP协议

    三种I/O方式

    NIO:采用JDK的NIO类库实现

    NIO2(AIO):采用JDK1.7的NIO2类库实现

    APR:采用APR(Apache可移植运行库)

    如何选择协议及I/0方式

    Tomcat的链接器

    AJP主要是用于Web服务器与Tomcat服务器集成,AJP采用二进制传输可读性文本,使用保持持久性的TCP链接,使得AJP占用更少的带宽,并且链接开销要小得多,但是由于AJP采用持久化链接,因此有效的连接数较HTTP要更多。

    HTTP2.0目前市场不成熟。

    对于I/0选择,要根据业务场景来定,一般高并发场景下,APRNIO2的性能要优于NIOBIO,(linux操作系统支持的NIO2由于是一个假的,并没有真正实现AIO,所以一般linux上推荐使用NIO,如果是APR的话,需要安装APR库,而Windows上默认安装了),所以在8.5的版本中默认是NIO

  • 相关阅读:
    控制台——args参数的赋值方法
    整数排序的几种方法
    基于CentOS系统下的Oracle的安装
    QT的学习
    HDU 2104 hide handkerchief
    HDU 2103 Family Plan
    HDU 2115 I Love This Game
    HDU 2100 Lovekey
    猜数字游戏
    利用Hough变换识别图像中的直线
  • 原文地址:https://www.cnblogs.com/Soy-technology/p/11220871.html
Copyright © 2011-2022 走看看