Java Web(七)__Tomcat(二)

Tomcat工作模式

Tomcat作为Servlet容器,有以下三种工作模式。

1)独立的Servlet容器,由Java虚拟机进程来运行

Tomcat作为独立的Web服务器来单独运行,Servlet容器组件作为Web服务器中的一部分而存在。这是Tomcat的默认工作模式。

在这种模式下,Tomcat是一个独立运行的Java程序。和运行其他Java程序一样,运行Tomcat需要启动一个Java虚拟机(JVM,Java Virtual Machine)进程,由该进程来运行Tomcat,如下图:

2)其他Web服务器进程内的Servlet容器

Tomcat分为Web服务器插件和Servlet容器组件两部分。

Web服务器插件在其他Web服务器进程的内部地址空间启动一个JVM(Java Virtual Machine),使Servlet容器组件在此虚拟机中运行。若客户机调用Servlet的请求,web服务器插件将取得对此请求的控制并将它传递(使用JNI)给Servlet容器组件。

注:JNI是Java Native Interface的简写,它是Java本地调用接口。通过这个接口,Java程序可以和其他语言编写的本地程序进行通信。

进程内的Servlet容器对于单进程、多线程的Web服务器非常合适,可以提供较高的运行速度,但缺乏伸缩性。

3)其他Web服务器进程外的Servlet容器

Tomcat分为Web服务器插件和Servlet容器组件两部分。

Web服务器插件在其他Web服务器的外部地址空间启动一个Java虚拟机进程,Servlet容器组件在此Java虚拟机中运行。如有客户端发出调用Servlet的请求,Web服务器插件获得对此请求的控制并将它转发(采用IPC通信机制)给Servlet容器。

注:IPC(Inter-Process Communication,进程间通信)是两个进程之间进行通信的一种机制。

进程外Servlet容器对客户请求的响应速度不如进程内Servlet容器,但进程外容器具有更好的伸缩性和稳定性。

从Tomcat的三种工作模式可以看出,当Tomcat作为独立的Servlet容器来运行时,此时Tomcat是能运行Java Servlet的独立Web服务器。

此外,Tomcat还可作为其他Web服务器进程内或者进程外的Servlet容器,从而与其他Web服务器集成(如Apache和IIS服务器等)。

集成的意义在于:对于不支持运行Java Servlet的其他Web服务器,可通过集成Tomcat来提供运行Servlet的功能。 


 Tomcat整体架构


Connector(连接器)

1)EndPoint

  • EndPoint : Coyote 通信端点,即通信监听的接口,是具体Socket接收和发送处理器,是对传输层的抽象,因此EndPoint用来实现TCP/IP协议的。

  • Tomcat 并没有EndPoint 接口,而是提供了一个抽象类AbstractEndpoint , 里面定义了两个内部类:Acceptor和SocketProcessor。

    • Acceptor用于监听Socket连接请求。

    • SocketProcessor用于处理接收到的Socket请求,它实现Runnable接口,在Run方法里调用协议处理组件Processor进行处理。为了提高处理能力,SocketProcessor被提交到线程池来执行。而这个线程池叫作执行器(Executor).

2) Processor

Processor : Coyote 协议处理接口 ,如果说EndPoint是用来实现TCP/IP协议的,那么Processor用来实现HTTP协议,Processor接收来自EndPoint的Socket,读取字节流解析成Tomcat Request和Response对象,并通过Adapter将其提交到容器处理,Processor是对应用层协议的抽象。

3)ProtocolHandler

ProtocolHandler: Coyote 协议接口, 通过Endpoint 和 Processor , 实现针对具体协议的处理能力。

  • Tomcat 按照协议和I/O 提供了6个实现类 : AjpNioProtocol , AjpAprProtocol, AjpNio2Protocol , Http11NioProtocol ,Http11Nio2Protocol ,Http11AprProtocol。
  • 我们在配置tomcat/conf/server.xml 时 , 至少要指定具体的ProtocolHandler ; 当然也可以指定协议名称 , 如 : HTTP/1.1 ,如果安装APR,那么将使用Http11AprProtocol , 否则使用 Http11NioProtocol 。

