Java面试——Tomcat
优质博文:IT_BLOG_CN
一、Tomcat 顶层架构
Tomcat
中最顶层的容器是Server
,代表着整个服务器,从上图中可以看出,一个Server
可以包含至少一个Service
,用于具体提供服务。Service
主要包含两个部分:Connector
和Container
。从上图中可以看出Tomcat
的心脏就是这两个组件,他们的作用如下:
【1】Connector
用于处理连接相关的事情,并提供Socket
与Request
和 Response
相关的转化;
【2】Container
用于封装和管理Servlet
,以及具体处理Request
请求;
一个Tomcat
中只有一个Server
,一个Server
可以包含多个Service
,一个 Service
只有一个Container
,但是可以有多个Connectors
,这是因为一个服务可以有多个连接,如同时提供Http
和Https
链接,也可以提供向相同协议不同端口的连接,示意图如下(Engine
、Host
、Context
下边会说到):
多个Connector
和一个Container
就形成了一个Service
,有了Service
就可以对外提供服务了,但是Service
还要一个生存的环境,必须要有人能够给她生命、掌握其生死大权,那就非Server
莫属了!所以整个Tomcat
的生命周期由 Server
控制。另外,上述的包含关系或者说是父子关系,都可以在tomcat
的 conf
目录下的 server.xml
配置文件中看出。
二、简要解释下 server.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 "%r" %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.xml
的整体架构(简洁版):
<Server><Service><Connector /><Connector /><Engine><Host><Context /><!-- 现在常常使用自动部署,不推荐配置Context元素,Context小节有详细说明 --></Host></Engine></Service>
</Server>
【1】**顶层元素:**元素是整个配置文件的根元素,元素代表一个Engine
元素以及一组与之相连的Connector
元素。
【2】连接器: 代表了外部客户端发送请求到特定Service
的接口;同时也是外部客户端从特定Service
接收响应的接口。
【3】**容器:**容器的功能是处理Connector
接收进来的请求,并产生对应的响应。Engine
包含Host
,Host
包含Context
。一个 Engine
组件可以处理Service
中的所有请求,一个Host
组件可以处理发向一个特定虚拟主机的所有请求,一个Context
组件可以处理一个特定Web
应用的所有请求。
三、Tomcat 都有哪些核心组件
【1】Server
:Server
元素在最顶层,代表整个 Tomcat
容器,因此他必须是server.xml
中唯一一个最外层的元素。一个Server
元素可以有一个或多个Service
元素。
<Server port="8005" shutdown="SHUTDOWN">
</Server>
可以看到,最外层有一个 元素,shutdown
属性表示关闭Server
的指令;port
属性表示Server
接收shutdown
指令的端口号,设置为-1
可以禁掉该端口。Server 的主要任务,就是提供一个接口让客户端能够访问到这个 Service集合,同时维护它所包含的所有的 Service的生命周期,包含如何初始化,如何结束服务,如何找到客户端要访问的 Service。
【2】**Service
:**在Connector
和Engine
外面包一层,把它们组合在一起,对外提供服务。一个Service
可以包含多个Connector
,但是只能包含一个Engine
;其中Connector
的作用是从客户端接收请求,Engine
的作用是处理接收进来的请求。
<Server port="8005" shutdown="SHUTDOWN"><Service name="Catalina"></Service>
</Server>
如上图,Server
中包含一个名称为Catalina
的Service
。实际上,Tomcat
可以提供多个Service
,不同的Service
监听不同的端口。
【3】**Connector
:**接收连接请求,创建Request
和 Response
对象用于和请求端交换数据;然后分配线程让Engine
来处理这个请求,并把产生的Request
和Response
对象传给Engine
。通过配置 Connector
,可以控制请求 Service的协议及端口号。
<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" /></Service>
</Server>
通过配置第一个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
是Service
组件中的请求处理组件。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
属性用于日志和错误信息,在整个Server
中应该是唯一的。defalutHost
属性指定了默认的host
名称,当发往本机的请求指定的host
名称不存在时,一律使用defaultHost
指定的host
进行处理;因此defaulthost
的值,必须与Engine
中的一个Host
组件的name
属性值匹配。
【5】Engine
和Host
:Host
是Engine
的子容器。Engine
组件中可以内嵌1
个或者多个Host
组件,每个Host
组件代表Engine
中的一个虚拟主机。Host
组件至少有一个,且其中一个的name
必须与 Engine
组件中的defaultHost
属性相匹配。
【6】Host
的作用:Host
虚拟主机的作用,是运行多个Web
应用(一个Context
代表一个Web
应用),并负责安装、展开、启动、结束每个Web
应用。Host
组件代表的虚拟主机,对应服务器中一个网络名实体(如www.test.com](https://links.jianshu.com/go?to=http%3A%2F%2Fwww.test.com)"或IP地址"116.25.25.25
);为了使用户可以通过网络名连接Tomcat
服务器,这个名字应该在DNS
服务器上注册。
客户端通常使用主机名来标识它们希望连接的服务器,该主机名也会包含在 HTTP
请求头中,Tomcat
从HTTP
头中提取出主机名,寻找名字匹配的主机。如果没有匹配,请求会发送至默认的主机。因此默认主机不需要再DNS
服务器中注册网络名,因为任何与所有Host
名称不匹配的请求,都会路由至默认主机。
【7】Host
的配置:name
属性指定虚拟主机的主机名,一个Engine
有且只有一个Host
组件的name
属性和Engine
组件的 defaultHost
属性相匹配;一般情况下,主机名需要是在DNS
服务器中注册网络名,但是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>
unpackWARs
指定了是否将代表Web
应用的WAR
文件解压;如果是true
,通过解压后的文件结构运行该Web
应用,如果是false
,直接使用WAR
文件运行Web
应用。
【8】Context
:Context
元素代表在虚拟主机上运行的一个Web
应用。在后文中,提到Context
、应用或Web
应用,他们都代指Web
应用,每个Web
应用基于WAR
文件,或WAR
文件解压后对应的目录(这里称为应用目录)Context
是Host
的子容器,每个Host
都可以定义任意多的Context
元素。元素的配置:Context
元素最重要的属性是 docBase
和path
,此外reloadable
属性也比较常用。
docBase
指定了该Web
应用使用war
包路径,或应用目录。需要注意的是:在自动部署场景下(配置文件位于xmlBase
中),docBase
不在appBase
目录中,才需要指定;如果docBase
指定的war
包或应用目录就在appBase
中,则不需要指定。因为Tomcat
会自动扫描appBase
中的war
包和应用目录,制定了反而造成问题。
path
指定了访问该Web
应用上下文路径,当请求到来时,Tomcat
根据Web
应用的path
属性与 URL匹配程度来选择Web
应用处理相应请求。例如:Web
应用app1
的path
属性是/app1
,Web
应用app2
的path
属性是"/app2",那么请求/app1/index.html
会交由app1
来处理;而请求/app2/index.html
会交由 app2
来处理。如果一个Context
元素的path
属性为"",那么这个Context
是虚拟主机的默认的Web
应用;当请求的uri
与所有的path
都不匹配时,使用该默认Web
应用来处理。
但是,需要注意的是,在自动部署场景(配置文件位于xmlBase
中),不能指定path属性,path
属性由配置的文件的文件名,WAR
文件的文件名或应用目录的名称自动推导出来。如扫描Web
应该时,发现xmlBase
目录下的app1.xml
,或appBase
目录下的app1.WAR
或app1
应用目录,则该Web用于的path
属性是app1
。如果名称不是app1
而是ROOT
,则该Web应用时虚拟主机默认的Web
应用,此时path
属性推导为""。
reloadable
属性指示tomcat
是否在运行时监控在WEB-INF/classes
和WEB-INF/lib
目录下class
文件的改动。如果值为true
,那么当class
文件改动时,会重新web
应用的重新加载。在开发环境下,reloadable
设置为ture
便于调试;但是在生产环境中设置为true
会给服务器带来性能压力,因此reloadable
参数的默认值为false
。在该例子中,docBase
位于Host
的appBase
目录之外;path
属性没有指定,而是根据app1.xml
自动推导为app1
。
<Context docBase="D:Program Filesapp1.war" reloadable="true"></Context>
若是自动部署(即autoDeploy="true"
),那么server.xml
配置文件中没有Context
元素的配置。这是因为Tomcat
开启了自动部署,Web
应用没有在 server.xml
中配置静态部署,而是由Tomcat
通过特定的规则自动部署。
四、Web 的自动部署
要开启Web
应用的自动部署,需要配置所在的虚拟主机;配置的方式就是在配置Host
元素的 deployOnStartup
和autoDeploy
属性。如果deployOnStartup
和autoDeploy
设置为true
,则tomcat
启动自动部署:当检测到新的Web
应用或Web
应用更新时,会触发应用的部署(或重新部署)。
二者的主要区别在于
【1】deployeOnStartup
为true
时,Tomcat
在启动时检查Web
应用,且检测到所有的Web
应用都试做新应用;
【2】autoDeploy
为true
时,Tomcat
在运行时定期检查新的Web
应用或Web
应用的更新;
通过配置
deployOnStartup
和autoDeploy
可以开启虚拟主机自动部署Web
应用;实际上,自动部署依赖于检查是否有新的或更改过的Web
应用,而Host
元素中的appBase
和xml
配置设置了检查Web
应用更新的目录。
其中,appBase
属性指定Web
应用所在的目录,默认值是webapps
,这是一个相对路径,代表 Tomcat
根目录下的webapps
文件夹。xmlBase
属性指定Web
应用的XML
配置文件所在的目录,默认值为conf/<engine_name><engine_name>
,例如上面例子中,主机localhost
的xmlBase
的默认值是$TOMCAT_HOME/conf/Catalina/localhost
。
五、appBase 和 docBase的区别
【1】**appBase
:这个目录下面的子目录将自动被部署为应用,且war
文件将被自动解压缩并部署为应用,默认为tomcat
下webapps
目录。
【2】docBase
:**指定需要关联的项目自动解压并部署到appBase
目录下。项目的名称由path
属性决定。
先部署 需要注意,docBase
所在的文件或者war
包必须存在。否则项目启动找不到对应的目录。此时文件解压到appBase
目录下,根据path
属性,决定解压后的文件名。
若采用了<Host name="localhost" appBase="webapp" autoDeploy="true">
配置,那么appBase
目录下的应用目录将会再次部署。此时项目是部署了两遍。解决办法,设置autoDeploy="false"
。
六、Tomcat 顶层架构小结
【1】Tomcat
中只有一个Server
,一个Server
可以有多个Service
,一个Service
可以有多个 Connector
和一个Container
;
【2】Server
掌管着整个Tomcat
的生死大权;
【3】Service
是对外提供服务的;
【4】Connector
用于接受请求并将请求封装成Request
和Response
来具体处理;
【5】Container
用于封装和管理Servlet
,以及具体处理Request
请求;
知道了整个Tomcat
顶层的分层架构和各个组件之间的关系以及作用,对于绝大多数的开发人员来说 Server
和Service
对我们来说确实很远,而我们开发中绝大部分进行配置的内容是属于Connector
和 Container
的,所以接下来介绍一下Connector
和Container
。
七、Connector 和 Container的微妙关系
由上述内容我们大致可以知道一个请求发送到Tomcat
之后,首先经过Service
然后会交给我们的 Connector
,Connector
用于接收请求并将接收的请求封装为Request
和Response
来具体处理,Request
和Response
封装完之后再交由Container
进行处理,Container
处理完请求之后再返回给 Connector
,最后在由Connector
通过Socket
将处理的结果返回给客户端,这样整个请求的就处理完了!
Connector
最底层使用的是Socket
来进行连接的,Request
和Response
是按照HTTP
协议来封装的,所以Connector
同时需要实现TCP/IP
协议和HTTP
协议。Tomcat
既然处理请求,那么肯定需要先接收到这个请求,接收请求这个东西我们首先就需要看一下Connector
。
八、Container 架构分析
Container
用于封装和管理Servlet
,以及具体处理Request
请求,在Connector
内部包含了4
个子容器,结构图如下:
4个子容器的作用分别是:
【1】Engine
:引擎,用来管理多个站点,一个Service
最多只能有一个Engine
;
【2】Host
:代表一个站点,也可以叫虚拟主机,通过配置Host
就可以添加站点;
【3】Context
:代表一个应用程序,对应着平时开发的一套程序,或者一个WEB-INF
目录以及下面的web.xml
文件;
【4】Wrapper
:每一Wrapper
封装着一个Servlet
;
下面找一个Tomcat
的文件目录对照一下,如下图所示:
Context
和Host
的区别是Context
表示一个应用,我们的Tomcat
中默认的配置下webapps
下的每一个文件夹目录都是一个Context
,其中ROOT
目录中存放着主应用,其他目录存放着子应用,而整个 webapps就是一个 Host站点。我们访问应用Context
的时候,如果是ROOT
下的则直接使用域名就可以访问,例如:www.ledouit.com,如果是Host(webapps)
下的其他应用,则可以使用 www.ledouit.com/docs 进行访问,当然默认指定的根应用ROOT
是可以进行设定的,只不过Host
站点下默认的主营用是ROOT
目录下的。
看到这里我们知道Container
是什么,但是还是不知道Container
是如何进行处理的以及处理完之后是如何将处理完的结果返回给Connector
的。
十、Container 如何处理请求的
Container
处理请求是使用Pipeline-Valve
管道来处理的!(Valve
是阀门之意)Pipeline-Valve
是责任链模式,责任链模式是指在一个请求处理的过程中有很多处理者依次对请求进行处理,每个处理者负责做自己相应的处理,处理完之后将处理后的请求返回,再让下一个处理着继续处理。
但是!Pipeline-Valve
使用的责任链模式和普通的责任链模式有些不同!区别主要有以下两点:
【1】每个Pipeline
都有特定的Valve
,而且是在管道的最后一个执行,这个Valve
叫做BaseValve
,BaseValve
是不可删除的;
【2】在上层容器的管道的BaseValve
中会调用下层容器的管道。
我们知道Container
包含四个子容器,而这四个子容器对应的BaseValve
分别在:StandardEngineValve
、StandardHostValve
、StandardContextValve
、StandardWrapperValve
。Pipeline
的处理流程图如下:
【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
的方式将结果返回给客户端。
十一、tomcat 容器是如何创建 servlet类实例?用到了什么原理?
当容器启动时,会读取在webapps
目录下所有的web
应用中的web.xml
文件,然后对xml
文件进行解析,并读取servlet
注册信息。然后,将每个应用中注册的servlet
类都进行加载,并通过反射的方式实例化。(有时候也是在第一次请求时实例化)在servlet
注册时加上如果为正数,则在一开始就实例化,如果不写或为负数,则第一次请求实例化。
十二、共享 session处理
目前的处理方式有如下几种:
【1】使用Tomcat
本身的Session
复制功能。参考http://ajita.iteye.com/blog/1715312
(Session
复制的配置)方案的有点是配置简单,缺点是当集群数量较多时,Session
复制的时间会比较长,影响响应的效率;
【2】使用第三方来存放共享Session
:目前用的较多的是使用memcached
来管理共享Session
,借助于memcached-sesson-manager
来进行Tomcat
的Session
管理。参考http://ajita.iteye.com/blog/1716320
(使用MSM
管理Tomcat
集群session
)
【3】使用黏性session
的策略:对于会话要求不太强(不涉及到计费,失败了允许重新请求下等)的场合,同一个用户的session
可以由nginx
或者apache
交给同一个Tomcat
来处理,这就是所谓的 session sticky
策略,目前应用也比较多。参考:http://ajita.iteye.com/blog/1848665(tomcat session sticky)Nginx
默认不包含session sticky
模块,需要重新编译才行(windows
下我也不知道怎么重新编译)优点是处理效率高多了,缺点是强会话要求的场合不合适。
十三、关于 Tomcat 的 session数目
这个可以直接从Tomcat
的web
管理界面去查看即可,或者借助于第三方工具Lambda Probe
来查看,它相对于Tomcat
自带的管理稍微多了点功能,但也不多 ;
十四、Tomcat 一个请求的完整过程
首先DNS
解析机器,一般是ng
服务器ip
地址,然后ng
根据server
的配置,寻找路径为yy/
的机器列表,ip
和端口。最后 选择其中一台机器进行访问。下面为详细过程:
【1】请求被发送到本机端口8080
,被在那里侦听的Coyote HTTP/1.1 Connector
获得;
【2】Connector
把该请求交给它所在的Service
的Engine
来处理,并等待来自Engine
的回应;
【3】Engine
获得请求localhost/yy/index.jsp
,匹配它所拥有的所有虚拟主机Host
;
【4】Engine
匹配到名为 localhost 的 Host(即使匹配不到也把请求交给该 Host处理,因为该Host被定义为该 Engine的默认主机);
【5】localhost Host
获得请求/yy/index.jsp
,匹配它所拥有的所有Context
;
【6】Host
匹配到路径为/yy
的Context
(如果匹配不到就把该请求交给路径名为”“的Context
去处理);
【7】path=”/yy”
的Context
获得请求/index.jsp
,在它的mapping table
中寻找对应的servlet
;
【8】Context
匹配到URL PATTERN
为*.jsp
的servlet
,对应于JspServlet
类;
【9】构造HttpServletRequest
对象和HttpServletResponse
对象,作为参数调用JspServlet
的doGet
或 doPost
方法;
【10】Context
把执行完了之后的HttpServletResponse
对象返回给Host
;
【11】Host
把HttpServletResponse
对象返回给Engine
;
【12】Engine
把HttpServletResponse
对象返回给Connector
;
【13】Connector
把HttpServletResponse
对象返回给客户browser
;
十五、Tomcat 工作模式
Tomcat
是一个JSP/Servlet
容器。其作为Servlet
容器,有三种工作模式:独立的Servlet
容器、进程内的Servlet
容器和进程外的Servlet
容器。进入Tomcat
的请求可以根据Tomcat
的工作模式分为如下两类:
【1】Tomcat
作为应用程序服务器:请求来自于前端的web
服务器,这可能是Apache
, IIS
, Nginx
等;
【2】Tomcat
作为独立服务器:请求来自于web
浏览器;
Tomcat
的工作一般分为三种:
【1】bio
: 传统的Java I/O
操作,同步且阻塞I/O
,一个线程处理一个请求,并发量高时,线程数较多,浪费资源;(已经很少有人在使用)
【2】nio
: JDK1.4
开始支持,同步阻塞或同步非阻塞IO
,可以通过少量的线程来处理大量的请求;(从Tomcat 8
版本开始默认就是这种模式)
【3】apr
: 以JNI
的形式调用Apache HTTP
服务器的核心动态链接库来处理文件读取或网络传输操作,从而大大地提高Tomcat
对静态文件的处理性能;(企业中使用较多)
十六、如何对 Tomcat 进行优化
【1】关闭Manager
管理页面;(默认已经关闭)
【2】关闭host-mangent
管理页面;(默认已经关闭)
【3】对Tomcat
日志进行分割;
【4】定义Tomcat 404
错误返回的页面;
【5】对JVM
进行优化;
【6】对Tomcat
线程池进行优化;
十七、如何对 Tomcat 进行优化
【1】关闭Manager
管理页面;(默认已经关闭)
【2】关闭host-mangent
管理页面;(默认已经关闭)
【3】对Tomcat
日志进行分割;
【4】定义Tomcat 404
错误返回的页面;
【5】对JVM
进行优化;
【6】对Tomcat
线程池进行优化;
【7】更改Tomcat
的工作的模式;
相关文章:
Java面试——Tomcat
优质博文:IT_BLOG_CN 一、Tomcat 顶层架构 Tomcat中最顶层的容器是Server,代表着整个服务器,从上图中可以看出,一个Server可以包含至少一个Service,用于具体提供服务。Service主要包含两个部分:Connector和…...
游戏引擎学习第113天
仓库:https://gitee.com/mrxiao_com/2d_game_2 黑板:优化的基本过程 在游戏编程中,优化是一个非常重要的学习内容,尤其是想要成为专业开发者时。优化的核心是理解代码的执行速度,以及如何提升其性能。在这个阶段,已经…...
【EB-02】TC397 Tresos 最小工程配置
TC397 Tresos 最小工程配置 1. 新建demo 工程2. 配置消除错误2.1 ResourceM 设置2.2 McalLib模块配置3. 生成代码3.1 校验工程3.2 生成代码1. 新建demo 工程 新建工程 设置工程名称 选择芯片型号 选择添加模块 得到最小工程需求模块 2. 配置消除错误 2.1 ResourceM 设置 设置芯…...
深入理解WebSocket接口:如何使用C++实现行情接口
在现代网络应用中,实时数据传输变得越来越重要。通过WebSocket,我们可以建立一个持久连接,让服务器和客户端之间进行双向通信。这种技术不仅可以提供更快的响应速度,还可以减少不必要的网络流量。本文将详细介绍如何使用C来实现We…...
前端面试题
以下是一些前端面试题: 一、HTML/CSS部分 如何实现一个元素的背景颜色渐变效果,并且在不同浏览器中保持兼容性? 答案: 对于现代浏览器,可以使用标准的CSS渐变语法。 线性渐变示例(从左到右,红色到蓝色):background: linear - gradient(to right, red, blue);径向渐变…...
Win11 24h2 不能正常使用ensp的问题(已解决)
因为Win11 24h2的内核大小更改,目前virtualbox在7.1.4中更新解决了。所以Win11 24H2系统版本无法使用 5.x.xx的virtualbox版本,virtualbox对于这个5.x.xx版本早已停止维护,所以这个以后不会有调整。 对应的报错代码是 virtualbox错误代码&…...
Hyper-V初探
听说window自带虚拟机,小窃喜了一下,这样就不用下载第三方虚拟机软件了:VMware或者Oracle VirtualBox,但是本地搜索一看,发现没有安装,百度了一下说家庭中文版是个阉割版的系统,只有教育版&…...
IP协议
IP协议介绍 IP地址=目标网络+目标主机 IP协议是网络层协议 IP报头格式 [IP报头图片] IP报头解析 4 位版本号(version): 指定 IP 协议的版本, 对于 IPv4 来说, 就是 4. 4 位头部长度(header length): IP 头部的长度是多少个 32bit, 也就是 length 4…...
Django Admin: 实现基于数据库实际值的动态过滤器
在 Django Admin 中,我们经常需要使用 list_filter 来为管理界面添加过滤功能。然而,有时我们希望过滤器能够动态地反映数据库中的实际值,而不是依赖于预定义的选项。本文将介绍如何实现一个基于数据库实际值的动态过滤器,以 ECR 仓库的区域过滤为例。 问题背景 在管理 E…...
overflow-x: auto 使用鼠标实现横向滚动,区分触摸板和鼠标滚动事件的方法
假设一个 div 的滚动只设置了 overflow-x: auto 我们发现使用鼠标的滚轮是无法左右滚动的,但是使用笔记本电脑的触摸板,或者在移动设备上是可以滚动的。所以我们需要兼容一下鼠标的横向滚动功能。 我们可以监控 wheel 事件,然后根据位置来计…...
DPVS-2:单臂负载均衡测试
上一篇编译安装了DPVS,这一篇开启DPVS的负载均衡测试 : 单臂 FULL NAT模式 拓扑-单臂 单臂模式 DPVS 单独物理机 CLINET,和两个RS都是另一个物理机的虚拟机,它们网卡都绑定在一个桥上br0 , 二层互通。 启动DPVS …...
宇树科技13家核心零部件供应商梳理!
2025年2月6日,摩根士丹利(Morgan Stanley)发布最新人形机器人研报:Humanoid 100: Mapping the Humanoid Robot Value Chain(人形机器人100:全球人形机器人产业链梳理)。 Humanoid 100清单清单中…...
sqli-labs之Kali搭建靶场环境
背景: SQL注入是一种常见的Web安全漏洞,攻击者可以通过该漏洞在应用程序中执行任意的SQL命令。为了帮助开发者和安全研究人员更好地理解和防范SQL注入攻击,sqli-labs应运而生。它是一个开源项目,提供了一系列的SQL注入练习环境&a…...
Kafka在Windows系统使用delete命令删除Topic时出现的问题
在使用Windows的Kafka时,想要删除某一个主题,发现使用了delete之后会一直报警告。下面是我发现错误之后重新实测的Bug 先创建2个topic kafka-topics.bat --bootstrap-server localhost:9092 --topic test1 --createkafka-topics.bat --bootstrap-serve…...
JVM 面试题相关总结
🧑 博主简介:CSDN博客专家,历代文学网(PC端可以访问:https://literature.sinhy.com/#/literature?__c1000,移动端可微信小程序搜索“历代文学”)总架构师,15年工作经验,…...
动态记忆网络 DeepMind的MEMO架构允许在推理时动态读写记忆矩阵,记忆容量提升40倍
为了更深入地理解 MEMO 架构的意义,我来详细解读一下,并探讨它在实际应用中的潜力: MEMO 架构的核心思想 MEMO (Memorizing over Memorized) 架构的核心思想是 “层叠记忆”。 传统的记忆网络通常只有一个外部记忆模块,而 MEMO …...
go 并发 gorouting chan channel select Mutex sync.One
goroutine // head: 前缀 index:是一个int的指针 func print(head string, index *int) {for i : 0; i < 5; i {// 指针对应的int *indexfmt.Println(*index, head, i)// 暂停1stime.Sleep(1 * time.Second)} }/* Go 允许使用 go 语句开启一个新的运…...
【STM32 基于PID的闭环电机控制系统】
STM32 基于PID的闭环电机控制系统 目录 STM32 基于PID的闭环电机控制系统一、PID算法在STM32F103C8T6中的实现思路二、代码实现与解释三、PID算法的调试与优化四、总结 一、PID算法在STM32F103C8T6中的实现思路 基本概念 • 目标 :通过PID算法调节电机的转速&#…...
Linux命令后双减号符(--)的含义
个人博客地址:Linux命令后双减号符(--)的含义 | 一张假钞的真实世界 Unix/Linux下各种命令的参数,都是以减号符(-)后面跟单字符参数,比如-r)或者双减号符(--)…...
QT闲记-工具栏
工具栏通常用来放置常用的操作按钮,如QPushButton,QAction等。可以放置在顶部,底部,左侧,右侧,并且支持拖曳,浮动。 1、创建工具栏 通常通过QMainWindow 提供的addToolBar()来创建,它跟菜单栏一样,如果需要工具栏,一般情况下,我们设置这个类的基类为QMainWindow。 …...
Linux中ps -ef命令详解
ps -ef 是一个常用的 Unix/Linux 命令,用于显示当前系统中所有进程的详细信息。具体来说,ps 是 "process status" 的缩写,用于查看进程的状态。-ef 是 ps 命令的选项组合,用于指定输出的格式和内容。 选项解释…...
【JavaScript】《JavaScript高级程序设计 (第4版) 》笔记-Chapter20-JavaScript API
二十、JavaScript API JavaScript API 随着 Web 浏览器能力的增加,其复杂性也在迅速增加。从很多方面看,现代 Web 浏览器已经成为构建于诸多规范之上、集不同 API 于一身的“瑞士军刀”。浏览器规范的生态在某种程度上是混乱而无序的。一些规范如 HTML5&…...
详解分布式ID实践
引言 分布式ID,所谓的分布式ID,就是针对整个系统而言,任何时刻获取一个ID,无论系统处于何种情况,该值不会与之前产生的值重复,之后获取分布式ID时,也不会再获取到与其相同的值,它是…...
Linux 高级篇 日志管理、定制自己的Linux系统、备份与恢复
一、日志管理 (1)基本介绍 日志文件是重要的系统信息文件,记录了如用户登录、系统启动、系统安全、邮件及各种服务等相关重要系统事件在安全方面,日志也至关重要,它能记录系统日常发生的各类事情,可用于检…...
uniapp中@input输入事件在修改值只有第一次有效的问题解决
在uniapp中使用输入框,要求输入不超过7个字,所以需要监听输入事件,当每次输入文字的时候,就把输入的值截断,取前7个值。但是在input事件中,重新赋值的值发生了变化,但是页面上的还是没有变&…...
单片机 code RO-data RW-data ZI-data以及OTA学习
带着问题去学习:这些数据是什么?分别放在哪里, 是什么:我个人的理解 code 和RO-data 分别是代码和只读数据,RW-data以及ZI-data分别是读写数据和初始化数据。 codeRO-data的大小正好是所占用ROM的大小,RO…...
Jenkins 视图(View)
Jenkins 视图(View) 一、视图是什么 Jenkins 视图(View) 如下图中 All、Apps 都是 Jenkisn 中的 View 左侧如果有 New View 或者 点击 All 这一行最右侧的 号,都可以创建视图 二、视图(View)的作用 点击最左侧的 All 可以看到所有的任务 随着项目不断发展&am…...
【Deepseek+Dify】wsl2+docker+Deepseek+Dify部署本地大模型知识库问题总结
wsl2dockerDeepseekDify部署本地大模型知识库问题总结 基于ollama部署本地文本模型和嵌入模型 部署教程 DeepSeekdify 本地知识库:真的太香了 问题贴:启动wsl中docker中的dify相关的容器 发现postgre服务和daemon服务一直在重启,导致前端加…...
实战解析传统发电站智能化改造-第二期(带图带教程)
传统发电站的智能化改造,如同为老工匠配备高科技工具,提升效率与精准度。改造后的发电站兼具传统与智能,更高效、环保,适应现代能源需求。智慧系统搭建平台是连接感知层和应用层的桥梁,将原始数据转化为有价值的信息&a…...
鸿蒙5.0实战案例:基于自定义注解和代码生成实现路由框架
往期推文全新看点(文中附带全新鸿蒙5.0全栈学习笔录) ✏️ 鸿蒙(HarmonyOS)北向开发知识点记录~ ✏️ 鸿蒙(OpenHarmony)南向开发保姆级知识点汇总~ ✏️ 鸿蒙应用开发与鸿蒙系统开发哪个更有前景&#…...
项目设置内网 IP 访问实现方案
在我们平常的开发工作中,项目开发、测试完成后进行部署上线。比如电商网站、新闻网站、社交网站等,通常对访问不会进行限制。但是像企业内部网站、内部管理系统等,这种系统一般都需要限制访问,比如内网才能访问等。那么一个网站应…...
单片机 Bootloade与二进制文件的生成
单片机的 Bootloader 是一种特殊的程序,负责在单片机上电后初始化硬件、更新用户应用程序(固件),并将控制权移交给用户程序。以下是其运行机制和关键流程的详细说明: 1、单片机 Bootloader 的核心作用 固件更新&…...
open webui 部署 以及解决,首屏加载缓慢,nginx反向代理访问404,WebSocket后端服务器链接失败等问题
项目地址:GitHub - open-webui/open-webui: User-friendly AI Interface (Supports Ollama, OpenAI API, ...) 选择了docker部署 如果 Ollama 在您的计算机上,请使用以下命令 docker run -d -p 3000:8080 --add-hosthost.docker.internal:host-gatewa…...
深度学习每周学习总结Y1(Yolov5 调用官方权重进行检测 )
🍨 本文为🔗365天深度学习训练营 中的学习记录博客Y1中的内容 🍖 原作者:K同学啊 | 接辅导、项目定制 ** 注意该训练营出现故意不退押金,恶意揣测偷懒用假的结果冒充真实打卡记录,在提出能够拿到视频录像…...
HTML项目一键打包工具:HTML2EXE 最新版
HTML2EXE 工具可以一键打包生成EXE可执行文件。可以打包任意HTML项目或者是一个网址为单个EXE文件,直接打开即可运行。支持KRPano全景VR项目、WebGL游戏项目、视频播放、,课件打包、网址打包等。 一、功能特点 类别序号功能标题1支持程序图标自定义(支持…...
网络工程师 (43)IP数据报
前言 IP数据报是互联网传输控制协议(Internet Protocol,IP)的数据报格式,由首部和数据两部分组成。 一、首部 IP数据报的首部是控制部分,包含了数据报传输和处理所需的各种信息。首部可以分为固定部分和可变部分。 固定…...
springboot-自定义注解
1.注解的概念 注解是一种能被添加到java代码中的【元数据,类、方法、变量、参数和包】都可以用注解来修饰。用来定义一个类、属性或一些方法,以便程序能被捕译处理。 相当于一个说明文件,告诉应用程序某个被注解的类或属性是什么,…...
Pytorch实现之特征损失与残差结构稳定GAN训练,并训练自己的数据集
简介 简介:生成器和鉴别器分别采用了4个新颖设计的残差结构实现,同时在损失中结合了鉴别器层的特征损失来提高模型性能。 论文题目:Image Generation by Residual Block Based Generative Adversarial Networks(基于残留块的生成对抗网络产生图像) 会议:2022 IEEE Int…...
微信小程序模仿快播标签云滚动特效
说到快播,故事肯定就不少。用过的人都知道快播首页有个标签云的特效效果,就是渐隐渐显外加上下滚动,其实还挺好看的。至于其他故事嘛,因为没有酒,所以,还是来说说代码吧~ 一开始不是做这个特效需求…...
XUnity.AutoTranslator-deepseek——调用腾讯的DeepSeek V3 API,实现Unity游戏中日文文本的自动翻译
XUnity.AutoTranslator-deepseek 本项目通过调用腾讯的DeepSeek V3 API,实现Unity游戏中日文文本的自动翻译。 准备工作 1. 获取API密钥 访问腾讯云API控制台申请DeepSeek的API密钥(限时免费)。也可以使用其他平台提供的DeepSeek API。 …...
对比机器学习揭示了跨物种共享与特异性的脑功能结构|文献速递-医学影像人工智能进展
Title 题目 Contrastive machine learning reveals species -shared and -specific brainfunctional architecture 对比机器学习揭示了跨物种共享与特异性的脑功能结构 01 文献速递介绍 猕猴作为人类的动物模型,广泛用于研究大脑和行为的关键方面(G…...
Vue 和 React 响应式的区别
React 和 Vue 在响应式机制上的核心区别主要体现在数据变化侦测方式、更新触发逻辑和设计理念上,具体如下: 一、数据变化侦测方式 Vue 的响应式 原理:通过 Proxy(Vue3)或 Object.defineProperty(Vue2&#…...
MySQL主从架构
MySQL主从架构 MySQL REPLICATION 在实际生产环境中,如果对数据库的读和写都在一个数据库服务器中操作。无论是在安全性、高可用性,还是高并发等各个方面都是完全不能满足实际需求的,因此,一般来说都是通过主从复制(…...
基于ros2与gazebo的导航仿真案例
文章目录 前言操作1、创建docker容器2、安装ROS23、Gazebo安装4、Nav2安装5、测试 前言 导航的入门小案例 参考: Ubuntu24.04 ROS2 Jazzy Gazebo Harmonic安装教程Docs / Gazebo Harmonic 注意选择版本 ROS 2 documentation 操作 1、创建docker容器 sudo docke…...
《Python实战进阶》专栏 No.3:Django 项目结构解析与入门DEMO
《Python实战进阶》专栏 第3集:Django 项目结构解析与入门DEMO 在本集中,我们将深入探讨 Django 的项目结构,并实际配置并运行一个入门DEMO博客网站,帮助你在 Web 开发中更高效地使用 Django。Django 是一个功能强大的 Python Web…...
基于WebGIS技术的校园地图导航系统架构与核心功能设计
本文专为IT技术人员、地理信息系统(GIS)开发者、智慧校园解决方案架构师及相关领域的专业人士撰写。本文提出了一套基于WebGIS技术的校园地图导航系统构建与优化方案,旨在为用户提供高效、智能、个性化的导航体验。如需获取校园地图导航系统技…...
开源且免费的CMS系统有哪几个可以放心用?
既开源又免费的两全其美的CMS不多见,不过总会存在一些个例,给用户们带来更具有建设性的选择,以下是一些开源免费且值得信赖的CMS系统,可以根据你的需求选择合适的平台: 1、WordPress ▷ 特点:全球最流行的…...
逻辑架构与软件架构在PREEvision中的设计关系
1 Introduction 在如今汽车电子系统的开发过程中,系统架构设计是至关重要的环节。无论是汽车控制系统、信息娱乐系统,还是电动驱动系统,架构设计都决定了整个系统的功能、性能以及后期的可维护性和可扩展性。 在往期文章中,我们…...
DeepSeek vs ChatGPT:AI 领域的华山论剑,谁主沉浮?
一、引言 在当今科技飞速发展的时代,人工智能(AI)已然成为推动各领域变革的核心力量。而在人工智能的众多分支中,自然语言处理(NLP)因其与人类日常交流和信息处理的紧密联系,成为了最受瞩目的领…...
现场可以通过手机或者pad实时拍照上传到大屏幕的照片墙现场大屏电子照片墙功能
现场可以通过手机或者pad实时拍照上传到大屏幕的照片墙现场大屏电子照片墙功能,每个人都可以通过手机实时拍照上传到大屏幕上,同时还可以发布留言内容,屏幕上会同步滚动播放展示所有人的照片和留言。相比校传统的照片直播功能更加灵活方便,而…...