Tomcat

Tomcat是最常用的Java部署容器,在我最初接触Java时就是主流,特点就是稳定.

与之类似还有个Jetty,用的不多就不涉及了.

安装

Ubuntu

安装:

apt install tomcat8  tomcat8-admin  tomcat8-docs tomcat8-examples
# 常用路径
/etc/tomcat8/server.xml
/etc/default/tomcat8
/var/lib/tomcat8/webapps/ROOT/index.html
/usr/share/tomcat8/bin   
/var/log/tomcat8 

服務:

# /etc/systemd/system/tomcat.service


[Unit]
Description=Apache Tomcat Web Application Container
After=network.target

[Service]
Type=forking

Environment=JAVA_HOME=/usr/java/default
Environment=CATALINA_PID=/opt/tomcat/temp/tomcat.pid
Environment=CATALINA_HOME=/opt/tomcat
Environment=CATALINA_BASE=/opt/tomcat
Environment='CATALINA_OPTS=-Xms512M -Xmx1024M -server -XX:+UseParallelGC'
Environment='JAVA_OPTS=-Djava.awt.headless=true -Djava.security.egd=file:/dev/./urandom'

ExecStart=/opt/tomcat/bin/startup.sh
ExecStop=/opt/tomcat/bin/shutdown.sh

User=tomcat
Group=tomcat
UMask=0007
RestartSec=10
Restart=always

[Install]
WantedBy=multi-user.target

CentOS

安装:

groupadd tomcat
useradd -s /bin/false -g tomcat -d /opt/tomcat tomcat
cd /opt/
wget http://mirrors.tuna.tsinghua.edu.cn/apache/tomcat/tomcat-8/v8.5.66/bin/apache-tomcat-8.5.66.tar.gz
sudo tar xvf apache-tomcat-8*tar.gz -C /opt/tomcat --strip-components=1
chown -hR tomcat:tomcat tomcat

服务:

# vi /etc/systemd/system/tomcat.service


# Systemd unit file for tomcat
[Unit]
Description=Apache Tomcat Web Application Container
After=syslog.target network.target

[Service]
Type=forking

Environment=JAVA_HOME=/usr/java/default
Environment=CATALINA_PID=/opt/tomcat/temp/tomcat.pid
Environment=CATALINA_HOME=/opt/tomcat
Environment=CATALINA_BASE=/opt/tomcat
Environment='CATALINA_OPTS=-Xms512M -Xmx2048M -server'

ExecStart=/opt/tomcat/bin/startup.sh
ExecStop=/bin/kill -15 $MAINPID

#User=tomcat
#Group=tomcat
#UMask=0007
RestartSec=10
Restart=always

[Install]
WantedBy=multi-user.target

服务管理:

# 加载服务
systemctl daemon-reload
# 启动
systemctl start tomcat

# 开机启动
systemctl enable tomcat

配置

常用配置

以最常用的HTTP Connector为例, 最关键的几个参数是:

  • maxThreads : 能同时处理的请求数, 默认200有些偏小。
  • acceptCount : 请求队列最大值,处理不过来就放到这个队列,队列满之后会拒绝请求. 默认100有些偏小.
  • maxConnections : 服务器接受并处理的最大连接数,超出后新连接会被阻塞.对于BIO连接器默认=maxThreads, NIO连接器默认10000.

Connector的实现主要是BIO,NIO,NIO2 其中BIO是大多数版本的默认实现,但是在最新版Tomcat8.5,已经不再支持BIO

开启HTTPS

关于SSL/TLS,建议使用Nginx反向代理配置而不使用Tomcat.

Tomcat开启TLS后,性能会有所下降(CPU占用更高).官方推荐使用APR,而不使用BIO或NIO(使用Java内置的安全组件JSSE)。

APR(Apache Portable Runtime)是Tomcat的Native Library,实现网络连接和随机数生成器.主要特点:

  • 支持Keep-Alive请求的非阻塞I/O
  • 使用OpenSSL 版本的TLS/SSL

NIO 配置

<Connector port="8443" 
    protocol="org.apache.coyote.http11.Http11NioProtocol"
    SSLEnabled="true" scheme="https" secure="true" 
    keystoreFile="/usr/local/jdk1.8.0_92/jre/lib/security/server.keystore" keystorePass="changeit" 
    clientAuth="false" sslProtocol="TLS" />

APR 配置

# CentOS
yum install epel-release
yum install tomcat-native.x86_64

# Ubuntu
apt-get install libtcnative-1

server.xml

<Connector port="8087" 
    protocol="org.apache.coyote.http11.Http11AprProtocol"
    SSLEnabled="true" scheme="https" secure="true"
    SSLCertificateFile="/usr/local/jdk1.8.0_92/jre/lib/security/server.crt" 
    SSLCertificateKeyFile= "/usr/local/jdk1.8.0_92/jre/lib/security/server.pem" 
    SSLVerifyClient="optional" SSLProtocol="all"  />

强制使用HTTPS

server.xml: redirectPort用于把http请求重定向到https端口.

注: 需要增加该HTTPS端口的配置项(见上面示例)

<Connector port="8080" protocol="HTTP/1.1"
               redirectPort="8443" />

web.xml: 可强制重定向http到https

<security-constraint>
    <user-data-constraint>
        <transport-guarantee>CONFIDENTIAL</transport-guarantee>
    </user-data-constraint>
</security-constraint>

注: transport-guarantee配置为NONE会关闭该配置.

关于参数调优

建议使用setenv.sh的方式调整参数,比如记录GC日志

    JAVA_OPTS="
    -Xmx6g
    -XX:+PrintGC
    -XX:+PrintGCDetails
    -XX:+PrintHeapAtGC
    -Xloggc:/usr/local/tomcat/logs/gc.log
    -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/usr/local/tomcat/logs/
    "

开启远程监控JMX

CATALINA_OPTS="
-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port=1616
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.authenticate=false
-Djava.rmi.server.hostname=10.120.1.99
"

开启目录列表

default servlet 负责处理静态资源和目录列表

    <init-param>
    <param-name>listings</param-name>
    <param-value>true</param-value>
    </init-param>

压缩日志

# vi /etc/logrotate.d/tomcat
/usr/local/tomcat/logs/catalina.out {
copytruncate
daily
rotate 5
dateext
compress
missingok
size 1024M
}

调试:

logrotate -d -f /etc/logrotate.d/tomcat

  • -d = 开启调试模式
  • -f = 强制循环日志

安全

隐藏出错时的具体版本号:

server.xml内的之前添加

<Valve className="org.apache.catalina.valves.ErrorReportValve"  showReport="false"  showServerInfo="false"/> 

其他

# 查看运行时参数
ps aux | grep catalina  # 或者
jinfo <tomcat_pid>
# 调试debug
set -x
# 使用pid
CATALINA_PID="$CATALINA_BASE/bin/catalina.pid"

AJP( Apache JServ Protocol)的特点是作为Web Server(Apache)和Servlet Container(Tomcat/JBoss)之间的反向代理, 使用二进制协议传输,没有解析开销.

资源链接