4)Adapter

由于协议不同,客户端发过来的请求信息也不尽相同,Tomcat定义了自己的Request类来“存放”这些请求信息。

  • ProtocolHandler接口负责解析请求并生成Tomcat Request类。但是这个Request对象不是标准的ServletRequest,也就意味着,不能用Tomcat Request作为参数来调用容器。
  • Tomcat设计者的解决方案是引入CoyoteAdapter,这是适配器模式的经典运用,连接器调用CoyoteAdapter的Sevice方法,传入的是Tomcat Request对象,CoyoteAdapter负责将Tomcat Request转成ServletRequest,再调用容器的Service方法。

Container(容器)

架构

4个子容器的作用分别是:

【1】Engine:表示整个Catalina的Servlet引擎,用来管理多个虚拟站点,一个Service最多只能有一个Engine,但是一个引擎可包含多个Host。

【2】Host:代表一个站点,也可以叫虚拟主机,可以给Tomcat配置多个虚拟主机地址,而一个虚拟主机下可包含多个Context;【整个webapps】

【3】Context:代表一个应用程序,对应着平时开发的一套程序,或者一个 WEB-INF目录以及下面的 web.xml文件;

【4】Wrapper:每一 Wrapper封装着一个 Servlet,Wrapper 作为容器中的最底层,不能包含子容器。


处理请求

使用 Pipeline-Valve 管道来处理的!(Valve是阀门之意)Pipeline-Valve 是责任链模式,责任链模式是指在一个请求处理的过程中有很多处理者依次对请求进行处理,每个处理者负责做自己相应的处理,处理完之后将处理后的请求返回,再让下一个处理着继续处理。

【1】Connector 在接收到请求后会首先调用最顶层容器的Pipeline来处理,这里的最顶层容器的 Pipeline就是EnginePipeline(Engine的管道);

【2】在 Engine的管道中依次会执行 EngineValve1、EngineValve2 等等,最后会执行 StandardEngineValve,在StandardEngineValve 中会调用 Host管道,然后再依次执行 Host 的 HostValve1、HostValve2 等,最后在执行StandardHostValve,然后再依次调用 Context的管道和 Wrapper的管道,最后执行到 StandardWrapperValve。

【3】当执行到 StandardWrapperValve 的时候,会在 StandardWrapperValve中创建 FilterChain,并调用其 doFilter方法来处理请求,这个 FilterChain包含着我们配置的与请求相匹配的 Filter和Servlet,其 doFilter方法会依次调用所有的 Filter的 doFilter方法和 Servlet的 service方法,这样请求就得到了处理!

【4】当所有的 Pipeline-Valve都执行完之后,并且处理完了具体的请求,这个时候就可以将返回的结果交给 Connector了,Connector 在通过 Socket的方式将结果返回给客户端。


service.xml文件

server.xml 是 Tomcat 中最重要的配置文件,server.xml 的每个元素都对应了 Tomcat中的一个组件;通过对xml文件中元素的配置,可以实现对 Tomcat 中各个组件的控制。

<?xml version="1.0" encoding="UTF-8"?>
<Server port="8005" shutdown="SHUTDOWN">
  <Listener className="org.apache.catalina.startup.VersionLoggerListener"/>
  <Listener SSLEngine="on" className="org.apache.catalina.core.AprLifecycleListener"/>
  <Listener className="org.apache.catalina.core.JasperListener"/>
  <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener"/>
  <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener"/>
  <Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener"/>

  <GlobalNamingResources>
    <Resource auth="Container" description="User database that can be updated and saved" factory="org.apache.catalina.users.MemoryUserDatabaseFactory" name="UserDatabase" pathname="conf/tomcat-users.xml" type="org.apache.catalina.UserDatabase"/>
  </GlobalNamingResources>

  <Service name="Catalina">
    <Connector port="8080" protocol="HTTP/1.1" connectionTimeOut="20000" redirectPort="8443"/>
    <Connector port="8009" protocol="AJP/1.3" redirectPort="8443"/>
    <Engine defaultHost="localhost" name="Catalina">
      <Realm className="org.apache.catalina.realm.LockOutRealm">
        <Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase"/>
      </Realm>

      <Host appBase="webapps" autoDeploy="true" name="localhost" unpackWARs="true">
         <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" pattern="%h %l %u %t &quot;%r&quot; %s %b" prefix="localhost_access_log." suffix=".txt"/>

        <Context docBase="cas-server-webapp" path="/cas" reloadable="true" source="org.eclipse.jst.j2ee.server:cas-server-webapp"/>
        <Context docBase="portal" path="/portal" reloadable="true" source="org.eclipse.jst.jee.server:portal"/>
      </Host>
    </Engine>
  </Service>
