Tomcat 核心配置
tomcat的核心配置在conf/server.xml中。
<Server> 根元素
<Server>即Catalina Servlet组件。
<Server port="8005" shutdown="SHUTDOWN">
常用属性
- Address—Tomcat监听shutdown命令的地址,默认为localhost
- className—指定实现org.apache.catalina.Server接口的类,默认值为org.apache.catalina.core.StandardServer
- port-Tomcat监听shutdown命令的端口。设置为-1,则禁止通过端口关闭Tomcat,同时shutdown.bat也不能使用
- shutdown-通过指定的地址(Address)、端口(port)关闭Tomcat所需的字符串。
远程关闭tomcat示例
启用Telnet:(Telnet是windows自带的与其它主机通信的程序)
win+s,输入telnet,匹配“启用或关闭windows功能”,回车,勾选telent
命令行输入 telnet 启动Telnet
输入 telnet localhost 8005 连接到指定主机(此处为本地主机)
输入 SHUTDOWN 即可关闭Tomcat
输入 quit 可退出Telnet
<Server>有3个子元素:<Listener>、<GlobalNamingResources>、<Service>。
<Listener>
Listener即监听器,负责监听特定的事件,当特定事件触发时,Listener会捕捉到该事件,并做出相应处理。
Listener通常用在Tomcat的启动和关闭过程,可嵌在Server、Engine、Host、Context内。
<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" /> <!--Initialize Jasper prior to webapps are loaded. Documentation at /docs/jasper-howto.html --> <Listener className="org.apache.catalina.core.JasperListener" /> <!-- 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" />
常用属性:
- className-指定org.apache.catalina.LifecycleListener接口的实现类
<GlobalNamingResources>
GlobalNamingResources用于配置JNDI,默认只加载conf/tomcat-users.xml中的用户配置。
<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>包含<Executor>、<Connector>、<Engine>3个组件|子元素,组成一个完整的服务。一个<Server>可以包含多个<Service>。
<Service name="Catalina">
<Executor /> <Connector />
<Engine></Engine>
</Service>
常用属性:
- name—<Service>的名字,需唯一
- className—指定org.apache.catalina. Service接口的实现类,默认值为org.apache.catalina.core.StandardService
<Service>的子元素
(1)<Executor>
Executor即Service提供的线程池,供Service内各组件使用。
<!-- <Executor name="tomcatThreadPool" namePrefix="catalina-exec-" maxThreads="150" minSpareThreads="4"/> -->
这个是tomcat提供的配置示例,并不是默认配置。
常见属性:
- name-线程池的名称
- className-指定实现org.apache.catalina. Executor接口的类,默认值为org.apache.catalina.core. StandardThreadExecutor
- daemon-线程池内的线程是否为守护线程,默认值为true
- threadPriority 线程池内线程的优先级,默认值5
- namePrefix-线程名的前缀。线程名通常为namePrefix+ threadNumber
- maxThreads-线程池内线程数上限,默认值200
- minSpareThreads-线程池内线程数下限,默认值10
- maxIdleTime-空闲线程的存活时间(单位:ms),默认值60000,即1min
- maxQueueSize-线程池满的情况下会将请求放在队列中排队等待,此属性设置队列大小(可容纳的请求个数),默认值100,超过此值,将拒绝连接
- prestartminSpareThreads-是否在Executor启动时,就生成minSpareThreads个线程。默认值false
- threadRenewalDelay-重建线程的时间间隔。重建线程池内的线程时,为了避免线程同时重建,每隔threadRenewalDelay(单位:ms)重建一个线程。默认值1000,设置为负则不重建
<Executor>配置的线程池,是此<Service>中的所有<Host>(所有webapp)共享的。
(2)<Connector>
Connector负责与其它机器(客户端、其它服务器)的通信、建立连接。
<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />
<!-- <Connector executor="tomcatThreadPool" port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" /> -->
<!-- <Connector port="8443" protocol="org.apache.coyote.http11.Http11Protocol" maxThreads="150" SSLEnabled="true" scheme="https" secure="true" clientAuth="false" sslProtocol="TLS" /> -->
<!-- <Connector protocol="AJP/1.3" address="::1" port="8009" redirectPort="8443" /> -->
有两种:HTTP Connector和AJP Connector,分别是使用http协议建立http连接、使用ajp协议建立ajp连接。
HTTP Connector负责与客户端通信,AJP Connector负责与其它web容器(apache、其他tomcat)通信。
nginx+tomcat的架构模式使用http,用不上ajp,可以将ajp连接注释掉。
默认只配置了http请求,客户端以http://ip|host:8080/的方式请求tomcat。
如果要使用安全的http协议,需要取消https的注释,客户端就可以通过https://ip|host:8443/的方式请求tomcat,或者以https://ip|host:8080/来请求tomcat(https+8080),会自动重定向到8443端口(https)。https可以看做数据加密的http,使用的是BIO,安全但是效率低。
默认都是使用tomcat默认配置的线程池,可以用executor属性引用自己配置的线程池。
<Connector>的常用属性:
- port-监听|接收请求的端口
- protocol-使用的协议
- connectionTimeout-连接超时时间,默认单位ms
- redirectPort-如果对方以https向http的端口(默认8080)发起请求时,将请求重定向到https的端口(默认8443)
- executor-指定线程池。也可以直接在<Connector>标签内设置maxThreads(默认200)、minSpareThreads(默认10)
- acceptCount-Connector请求队列的上限,默认值100,超过100,将拒绝连接
(3)<Engine>
Engine负责处理所有的请求:接收来自Connector的请求,传给对应的Host处理,Host调用对应的Context(webapp)来处理,处理完将结果一级一级往上传。
一个<Service>内必须包含、且只能包含一个<Engine>,可以包含一个或多个<Connector>,这些<Connector>共用一个<Engine>。
<!-- <Engine name="Catalina" defaultHost="localhost" jvmRoute="jvm1"> --> <Engine name="Catalina" defaultHost="localhost"> <!-- <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/> -->
<Realm className="org.apache.catalina.realm.LockOutRealm"> <Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase"/> </Realm>
<Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true"> <!-- <Valve className="org.apache.catalina.authenticator.SingleSignOn" /> --> <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" prefix="localhost_access_log." suffix=".txt" pattern="%h %l %u %t "%r" %s %b" /> </Host> </Engine>
<Engine>的常用属性:
- name-Engine的名字
- defaultHost-指定默认的Host。Engine接收来自Connector的请求,传给对应的Host来处理,如果找不到对应的host,就使用默认的host来处理。
- className-指定实现org.apache.catalina. Engine接口的类,默认值为org.apache.catalina.core. StandardEngine
- backgroundProcessorDelay-Engine及其部分子组件(Host、Context)调用backgroundProcessor方法的时间间隔,默认值10,负值表示不调用backgroundProcessor
Tomcat启动后,Engine、Host、Context都会启动一个后台线程,定期调用backgroundProcessor方法
backgroundProcessor方法主要用于重新加载Web应用程序的类文件和资源、扫描Session过期
- jvmRoute-Tomcat集群节点的id,tomcat路由时使用此属性。
session共享
session原本是储存在tomcat服务器上的:
这次可能用tomcat1处理此用户的请求,此次的session数据保存在tomcat1上;
下次可能使用tomcat2处理此用户的请求,tomcat2在本机上找不到此用户的session数据(因为储存在tomcat1上),而这次产生的session数据保存在tomcat2上,tomcat1上的session数据没有更新。
数据不同步是分布式系统(集群、微服务)都会遇到的问题。
Tomcat集群,tomcat之间要共享session等数据,常见的做法有2种:
- 使用redis,把要共享的数据都放到redis上(推荐)
- 使用tomcat的路由|广播
tomcat路由
conf/server.xml中配置:
<Engine name="Catalina" defaultHost="localhost" jvmRoute="jvm1">
<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>
<!--其它配置-->
</Engine>
指定jvmRoute,指定路由的实现类。
jvmRoute相当于组名,会把jvmRoute值相同的tomcat划为一组,比如要使用session,会在这组tomcat中找到SessionId为xxx的所有Session,组合成一个完整的session来使用。
属性名中有jvm,是因为tomcat是运行在jvm上的(依赖jdk),session等数据实际都是在jvm中,相当于是jvm的路由。
使用redis做数据共享
把session等数据保存到redis上,而非tomcat本地,要用时从redis上取出。
遍历一组tomcat节点很花时间,尤其是session钝化后需要从硬盘加载,很花时间,比起redis这种内存数据库,性能差太多。
不推荐使用tomcat路由,尽量使用redis做数据共享。
<Engine>常见的子元素
1、<Cluster />
tomcat路由时使用
2、<Realm>
Realm可以理解为包含用户、密码、角色的”数据库”。
Tomcat定义了多种Realm实现:JDBC Database Realm、DataSource Database Realm、JNDI Directory Realm、UserDatabase Realm等。
<Realm className="org.apache.catalina.realm.LockOutRealm"> <Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase"/> </Realm>
默认只配置了UserDatabaseRealm,使用从conf/tomcat-users.xml中加载的tomcat用户信息。
3、<Host>
一个<Host>即一个虚拟主机,比如www.chy.com,需要在DNS上注册才可以正常使用(绑定ip),不然只能使用本地的localhost(对应ip127.0.0.1)。
一个tomcat上可以设置多个host,比如www.a.com、www.b.com都在一个tomcat上,对应一个ip,这是可以的。
可以配置多个<Host>,也可以在tomcat控制台 -> Host Manager中添加虚拟主机。
默认只设置了一个虚拟主机:
<Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true"> <!-- <Valve className="org.apache.catalina.authenticator.SingleSignOn" /> --> <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" prefix="localhost_access_log." suffix=".txt" pattern="%h %l %u %t "%r" %s %b" /> </Host>
常用属性:
- appBase-web项目的部署目录,默认值webapps
- unpackWARs-如果appBase下有war包,是直接使用war包部署,还是先将war包解压,使用解压得到的文件夹来部署。
unpack即不打包,默认为true——先解压,使用解压得到的文件夹来部署。
- autoDeploy-是否开启自动部署,默认为true。
开启自动部署的效果:tomcat会监听appBase下的文件|文件夹变化,放进来一个web项目时会自动部署,修改已部署的项目中的文件时会自动同步(重新部署)
- startStopThreads-Tomcat启动|关闭时,此Host要使用几个线程来部署|卸载web应用。
默认值1,部署|卸载webapp很慢,可以使用多个线程并行部署|卸载,减少tomcat的启动|关闭所需的时间。
- name-Host的名字,即主机名,要对应域名
比如主机名是localhost,那就只能以http://localhost:8080/来访问,因为域名都要转换为ip,所以可以在地址栏输入对应的ip。
如果主机名是www.chy.com,那就要以http://www.chy.com:8080/来访问,需要在DNS上注册这个域名,将域名与ip绑定,才可以使用。
当然本地模拟的话,在host文件中加一行:
192.168.1.6 www.chy.com
把本机的ip加上去,开启tomcat,浏览器地址栏输入http://www.chy.com:8080也是可以的:
只能使用本机的实际ip,不能写127.0.01,因为127.0.0.1 <=> localhost是写死的,修改不了。
<Context>
一个<Context>即一个webapp的部署配置,一个<Host>中可以有多个<Context>。
<Context docBase="helloApp" path="/helloApp" debug="0" reloadable="false"/>
常用属性:
- docBase - 指定项目路径,相对于appBase,也可以使用绝对路径
- path - 指定该webapp的映射地址
比如映射为/test,就以http://ip|host:port/test来访问,/表示host的根目录。
默认为/war包名,或/部署的文件夹名。
- debug - 调试级别,值为0-9,数值越大,日志输出的调试信息越详细。
- reloadable-是否监控此webapp的/WEB-INF/classes/和/WEB-INF/lib的变化,检测到变化时,会重新部署此webapp,同步改变。
通常开发时设为true,方便调试;正式上线|发布则设为false,减轻服务器的负担、提高服务器性能。
默认为false。
- crossContext-是否将本webapp的session共享给同一host下的其它webapp,默认为false
Context代表一个webapp,crossContext即数据穿过当前webapp,共享给同一host下的其它webapp。
tomcat默认没有设置<Context />,里面的属性均使用默认值。
<Valve>
Valve可以理解为Tomcat的拦截器,可以用于Tomcat的日志、权限等,可嵌在Engine、Host、Context内使用。
<!-- <Valve className="org.apache.catalina.authenticator.SingleSignOn" /> --> <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" prefix="localhost_access_log" suffix=".txt" pattern="%h %l %u %t "%r" %s %b" />
默认注释掉了单点登录。
单点登录:登陆状态对同一host下的其它webapp共享。
使用AccessLogValve记录此host处理的所有的请求的日志,每天的日志记录到一个新的文件中,
指定了日志文件目录、日志文件名的前缀、后缀,pattern指定日志格式。
<Value>同样可以使用debug属性设置调试级别。
session超时设置
conf/web.xml,搜索session:
<!-- ==================== Default Session Configuration ================= --> <!-- You can set the default session timeout (in minutes) for all newly --> <!-- created sessions by modifying the value below. --> <session-config> <session-timeout>30</session-timeout> </session-config>
默认30min。
说明
Tomcat的操作手册即在webapps/docs,都是些html文档,可直接查看,也可启动tomcat,地址栏输入localhost:8080/docs查看。
tomcat的配置手册在webapps/docs/conf下。
也可以到tomcat官网查看文档。