Tomcat是一个免费的开源的Serlvet容器,它是Apache基金会的Jakarta项目中的一个核心项目,由Apache、Sun和其它一些公司及个人共同开发而成。由于有了Sun的参与和支持,最新的Servlet和Jsp规范总能在 Tomcat中得到体现。
尽管Tomcat也可以作为独立的Java Web服务器,但在对静态资源(HTML、图像文件等)的处理速度,Web服务器管理等方面都不如Apache、IIS服务器等其他专业的HTTP服务器,因此在实际应用中,常常把Tomcat与其他的HTTP服务器集成使用。对于不支持Servlet/JSP的HTTP服务器,可以通过Tomcat服务器来运行Servlet/JSP组件。
当Tomcat与其他HTTP服务器集成时,Tomcat服务器的工作模式通常为进程外的Servlet容器,Tomcat服务器与其他HTTP服务器之间通过专门的插件来通信。
$CATALINA_HOME Tomcat安裝目录下面有
Tomcat服务器由一系列可配置组件构成,其中核心组件是Catalina Servlet容器,它是其他所有Tomcat组件的顶层容器。在server.xml配置文件中,各组件之间关系如下
<Server>................................Server层
<Service>............................Service层
<Connector/>
<Engine>..........................Engine层
<Host>.........................Host层
<Context/>...............Context层
</Host>
</Engine>
</Service>
<Server>
Server层
对应Server组件,表示整个Tomcat(Catalina Servlet容器),它处于Tomcat顶层,可以包含一个或多个Service层。
Service层
对应Service组件,是Server层中的一个逻辑功能层,包含一个Engine层,以及一个或多个Connector,Service组件将一个或多个Connector组件绑定到Engine层上,Connector组件侦听端口,获得用户请求,并将请求转发到Engine层处理,同时把处理结果转发给用户,从而实现一个特定的功能。
Engine层
对应Engine组件,负责请求分发处理,可以连接多个Connector,它从Connector接收请求后,解析出可以完成用户请求的URL,根据URL可以把请求匹配到正确的Host上,当Host处理完用户请求后,Engine层把结果返回给适合连接器,再由连接器传输给用户。
Host层
对应Host组件,表示一个虚拟主机,一个Engine层可以包含多个Host层,每个Host层可以包含一个或多个Context层,对应不同的web应用。
Context层
对应Context组件,代表某个虚拟主机上的实际目录或一个WAR,即单个Web应用程序,它运行在特定的虚拟主机中,使用最为频繁。一个Host层包含多个Context层,每一个Context都有唯一的路径,Host层接到请求后,根据用户请求的URL,将请求定位到Context层。
server.xml:Tomcat中最重要的配置文件,定义了tomcat的体系结构,包括连接器端口、连接数、集群、虚拟目录、访问日志等的设置。
context.xml:全局context的配置文件,包括JNDI等信息的配置。
tocmat-users.xml:Tocmat管理员身份的配置文件,关键是设置管理员账号的密码。
logging.properties:Tocmat日志配置文件,可以修改默认的Tocmat日志路径和名称。
根据系统物理内存大小合理设置下列五个参数catalina.sh/catalina.bat
-server -Xms512m -Xmx512m -XX:PermSize=128m -XX:MaxPermSize=128m
一般情况下,设置-Xms=-Xmx、-XX:PermSize=-XX:MaxPermSize,正式服务器必须设置以上参数,以尽可能压榨服务器性能。相关参数取值需要根据实际情况考虑,不要超过(物理内存-其他程序内存)的80%即可。
没有特殊理由,尽量不要对上述五个参数外的其他JVM参数进行设置:
无法保证各种操作系统平台的可移植性
过度干涉JVM内存管理会导致无法预料的后果
如果在Windows平台上将解压版的Tomcat安装为服务,可以通过修改批处理文件$CATALINA_HOME/bin/service.bat对JVM参数进行调整。
Tomcat日志配置
Tomcat日志信息包括访问日志和运行日志。
访问日志用于对用户访问系统的行为进行跟踪记录,主要记录用户访问的时间、对应的IP地址、访问的资料等信息。记录访问日志主要是基于对系统安全的考虑,对系统中一些重要、敏感信息的资料访问历史进行记录,便于对资源的访问历史进行追踪,对于敏感信息未经授权访问等进行事后追查有一定帮助。但记录访问日志会对服务器性能产生一定的影响,在生产系统中需要慎用。
运行日志主要记录程序运行的一些信息,其中的异常错误信息可以为我们定位错误。从6.0版本开始,Tomcat的日志接口采用是对Apache Commons Logging日志接口进行独立封装,缺省配置下,该日志接口采用硬编码使用java.util.logging日志框架。
由于Tomcat发布版本中独立封装的Apache Commons Logging接口并没有对接口完全实现,如果要选择不同的日志框架就需要将该日志接口替换为完全实现的版本。
缺省配置下,Tomcat是不记录访问日志的,可以通过如下配置允许Tomcat记录访问日志:
修改$CATALINA_HOME/server.xml,在Host标签下,找到如下配置信息,去掉两端的注释就会启用访问日志记录功能:
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
prefix="localhost_access_log." suffix=".txt" pattern="common" resolveHosts="false"/>
通过对pattern项的修改,可以改变日志输出的内容。该项值可以为: common 与 combined,对应的日志输出内容如下所示:
common: %h %l %u %t %r %s %b
combined: %h %l %u %t %r %s %b %{Referer}i %{User-Agent}i
pattern 也可以根据需要自由组合, 例如 pattern="%h %l",对 于各 fields 字段的含义请参照Tomcat官方文档。
在不同的环境下,需要设置不同的日志级别,在生产环境中,为了提高效率和稳定性,一般会将日志级别设置为相对较高的级别,而开发环境中为了跟踪程序流程,可以将日志级别调整为较低的级别。不同日志框架有不同的日志级别,常用的日志框架对应级别如下:
Java.util.logging对应的日志级别由高到低分别为:
severe > warning > info > config > fine > finer > finest
org.apache.log4j对应的日志级别由高到低分别为:
fatal > error > warn > info > debug > trace
在缺省配置下,Tomcat采用Java.util.logging日志框架,对应的配置文件为$CATALINA_HOME/ logging.properties,常用的日志级别设定方法如下:
设置catalina日志的级别为:FINE
1catalina.org.apache.juli.FileHandler.level = FINE
禁用catalina日志的输出:
1catalina.org.apache.juli.FileHandler.level = OFF
设置catalina所有的日志消息均输出:
1catalina.org.apache.juli.FileHandler.level = ALL
Log4j是目前应用最广的日志框架,可以使用Log4j替换Tomcat缺省采用的java.util.logging日志框架,步骤如下:
创建log4j配置文件log4j.properties ,保存在$CATALINA_HOME/lib 下。
从Apache官网Log4J项目下载Log4J(1.2版本以后)。
从Apache官网Tomcat项目下载tomcat-juli.jar和tomcat-juli-adapters.jar。
复制log4j.jar、tomcat-juli-adapters.jar到$CATALINA_HOME/lib下。
用tomcat-juli.jar覆盖$CATALINA_HOME/bin下的同名文件。
删除Tomcat的缺省日志配置文件$CATALINA_HOME/conf/ logging.properties,以避免生成一些冗余的空日志文件。
缺省情况下,如果URL当中包含有非英文字符,需要通过在程序对URL进行转码处理,否则URL中的非英文字符无法保证正确解析。在无特殊要求的情况下,需要将URL编码设置为和项目统一的编码格式,目前公司大部分项目都统一采用UTF-8字符编码方式,示例如下:
<Connector port="8087" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443"
URIEncoding="utf-8" />
JVM内存溢出(OOM),分为堆内存溢出和PermGen区内存溢出:
java.lang.OutOfMemoryError: PermGen space
PermGen space(Permanent Generation space),是指内存的永久保存区域,主要用于存放Class和Meta信息的,Class在被Loader时就会被放到PermGen space中, 它和存放类实例(Instance)的Heap区域不同,GC(Garbage Collection)不会在主程序运行期对其进行清理,所以如果应用中有很多CLASS的话,就很可能出现PermGen space错误。如果加载的Class超过MaxPermSize,就会抛出该异常,可以通过调整MaxPermSize进行解决。
java.lang.OutOfMemoryError: Java heap space
JVM堆是指java程序运行过程中JVM可以调配使用的内存空间。JVM在启动的时候会自动设置Heap size的值,其初始空间(-Xms)是物理内存的1/64,最大空间(-Xmx)是物理内存的1/4。可以利用JVM提供的-Xmn -Xms -Xmx等选项可进行设置。Heap size 的大小是Young Generation 和Tenured Generaion 之和。在JVM中如果98%的时间是用于GC且可用的Heap size 不足2%的时候将抛出此异常信息。
JDK安装及JAVA_HOME设置
启动不成功,没有日志,一般是JDK安装不正确或没有设置环境变量。
大量用户访问时浏览器没有响应
并发线程数设置太小,调整$CATALINA/conf/server.xml中连接器对应的请求处理线程数。