</Server>

整体架构简洁版

<Server>
    <Service>
        <Connector />
        <Connector />
        <Engine>
            <Host>
                <Value />
                <Context /><!-- 现在常常使用自动部署,不推荐配置Context元素-->
            </Host>
        </Engine>
    </Service>
</Server>

核心组件

【1】Server

Server元素在最顶层,代表整个 Tomcat容器,因此他必须是 server.xml中唯一一个最外层的元素。一个 Server元素可以有一个或多个 Service元素。

Server 的主要任务,就是提供一个接口让客户端能够访问到这个 Service集合,同时维护它所包含的所有的 Service的生命周期,包含如何初始化,如何结束服务,如何找到客户端要访问的 Service。

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

说明:

  • shutdown :发往此Server用于实现关闭tomcat实例的命令字符串,默认为SHUTDOWN;
  • port 属性表示 Server接收 shutdown指令的端口号,设置为-1可以禁掉该端口。默认仅允许通过本机访问,默认为8005;
  • address:服务器等待关机命令的TCP / IP地址。如果没有指定地址,则使用localhost。
  • className: 用于实现此Server容器的完全限定类的名称,默认为org.apache.catalina.core.StandardServer;
【2】Service

在 Connector 和 Engine外面包一层,把它们组合在一起,对外提供服务。一个Service可以包含多个Connector,但是只能包含一个Engine;其中 Connector 的作用是从客户端接收请求,Engine 的作用是处理接收进来的请求。

<Server port="8005" shutdown="SHUTDOWN">
    <Service name="Catalina">
    </Service>
</Server>

属性说明:

  • className: 用于实现service的类名,一般都是org.apache.catalina.core.StandardService。
  • name:此服务的名称,默认为Catalina;

如上图,Server 中包含一个名称为 “Catalina” 的Service,此名字也会在产生相关的日志信息时记录在日志文件当中。

实际上,Tomcat 可以提供多个 Service,不同的 Service监听不同的端口。

【3】Connector

接收连接请求,创建 Request 和 Response对象用于和请求端交换数据;然后分配线程让 Engine来处理这个请求,并把产生的 Request 和 Response对象传给 Engine。通过配置 Connector,可以控制请求 Service的协议及端口号。【连接器类型通常包括:1) HTTP连接器;2) SSL连接器;3)AJP 1.3连接器;4) proxy连接器

<Server port="8005" shutdown="SHUTDOWN">
    <Service name="Catalina">
        <Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" maxParameterCount="1000"/>
        <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
    </Service>
</Server>

常用属性的说明:

  • 1) address:指定连接器监听的地址,默认为所有地址,即0.0.0.0;
  • 2) maxThreads:支持的最大并发连接数,默认为200;
  • 3) port:监听的端口,默认为8080;
  • 4) protocol:连接器使用的协议,默认为HTTP/1.1,定义AJP协议时通常为AJP/1.3;
  • 5) redirectPort:如果某连接器支持的协议是HTTP,当接收客户端发来的HTTPS请求时,则转发至此属性定义的端口;
  • 6) connectionTimeout:等待客户端发送请求的超时时间,单位为毫秒,默认为60000,即1分钟;
  • 7) enableLookups:是否通过request.getRemoteHost()进行DNS查询以获取客户端的主机名;默认为true;
  • 8) acceptCount:设置等待队列的最大长度;通常在tomcat所有处理线程均处于繁忙状态时,新发来的请求将被放置于等待队列中;

