Tomcat 安装配置与优化

什么是 Tomcat

Tomcat 是 Java web 服务器中使用最广的中间件,jsp 必须要使用类似 Tomcat 这样的程序进行解析。

Tomcat是Apache 软件基金会(Apache Software Foundation)的Jakarta 项目中的一个核心项目,由Apache、Sun 和其他一些公司及个人共同开发而成。因为Tomcat 技术先进、性能稳定,而且免费,因而深受Java 爱好者的喜爱并得到了部分软件开发商的认可,成为目前比较流行的Web 应用服务器。 Tomcat 是一个轻量级应用服务器,在中小型系统和并发访问用户不是很多的场合下被普遍使用,是开发和调试JSP 程序的首选。对于一个初学者来说,可以这样认为,当在一台机器上配置好Apache 服务器,可利用它响应对HTML 页面的访问请求。实际上Tomcat 部分是Apache 服务器的扩展,但它是独立运行的,所以当你运行tomcat 时,它实际上作为一个与Apache 独立的进程单独运行的。

安装 Java

1.下载

wget -c http://file201503.oss-cn-shanghai.aliyuncs.com/ftp/jdk-8u151-linux-x64.tar.gz

2.解压后放到/usr/local/下

mv jdk1.8.0_151/ /usr/local/jdk18  

3.配置环境变量

vim /etc/profile  

输入

export JAVA_HOME=/usr/local/jdk18
export PATH=$JAVA_HOME/bin:$PATH
export CLASSPATH=.$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar 

保存后执行

source /etc/profile    

安装 Tomcat

1.打开官网下载

wget -c http://supergsego.com/apache/tomcat/tomcat-8/v8.5.29/bin/apache-tomcat-8.5.29.tar.gz

解压后复制3份分别为 Tomcat1 Tomcat2 Tomcat3

[root@centos ~]# cd /usr/local/tomcat
tomcat1/ tomcat2/ tomcat3/

分别修改3个目录下 conf 下的 server.xml 端口为 8080、8081、8082

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

启动 3 个 Tomcat

[root@centos bin]# ./catalina.sh start
Using CATALINA_BASE:   /usr/local/tomcat1
Using CATALINA_HOME:   /usr/local/tomcat1
Using CATALINA_TMPDIR: /usr/local/tomcat1/temp
Using JRE_HOME:        /usr/local/jdk18
Using CLASSPATH:       /usr/local/tomcat1/bin/bootstrap.jar:/usr/local/tomcat1/bin/tomcat-juli.jar
Tomcat started.

Tomcat 目录说明:

bin:二进制执行文件。里面最常用的文件是startup.bat,如果是 Linux 或 Mac 系统启动文件为 startup.sh。
conf:配置目录。里面最核心的文件是server.xml。可以在里面改端口号等。默认端口号是8080,也就是说,此端口号不能被其他应用程序占用。
lib:库文件。tomcat运行时需要的jar包所在的目录
logs:日志
temp:临时产生的文件,即缓存
webapps:web的应用程序。web应用放置到此目录下浏览器可以直接访问
work:编译以后的class文件。

Tomcat 自身配置域名和80端口访问

如果要使用80端口访问域名则配置

<Connector port="80" protocol="HTTP/1.1"
             connectionTimeout="20000"
             redirectPort="8443" />

         ……

<Host name="www.v5linux.com"  appBase="webapps"
          unpackWARs="true" autoDeploy="true">

      <!-- SingleSignOn valve, share authentication between web applications
           Documentation at: /docs/config/valve.html -->
      <!--
      <Valve className="org.apache.catalina.authenticator.SingleSignOn" />
      -->

      <!-- Access log processes all example.
           Documentation at: /docs/config/valve.html
           Note: The pattern used is equivalent to using pattern="common" -->
      <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
             prefix="localhost_access_log" suffix=".txt"
             pattern="%h %l %u %t &quot;%r&quot; %s %b" />
       <Context docBase="/data/" path="" debug="0"  reloadable="true"/>
    </Host>

配置 nginx 代理多Tomcat 访问

在 nginx http 段加入