配置说明:

  • 通过配置第一个 Connector,客户端可以通过 8080端口号协议访问 Tomcat。其中,protocol 属性规定了请求的协议,port 规定了请求的端口号,redirectPort 表示当强制要求 https而请求是 http时,重定向至端口号为 8443的Connector,connectionTimeout表示连接的超时时间。
    • 在这个例子中,Tomcat 监听 Http请求,使用的是 8080端口,而不是正式的 80端口;实际上,在正式的生产环境中,Tomcat也常常监听8080端口。而不是80端口。这是因为在生产环境中,很少讲 Tomcat直接对外开放接收请求,而是在 Tomcat和客户端之间加一层代理服务器(如Nginx),用于请求的转发、负载均衡、处理静态文件等;通过代理服务器访问 Tomcat时,是在局域网中,因为一般仍使用8080端口。
  • 第二个配置 Connector,客户端可以通过 8009端口使用 AJP协议访问 Tomcat。AJP协议负责和其他的Http服务器(如Apache)建立连接;在把 Tomcat与其他服务器集成时,就需要用到这个连接器,之所以使用 Tomcat和其他服务器集成,是因为 Tomcat可以用作 Servlet/JSP容器,但是对静态资源处理速度较慢,不如 Apache和 IIS等 HTTP服务器;因此常常将 Tomcat和 Apache等集成,前者做 Servlet容器,后者处理静态资源,而 AJP协议便负责 Tomcat与 Apache的连接。Tomcat 和 Apache等集成的原理如下图:

【4】Engine

Engine 组件在 Service 组件有且只有一个;

  • Engine是Servlet处理器的一个实例,即servlet引擎,默认为定义在server.xml中的Catalina。
  • Engine组件从一个或多个Connector 中接收并处理,并将完成的响应返回给 Connector,最终传递给客户端。
  • Engine、Host 和 Context都是容器,但是它们不是平行关系,而是父子关系:Engine 包含 Host,Host 包含 Context。
<Server port="8005" shutdown="SHUTDOWN">
    <Service name="Catalina">
        <Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />
        <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
        <Engine name="Catalina" defaultHost="localhost">
        </Engine>
    </Service>
</Server>

 参数说明:

  •  name:Engine组件的名称,用于日志和错误信息记录时区别不同的引擎;
  • defalutHost :指定了默认的 host名称【接收所有发往非明确定义虚拟主机的请求的host组件,即当发往本机的请求指定的 host名称不存在时,一律使用 defaultHost指定的 host进行处理;】
  • 因此 defaulthost的值,必须与 Engine中的一个Host组件的 name属性值匹配。

Engine 和 Host的关系:

  • Host 是 Engine的子容器。
  • Engine 组件中可以内嵌1个或者多个 Host组件;
  • 每个 Host组件代表 Engine中的一个虚拟主机。
  • Host组件至少有一个,且其中一个的 name必须与 Engine组件中的 defaultHost属性相匹配。
<Server port="8005" shutdown="SHUTDOWN">
    <Service name="Catalina">
        <Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />
        <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
        <Engine name="Catalina" defaultHost="localhost">
            <Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true">
                
            </Host>
        </Engine>
    </Service>
</Server>
【5】Host

位于Engine容器中用于接收请求并进行相应处理的主机或虚拟主机。作用是运行多个 Web应用(一个 Context 代表一个 Web应用),并负责安装、展开、启动、结束每个 Web应用。

  • Host 组件代表的虚拟主机,对应服务器中一个网络名实体(如"www.test.com"或IP地址"116.25.25.25");为了使用户可以通过网络名连接Tomcat服务器,这个名字应该在DNS服务器上注册。
  • 客户端通常使用主机名来标识它们希望连接的服务器,该主机名也会包含在 HTTP请求头中,Tomcat 从 HTTP头中提取出主机名,寻找名字匹配的主机。
  • 如果没有匹配,请求会发送至默认的主机。因此默认主机不需要在 DNS服务器中注册网络名,因为任何与所有 Host名称不匹配的请求,都会路由至默认主机。

参数说明:

  • 1) appBase:此Host的webapps目录,即存放非归档的web应用程序的目录或归档后的WAR文件的目录路径;可以使用基于$CATALINA_HOME的相对路径;
  • 2) autoDeploy:在Tomcat处于运行状态时放置于appBase目录中的应用程序文件是否自动进行deploy;默认为true;
  • 3) unpackWars:在启用此webapps时是否对WAR格式的归档文件先进行展开;默认为 true,通过解压后的文件结构运行该 Web应用;如果是false,直接使用 WAR文件运行 Web应用。
  • 4)name 属性指定虚拟主机的主机名,一个 Engine有且只有一个 Host组件的 name属性和 Engine组件的 defaultHost属性相匹配;一般情况下,主机名需要是在 DNS服务器中注册网络名,但是 Engine指定的 defaultHost不需要。
<Context docBase="D:\Program Files\app1.war" reloadable="true"></Context>
【6】Context(静态部署)

Context元素代表在虚拟主机上运行的一个Web应用。

  • 每个 Web应用基于 WAR文件,或 WAR文件解压后对应的目录(这里称为应用目录)。
  • Context 是 Host 的子容器,每个 Host 都可以定义任意多的 Context元素。

属性说明:

  • docBase :指定Web应用程序的存放位置;也可以使用相对路径,起始路径为此Context所属Host中appBase定义的路径;切记,docBase的路径名不能与相应的Host中appBase中定义的路径名有包含关系,比如,如果appBase为deploy,而docBase绝不能为deploy-bbs类的名字;
  • path 指定了访问该Web应用上下文路径,当请求到来时,Tomcat 根据 Web应用的 path属性与 URL匹配程度来选择 Web应用处理相应请求。
  • reloadable属性指示tomcat是否在运行时监控在 WEB-INF/classes和WEB-INF/lib目录下class文件的改动。默认值为false;当值为 true,在 class文件改动时会重新 web应用的重新加载。在开发环境下,reloadable 设置为 ture便于调试;
  • 若是自动部署(即 autoDeploy=“true”),那么 server.xml配置文件中没有 Context元素的配置。这是因为 Tomcat开启了自动部署,Web应用没有在 server.xml中配置静态部署,而是由 Tomcat通过特定的规则自动部署。

注:目前往往server.xml配置文件中看不到Context元素的出现,因为Tomcat开启了自动部署,Web应用没有在server.xml中配置静态部署,而是由Tomcat通过特定的规则自动部署。

静态部署与自动部署是可以共存的。在实际应用中,并不推荐使用静态部署,因为server.xml 是不可动态重加载的资源,服务器一旦启动了以后,要修改这个文件,就得重启服务器才能重新加载。而自动部署可以在Tomcat运行时通过定期的扫描来实现,不需要重启服务器。

注意的是:在自动部署场景下(配置文件位于 xmlBase中)

  • docBase 不在 appBase目录中,才需要指定;如果 docBase指定的 war包或应用目录就在 appBase中,则不需要指定。因为 Tomcat会自动扫描 appBase中的 war包和应用目录,制定了反而造成问题。
  • 不能指定path属性,path属性由配置的文件的文件名,WAR文件的文件名或应用目录的名称自动推导出来。

appBase 和 docBase的区别

【1】appBase:这个目录下面的子目录将自动被部署为应用,且 war文件将被自动解压缩并部署为应用,默认为 Tomcat根目录下的 webapps文件夹。

【2】docBase:指定需要关联的项目自动解压并部署到 appBase目录下。项目的名称由 path属性决定。

  • docBase 所在的文件或者 war包必须存在,否则项目启动找不到对应的目录。此时文件解压到 appBase目录下,根据 path属性,决定解压后的文件名。
  • 若采用了 配置,那么 appBase目录下的应用目录将会再次部署。此时项目是部署两遍。解决办法,设置 autoDeploy=“false”。
【7】Valve组件

Valve类似于过滤器,它可以工作于Engine和Host/Context之间、Host和Context之间以及Context和Web应用程序的某资源之间。

不同的Valve有不同的特性,AccessLogValve记录的日志就是访问日志,每天的请求会写到一个日志文件里。AccessLogValve可以与Engine、Host或Context关联;