http {
    upstream tomcatcluster {
    ip_hash;
        server 127.0.0.1:8080;
        server 127.0.0.1:8081;
        server 127.0.0.1:8082;
   }
   ……

在 server 段配置,这里我配置了80端口跳443,并且加了 ssl 证书

    server {
    listen  80;
    server_name _;
    server_name www.v5linux.com v5linux.com;
    if ($request_method !~ ^(GET|HEAD|POST)$ ) {
            return        444;
        }
    rewrite ^(.*)$  https://www.v5linux.com$1 permanent;
}
    server {
        listen       443;
        server_name  www.v5linux.com;
        ssl on;
        ssl_certificate //usr/local/nginx/ssl/v5linux/fullchain.cer;
        ssl_certificate_key /usr/local/nginx/ssl/v5linux/v5linux.key;
        ssl_ciphers                EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;
        ssl_prefer_server_ciphers  on;
        ssl_protocols              TLSv1.2;
        ssl_session_cache          shared:SSL:50m;
        ssl_session_timeout        1d;
        ssl_session_tickets        on;
        resolver                   114.114.114.114 valid=300s;
        resolver_timeout           10s;

        access_log  logs/host.access.log  main;

        location / {
            root   html;
            index  index.html index.htm;
            proxy_pass http://tomcatcluster;
        }

    }

开放防火墙

iptables -A INPUT -p tcp --dport 443 -j ACCEPT

做好解析,并确认

# dig www.v5linux.com

; <<>> DiG 9.10.6 <<>> www.v5linux.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 62933
;; flags: qr aa rd ra ad; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;www.v5linux.com.        IN    A

;; ANSWER SECTION:
www.v5linux.com.    0    IN    A    59.111.92.121

;; Query time: 12 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Wed Apr 04 14:00:14 CST 2018
;; MSG SIZE  rcvd: 49

浏览器访问

发现没有问题

Tomcat 自身配 ssl 证书,可以在 server.xml 中这段进行配置

<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"
            maxThreads="150" SSLEnabled="true">
     <SSLHostConfig>
         <Certificate certificateKeystoreFile="conf/localhost-rsa.jks"
                      type="RSA" />
     </SSLHostConfig>
 </Connector>

Tomcat 默认的路径是在 Tomcat 的目录下的 webapps ,可以在配置文件中修改

<Host name="localhost"  appBase="webapps"
          unpackWARs="true" autoDeploy="true">

我们将其修改为

<Context docBase="/data/" path="" debug="0"  reloadable="true"/>    

创建 data 目录

mkdir /data/

然后新建一个 jsp 文件

 <%@ page contentType="text/html;charset=UTF-8" %>
<%
out.print("test");
%> 

访问

优化

  • java.lang.OutOfMemoryError: Java heap space异常
    表示堆内存空间满了,如果不是程序逻辑的bug,可能是因为项目中引用的jar比较多,导到内存溢出。JVM默认堆的最小使用内存为物理内存的1/64,最大使用内存为物理内存的1/4,如8G的物理内存,JVM默认堆的最小和最大内存分别为128m和2048m。通过调整JVM的-Xms(初始内存)和-Xmx(最大内存)两个参数加大内存使用限制。
  • java.lang.OutOfMemoryError: PermGen space异常
    表示静态内存区满了,通常是由于加载的类过多导致。jdk8以下版本通过修改JVM的-XX:PermSize和-XX:MaxPermSize两个参数,限制静态区最小和最大内存范围。jdk8改变了内存模型,将类定义存放到了元数据(MetaspaceSize)空间,而元数据空间是与堆空间共享同一块内存区域的,所以在JDK8以后版本不会存在PermGen space异常了,故不用设置此参数。
  • java.lang.StackOverflowError异常
    表示栈内存溢出。通常是由于死循环、无限递归导致。

修改Tomcat的内存配置,打开$TOMCAT_HOME/bin/catalina.sh文件(Windows系统是catalina.bat文件),大楖在250行左右,在JAVA_OPTS参数上添加内存参数设置即可。完整的JVM参数设置如下所示:

JAVA_OPTS="$JAVA_OPTS -server -Xms2048m -Xmx2048m -XX:PermSize=128m -XX:MaxPermSize=256 -Djava.awt.headless=true"

-server参数:表示以服务模式启动,启动速度会稍微慢一点,但性能会高很多。不加这个参数,默认是以客户端模式启动。
java.awt.headless=true参数:与图形操作有关,适用于linux系统。如生成验证码,含义是当前使用的是没有安装图安装图形界面的服务器,应用中如果获取系统显示有关参数会抛异常,可通过jmap -heap proccess_id查看设置是否成功。

修改后

并发配置优化

主要配置Tomcat能处理的请求数,当一个进程的线程数超过500个的话,那么这个进程的运行效率就很低了。表面上看线程越多处理的请求越多,其实过多的线程会占用CPU在不同线程之间切换的资源,导致CPU在每个线程上处理的时间片极期有限,反而会降低服务器的响应性能。

<Connector port="8080" protocol="org.apache.coyote.http11.Http11AprProtocol"
               connectionTimeout="20000"
               redirectPort="8443" 

                maxThreads="500"
                minSpareThreads="100"
                maxSpareThreads="200"
                acceptCount="200"
                maxIdleTime="30000"
                enableLookups="false"
               />

Tomcat的并发请求处理数量=maxThreads + acceptCount

maxThreads:最大能接受的请求数,默认为200
minSpareThreads:最少备用线程数,默认初始化,默认为25
maxSpareThreads:最多备用线程数,一旦创建的线程超过这个值,Tomcat就会关闭不再需要的socket线程
acceptCount:等待处理的请求队列,默认为100,超过队列长度,服务器则拒绝客户端请求,直接返回403
maxIdleTime:如果一个线程在30秒以内没有活跃,则终止运行并从线程池中移除。除非线程池数量小于或等于minSpareThreads数量。默认值是1分钟
enableLookups:如果为true,调用request.getRemoteHost会执行DNS反查,反向解析IP对应的域名或主机,效率较低,建议设为false。

更多参数设置,请参考Tomcat官方文档:http://tomcat.apache.org/tomcat-8.0-doc/config/http.html