注:一个容器内可以建立多个Valve,而且Valve定义的次序也决定了它们生效的次序。

相关属性定义有:

  • className:规定了Valve的类型,是最重要的属性;本例中,通过该属性规定了这是一个AccessLogValve。

  • directory:指定日志存储的位置,本例中,日志存储在$TOMCAT_HOME/logs目录下。

  • prefix:指定了日志文件的前缀。

  • suffix:指定了日志文件的后缀。通过directory、prefix和suffix的配置,在$TOMCAT_HOME/logs目录下,可以看到如下所示的日志文件。

  • pattern:指定记录日志的格式。

pattern中一些值:

  • %h:远程主机名或IP地址;如果有nginx等反向代理服务器进行请求分发,该主机名/IP地址代表的是nginx,否则代表的是客户端。后面远程的含义与之类似,不再解释。
  • %l:远程逻辑用户名,一律是”-”,可以忽略。
  • %u:授权的远程用户名,如果没有,则是”-”。
  • %t:访问的时间。
  • %r:请求的第一行,即请求方法(get/post等)、uri、及协议。
  • %s:响应状态,200,404等等。
  • %b:响应的数据量,不包括请求头,如果为0,则是””-。
  • %D:请求处理的时间(单位是毫秒)
【8】Listener

Listener(即监听器)定义的组件,可以在特定事件发生时执行特定的操作;

  • 被监听的事件通常是Tomcat的启动和停止。
  • 监听器需要配置的最重要的属性是className,该属性规定了监听器的具体实现类,该类必须实现了org.apache.catalina.LifecycleListener接口。
    <Listener className="org.apache.catalina.startup.VersionLoggerListener" />
    <!-- Security listener. Documentation at /docs/config/listeners.html
    <Listener className="org.apache.catalina.security.SecurityListener" />
    -->
    <!-- APR library loader. Documentation at /docs/apr.html -->
    <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
    <!-- Prevent memory leaks due to use of particular java/javax APIs-->
    <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
    <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
    <Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />

例如:

  • VersionLoggerListener:当Tomcat启动时,该监听器记录Tomcat、Java和操作系统的信息。该监听器必须是配置的第一个监听器。

  • AprLifecycleListener:Tomcat启动时,检查APR库,如果存在则加载。APR,即Apache Portable Runtime,是Apache可移植运行库,可以实现高可扩展性、高性能,以及与本地服务器技术更好的集成。

  • JasperListener:在Web应用启动之前初始化Jasper,Jasper是JSP引擎,把JVM不认识的JSP文件解析成java文件,然后编译成class文件供JVM使用。

  • JreMemoryLeakPreventionListener:与类加载器导致的内存泄露有关。

  • GlobalResourcesLifecycleListener:通过该监听器,初始化< GlobalNamingResources>标签中定义的全局JNDI资源;如果没有该监听器,任何全局资源都不能使用。

  • ThreadLocalLeakPreventionListener:当Web应用因thread-local导致的内存泄露而要停止时,该监听器会触发线程池中线程的更新。当线程执行完任务被收回线程池时,活跃线程会一个一个的更新。只有当Web应用(即Context元素)的renewThreadsWhenStoppingContext属性设置为true时,该监听器才有效。

其他 

Tomcat 还有其它重要的组件,如安全组件 Security、Logger、Session、Mbeans、Naming 等其它组件。这些组件共同为 Connector 和 Container 提供必要的服务。


Tomcat调优

1.Tomcat 的自身调优:

  • 采用动静分离节约 Tomcat 的性能;【采用:Nginx+Tomcat 实现动静分离】
  • 禁用 AJP 连接器【使用 Nginx+Tomcat的架构,所以用不着 AJP 协议,所以把AJP连接器禁用。】
  • 调整 Tomcat 的线程池
  • 调整 Tomcat 的连接器
  • 修改 Tomcat 的运行模式
  • 关闭 Manager管理页面;(默认已经关闭)
  • 关闭 host-mangent管理页面;(默认已经关闭)
  • 对 Tomcat 日志进行分割;
  • 定义 Tomcat 404 错误返回的页面;

2.JVM的调优:

  • 调优Jvm内存

参考文档:tomcat优化(五)tomcat调优-腾讯云开发者社区-腾讯云

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/402488.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

一文弄明白KeyedProcessFunction函数

引言 KeyedProcessFunction是Flink用于处理KeyedStream的数据集合&#xff0c;它比ProcessFunction拥有更多特性&#xff0c;例如状态处理和定时器功能等。接下来就一起来了解下这个函数吧 正文 了解一个函数怎么用最权威的地方就是 官方文档 以及注解&#xff0c;KeyedProc…

Observability:使用 OpenTelemetry 和 Elastic 监控 OpenAI API 和 GPT 模型

作者&#xff1a; 来自 Elastic David Hope ChatGPT 现在非常火爆&#xff0c;甚至席卷了整个互联网。 作为 ChatGPT 的狂热用户和 ChatGPT 应用程序的开发人员&#xff0c;我对这项技术的可能性感到非常兴奋。 我看到的情况是&#xff0c;基于 ChatGPT 的解决方案将会呈指数级…

C++实现归并排序题目

目录 例1 例2 例3 例4 例1 912. 排序数组 参考代码 class Solution { public:vector<int> tmpnums;vector<int> sortArray(vector<int>& nums) {tmpnums.resize(nums.size());mergeSort(nums, 0, nums.size() - 1);return nums;}void mergeSort(vector…

如何使用rocketmq实现分布式事务?

什么是rocketmq事务消息 事务消息是 Apache RocketMQ 提供的一种高级消息类型&#xff0c;支持在分布式场景下保障消息生产和本地事务的最终一致性。 RocketMQ的分布式事务又称为“半消息事务”。 事务消息处理流程 RocketMQ是靠半消息机制实现分布式事务 事务消息&#x…

OpenAI 的 GPTs 提示词泄露攻击与防护实战:防御卷(一)

前面的OpenAI DevDay活动上&#xff0c;GPTs技术的亮相引起了广泛关注。随着GPTs的创建权限开放给Plus用户&#xff0c;社区里迅速涌现了各种有趣的GPT应用&#xff0c;这些都是利用了Prompt提示词的灵活性。这不仅展示了技术的创新潜力&#xff0c;也让人们开始思考如何获取他…

C++学习Day09之系统标准异常

目录 一、程序及输出1.1 系统标准异常示例1.2 标准异常表格 二、分析与总结 一、程序及输出 1.1 系统标准异常示例 #include<iostream> using namespace std; #include <stdexcept> // std 标准 except 异常class Person { public:Person(int age){if (age <…

短小精悍的npm入门级保姆教程,一篇包会

npm是什么&#xff1f; npm是一个强大的包管理工具&#xff0c;它使开发人员能够轻松地安装、更新和管理项目依赖的包。通过初始化一个package.json 文件&#xff0c;我们可以描述你的项目并记录其依赖关系。使用npm install命令&#xff0c;我们可以安装和管理包。使用npm pu…

SQL注入漏洞解析

什么是SQL注入 原理&#xff1a; SQL注入即是指web应用程序对用户输入数据的合法性没有判断或过滤不严&#xff0c;攻击者可以在web应用程序中事先定义好的查询语句的结尾上添加额外的SQL语句&#xff0c;在管理员不知情的情况下实现非法操作&#xff0c;以此来实现欺骗数据库服…

消息中间件之RocketMQ源码分析(十三)

Broker消息存储机制 RocketMQ首先将消息数据写入操作系统PageCache&#xff0c;然后定时将数据刷入磁盘。接下来主要分析RocketMQ是如何接收发送消息请求并将消息写入PageCache的&#xff0c;整个过程如图 Commit目录下有多个CommitLog文件&#xff0c;其实CommitLog只有一个…

前端构建效率优化之路

项目背景 我们的系统&#xff08;一个 ToB 的 Web 单页应用&#xff09;前端单页应用经过多年的迭代&#xff0c;目前已经累积有大几十万行的业务代码&#xff0c;30 路由模块&#xff0c;整体的代码量和复杂度还是比较高的。 项目整体是基于 Vue TypeScirpt&#xff0c;而构…

PostgreSQL与MySQL,谁更胜一筹

前言 PostgreSQL与MySQL都是优秀的开源数据库。在日常学习中&#xff0c;新手可能接触最多的是MySql,但是实际工作中&#xff0c;两者的应用场景其实都很广。我之前的做过上网流量销售业务&#xff0c;用的是MySQL,现在接触广告业务&#xff0c;用的是pg数据库&#xff0c;每天…

C语言:指针(一)

目录 1.内存和地址2. 指针变量和地址2.1 取地址操作符&#xff08;&&#xff09;2.2 指针变量和解引用操作符&#xff08;*&#xff09;2.2.1 指针变量2.2.2 解引用操作符&#xff08;*&#xff09; 2.3 指针变量的大小 3.指针变量的类型和意义3.1 指针的解引用3.2 指针 -指…

SQL注入漏洞解析--less-3

1.首先我们打开第三关看一下 2.这个和之前1.2关提示都是一样&#xff0c;所以我们先输入id数字看一下显示什么 3.这里正常回显&#xff0c;当我们后边加上时可以看到页面报错信息。可推断sql语句是单引号字符型且有括号&#xff0c;所以我们需要闭合单引号且也要考虑括号。 4…

FISCO BCOS(十七)利用脚本进行区块链系统监控

要利用脚本进行区块链系统监控&#xff0c;你可以使用各种编程语言编写脚本&#xff0c;如Python、Shell等 利用脚本进行区块链系统监控可以提高系统的稳定性、可靠性&#xff0c;并帮助及时发现和解决潜在问题&#xff0c;从而确保区块链网络的正常运行。本文可以利用脚本来解…

java使用File创建空文件和创建单级文件、多级文件、删除、获得文件夹下的文件和文件夹

1、使用createNewFile创建文件 package com.controller;import org.springframework.web.bind.annotation.*;import java.io.File; import java.io.IOException; import java.util.LinkedList;RestController CrossOrigin RequestMapping("/admin") public class Ad…

IO进程线程作业day5

1> 将互斥机制的代码实现重新敲一遍 #include <myhead.h> int num520;//定义一个全局变量 pthread_mutex_t mutex;//创建锁 //线程1任务 void *task1(void *arg) {puts("任务1");pthread_mutex_lock(&mutex);//上锁num1314;sleep(1);printf("tas…

Liunx使用nginx和http搭建yum-server仓库

文章目录 1. yum-server的搭建方式2. nginx搭建yum-server仓库2.1. 安装配置nginx2.2 配置yum-server的rpm2.3. 同步yum源相关包2.3.1 rsync同步源3.3.1 reposync同步源 2.4. 配置客户端访问yum配置2.5. 验证测试 3. http服务搭建yum-server仓库3.1. 安装配置http3.2 配置yum-s…

代码随想录算法训练营第一天

● 今日学习的文章链接和视频链接 ● 自己看到题目的第一想法 1. 704二分法&#xff1a; 方法一&#xff1a; 整个数组是 左闭右闭区间 [ ] left指针指向数组开始下标&#xff0c; right 指针指向数组最后下表nums.size()-1, mid为 (leftright) /2循环条件 left<rightnu…

论文精读--Noisy Student

一个 EfficientNet 模型首先作为教师模型在标记图像上进行训练&#xff0c;为 300M 未标记图像生成伪标签。然后将相同或更大的 EfficientNet 作为学生模型并结合标记图像和伪标签图像进行训练。学生网络训练完成后变为教师再次训练下一个学生网络&#xff0c;并迭代重复此过程…

unity学习(34)——角色选取界面(跨场景坑多)

先把SelectMenu中的camera的audio listener去掉。 现在还是平面&#xff0c;直接在camera下面添加两个panel即可&#xff0c;应该是用不到canvas了&#xff0c;都是2D的UI。 加完以后问题来了&#xff0c;角色选择界面的按钮跑到主界面上边了&#xff0c;而且现在账号密码都输…