[TOC]
修订控制页
版本 |修订日期 |修订人 |修订摘要
—|—|—|—
1.0| 2019年9月10日 09点00分 |WeiyiGeek |初稿
为了更好的指导部署Tomcat应用容器,保证服务的安全稳定高性能的运行,需要对其进行加固和优化; 本次进行Tomcat容器调优加固主要从以下几个部分:
内核参数优化性能参数优化安全加固配置本文档仅供内部使用,禁止外传,帮助研发人员,运维人员对系统长期稳定的运行提供技术文档参考。
1) 项目经理 2) 开发人员 3) 测试人员 4) 运维人员 5) 相关领导
Apache Tomcat是美国Apache软件基金会的一款轻量级Web应用服务器,该程序实现了对Servlet和JSP的支持。 目前是Apache开源软件组织的一个软件项目它的官网 :http://tomcat.apache.org , 在中小型系统和并发访问用户不是很多的场合下被普遍使用,是开发和调试 JSP 程序的首选,默认端口8080。
Tomcat8配置帮助文档: http://tomcat.apache.org/tomcat-8.0-doc/config/ Security Manage: http://tomcat.apache.org/tomcat-8.0-doc/security-manager-howto.html
Tomcat初始目录结构
/usr/local/tomcat #主目录即安装的目录 ├── bin #存放启动和关闭Tomcat的脚本文件 ├── conf #存放Tomcat服务器的各种配置文件(后面单介绍) ├── lib #存放tomcat服务器支撑的jar包 ├── logs #存放Tomcat的日志文件 ├── temp #存放Tomcat运行时产生的临时文件 ├── webapps #web应用虽在目录,即供外界访问的web资源的存放目录,就是Web发布目录 │ ├── docs #帮助文档目录 │ ├── examples #Servlet and JSP Examples案例目录 │ ├── host-manager #主机管理目录 │ ├── manager #应用程序管理目录 │ └── ROOT #应用程序放置地址 └── work #Tomcat的工作目录,存放jsp编译后产生的class文件
Tomcat全局配置目录结构:
[root@master conf]# tree ├── catalina.policy #权限控制配置文件 ├── catalina.properties #Tomcat属性配置文件 ├── context.xml #上下文配置文件(selinux) ├── jaspic-providers.xml ├── jaspic-providers.xsd ├── logging.properties #日志log相关配置文件 ├── server.xml #主配置文件(如修改监听端口,开启关闭额外的服务,设置网站根目录,虚拟主机,开启https等功能) ├── tomcat-users.xml #manager-gui管理用户配置文件(Tomcat安装后生成的管理界面,该文件可开启访问) ├── tomcat-users.xsd └── web.xml #Tomcat的servlet,servlet-mapping,filter,MIME等相关配置
Tomcat的JavaWeb应用的组成结构:
mail--- #-Web应用所在目录 |---- #html、jsp、css、js等文件,根目录下的文件外界可以直接访问 |---- #WEB-INF目录 (应用配置文件存放) |---------classes目录 #(java类) |---------lib目录 #(java类运行所需的jar包) |---------conf目录 #(数据库以及其他配置文件存放目录) |---------web.xml #(web应用的配置文件) #注意:WEB-INF 这个目录下的文件外界无法直接访问,由web服务器负责调用
Tomcat默认开发的端口介绍:
8005:用于SHUTDOWN指令来关闭Tomcat时使用;8009:用于Apache连接Tomcat时候专用端口采用AJP协议;8080:用于HTTP协议远程访问端口即Web页面访问端口;需要进行调整的内核参数
cat >> /etc/sysctl.conf << EOF # cat /proc/sys/net/core/netdev_max_backlog # 默认值:1000 # 作用:网卡设备将请求放入队列的长度 net.core.netdev_max_backlog = 32768 # cat /proc/sys/net/core/somaxconn # 默认值:128 # 作用:已经成功建立连接的套接字将要进入队列的长度 net.core.somaxconn = 32768 # cat /proc/sys/net/core/rmem_default # 默认值:212992 # 作用:默认的TCP数据接收窗口大小(字节) net.core.rmem_default = 8388608 # cat /proc/sys/net/core/wmem_default # 默认值:212992 # 作用:默认的TCP数据发送窗口大小(字节) net.core.wmem_default = 8388608 # cat /proc/sys/net/core/rmem_max # 默认值:212992 # 作用:最大的TCP数据接收窗口大小(字节) net.core.rmem_max = 16777216 # cat /proc/sys/net/core/wmem_max # 默认值:212992 # 作用:最大的TCP数据发送窗口大小(字节) net.core.wmem_max = 16777216 # cat /proc/sys/net/ipv4/ip_local_port_range # 默认值:32768 61000 # 作用:可用端口的范围 net.ipv4.ip_local_port_range = 1024 65535 # cat /proc/sys/net/ipv4/route/gc_timeout # 默认值 300 # 作用:路由缓存刷新频率,当一个路由失败后多长时间跳到另一个路由 net.ipv4.route.gc_timeout = 100 # cat /proc/sys/net/ipv4/tcp_fin_timeout # 默认 60 # 作用:表示如果套接字由本端要求关闭,这个参数决定了它保持在FIN-WAIT-2状态的时间 net.ipv4.tcp_fin_timeout = 30 # cat /proc/sys/net/ipv4/tcp_keepalive_time # 默认值:7200 # 作用:间隔多久发送1次keepalive探测包 net.ipv4.tcp_keepalive_time = 1200 # cat /proc/sys/net/ipv4/tcp_timestamps # 默认值:1 # 作用:TCP时间戳,时间戳必须要开启,否则下面的 TIME_WAIT 重用和快速回收无效 net.ipv4.tcp_timestamps = 1 # cat /proc/sys/net/ipv4/tcp_tw_recycle # 默认值:0 # 作用:表示开启TCP连接中TIME-WAIT sockets的快速回收,默认为0,表示关闭。 net.ipv4.tcp_tw_recycle = 1 ######################## cat /proc/sys/net/ipv4/tcp_tw_reuse # 默认值:0 # 作用:针对 TIME-WAIT,做为客户端可以启用(例如,作为nginx-proxy前端代理,要访问后端的服务) net.ipv4.tcp_tw_reuse = 1 # cat /proc/sys/net/ipv4/tcp_syn_retries # 默认值 2 # 作用:在内核放弃建立连接之前发送SYN包的数量。 net.ipv4.tcp_syn_retries = 1 # cat /proc/sys/net/ipv4/tcp_synack_retries # 默认值 2 # 作用:为了打开对端的连接,内核需要发送一个SYN并附带一个回应前面一个SYN的ACK。也就是所谓三次握手中的第二次握手。这个设置决定了内核放弃连接之前发送SYN+ACK包的数量。 net.ipv4.tcp_synack_retries = 1 # cat /proc/sys/net/ipv4/tcp_mem #确定 TCP 栈应该如何反映内存使用;每个值的单位都是内存页(通常是 4KB)。 #第一个值是内存使用的下限。 #第二个值是内存压力模式开始对缓冲区使用应用压力的上限。 #第三个值是内存上限。在这个层次上可以将报文丢弃,从而减少对内存的使用。对于较大的 BDP 可以增大这些值(但是要记住,其单位是内存页,而不是字节)。 net.ipv4.tcp_mem = 94500000 915000000 927000000 # cat /proc/sys/net/ipv4/tcp_max_orphans # 默认值 16384 # 作用:系统中最多有多少个TCP套接字不被关联到任何一个用户文件句柄上。如果超过这个数字,孤儿连接将即刻被复位并打印出警告信息。这个限制仅仅是为了防止简单 的DoS攻击,你绝对不能过分依靠它或者人为地减小这个值,更应该增加这个值(如果增加了内存之后)。 net.ipv4.tcp_max_orphans = 3276800 # cat /proc/sys/net/ipv4/tcp_max_syn_backlog # 默认值:128 # 作用:增大SYN队列的长度,容纳更多连接 net.ipv4.tcp_max_syn_backlog = 65535 EOF #执行使内核参数生效 sysctl -p
描述: 由于Tomcat的运行依赖于JVM,从虚拟机的角度我们把Tomcat的调整分为外部环境调优和自身调优两类来描述。
主要调整Tomcat运行环境的操作系统参数和运行Tomcat的java虚拟机参数。
Tomcat需要依赖Java虚拟机运行,根据客户选用的主机的操作系统选择对应的JDK的版本建议使用最新的版本。 Tomcat的使用内存配置实质上是JVM的内存配置编辑 catalina.[sh / bat] 配置文件,注意这里区分Windows和Linux;
jvm 优化是我们要去调配置、调代码,需要充分利用JVM底层的内容进行设置, 注意整个堆heap大小 = 年轻代大小 + 年老代大小 + 持久代大小 之和。
(1) 尽可能将对象预留在新生代,减少老年代GC的次数(通常老年回收起来比较慢)(2) 实际工作中,通常将堆的初始值和最大值设置相等,这样可以减少程序运行时进行的垃圾回收次数和空间扩展,从而提高程序性能。此值可以设置与-Xmx相同,以避免每次垃圾回收完成后JVM重新分配内存。(3) 年轻代:刚创建完对象放到里面去不用时等待jvm移除(可根据创建时间)。(4) 年老代:当空间不够时则将创建最早的对象挪过去。当又需要用到这个对象时,又将其挪入年轻但,挪来挪去影响效率。JVM调优之设置Java虚拟机运行生产环境参数配置:
参数 | 描述 | 备注 |
---|---|---|
-server | Server 模式启动应用慢但是极大程度提高运行性能,特别是在稳定期过后。 -client | Cliet 模式启动应用快。
内存调优 | 描述说明 | 备注 |
---|---|---|
-Xms2g | 堆的初始可用内存大小,单位 m、g 。如 -Xms2g -Xmx2g | 堆的最大可用内存大小,单位 m、g 。如 -Xmx2g (设置与Xms相同的内存大小 , 为减少程序运行时进行的垃圾回收次数和空间扩展) -Xmn256m | 设置年轻代内存大小,单位 m、g 。 如 -Xmn256m (此值对系统性能影响较大,推荐配置为整个堆的 3/8 或 1/4,一般在增大年轻代内存后,也会将会减小年老代大小。) -Xss128k | 设置每个线程的栈Stack大小,单位 m、g 。如 -Xss128k (越大我们能递归调用的方法数量越多,但是空间越大创建时间越长)。 每个线程栈大小为1M以前每个线程栈大小为256K, 更具应用的线程所需内存大小进行调整, 在相同物理内存下,减小这个值能生成更多的线程。 但是操作系统对一个进程内的线程数还是有限制的不能无限生成,经验值在3000~5000左右可以在Linux内核中进行配置。 -XX:NewRatio=4 | 设置年轻代(包括Eden和两个Survivor区)与年老代的比值(除去持久代)。如此时则年轻代与年老代所占比值为1:4, 年轻代占整个堆栈的 1/5。 -XX:SurvivorRatio=4 | 设置年轻代中Eden区与Survivor区的大小比值。如Eden区与两个Survivor区的比值为4:2, 一个Survivor区占整个年轻代的1/6。 -XX:PermSize=16m | 设置持久代大小为16m, 持久代一般固定的内存大小为64m。 (越大加载的类阅越多) | support was removed in 8.0 -XX:MaxPermSize=16m | 设置最大持久代大小为16m, 默认是物理内存的1/4最大1024m。| support was removed in 8.0 -XX:MaxTenuringThreshold=0 | 设置垃圾最大年龄存活。 如果设置为0的话则年轻代对象不经过Survivor区,直接进入年老代, 对于年老代比较多的应用可以提高效率。 如果将此值设置为一个较大值,则年轻代对象会在Survivor区进行多次复制,这样可以增加对象再年轻代的存活时间,增加在年轻代即被回收的概论。
垃圾回收策略调优
描述: 我们都知道Java虚拟机都有默认的垃圾回收机制,但是不同的垃圾回收机制的效率是不同的,正是因为这点我们才经常对Java虚拟机的垃圾回收策略进行相应的调整。
Tips : Java虚拟机的垃圾回收策略一般分为串行收集器、并行收集器和并发收集器。
垃圾回收策略之串行收集器调优 | 描述说明 | 备注 |
---|---|---|
-XX:+UseSerialGc | 代表垃圾回收策略为串行收集器,即在整个扫描和复制过程采用单线程的方式来进行,适用于单CPU、新生代空间较小及对暂停时间要求不是非常高的应用上,是client级别默认的GC方式,主要在JDK1.5之前的垃圾回收方式。 | |
垃圾回收策略之并行收集器调优 | 描述说明 | 备注 |
---|---|---|
-XX:+UseParallelGC | 代表垃圾回收策略为并行收集器(吞吐量优先),即在整个扫描和复制过程采用多线程的方式来进行,适用于多CPU、对暂停时间要求较短的应用上,是server级别默认采用的GC方式。此配置仅对年轻代有效。该配置只能让年轻代使用并发收集,而年老代仍旧使用串行收集。| | -XX:ParallelGCThreads=4 | 配置并行收集器(Gc)的线程数,即:同时多少个线程一起进行垃圾回收。此值最好配置与处理器数目相等。 | | -XX:+UseParallelGCThreads=8 | 并行收集器线程数同时有多少个线程进行垃圾回收一般与CPU数量相等 | support was removed in 8.0 -XX:+UseParallelOldGC | 配置年老代垃圾收集方式为并行收集, JDK6.0支持对年老代并行收集。| | -XX:MaxGCPauseMillis=100 | 设置每次年轻代垃圾回收的最长时间,如果无法满足此时间,JVM会自动调整年轻代大小,以满足此值。| | -XX:+UseAdaptiveSizePolicy | 设置此选项后,并行收集器会自动选择年轻代区大小和相应的Survivor区比例,以达到目标系统规定的最低相应时间或者收集频率等,此值建议使用并行收集器时一直打开。 | |
垃圾回收策略之并发收集器调优 | 描述说明 | 备注 |
---|---|---|
-XX:+UseConcMarkSweepGC | 代表垃圾回收策略为并发收集器 |
垃圾回收策略之其它策略 | 描述说明 | 备注 |
---|---|---|
-XX:PrintGC | 每次触发GC的时候打印相关日志 | | -XX:+PrintGCDetails | 更详细的GC日志 | | -XX:+HeapDumpOnOutOfMemoryError| 堆异常报错输出 | | -XX:HeapDumpPath=path | 设置在dump heap时将文件dump到哪里。默认是当前目录下 java_pidpid.hprof这样形式的文件。| | -XX:+UseCMSCompactAtFullCollection | 开启内存空间压缩和整理,防止过多内存碎片 | tomcat 8.0 报警告 Headless=true | windows系统可不用设置,适用于Linux系统与图形操作有关,如生成验证码含义是当前的是无显示器的服务器,应用中如果获取系统显示有关的参数会抛出异常 || -Dfile.encoding=UTF-8 |设置字符集避免日志中出现乱码 | | -Dsun.jnu.encoding=UTF-8 | 设置字符集避免日志中出现乱码 || -Duser.timezone=GMT+08 |时区设置 ||
Tomcat 默认可以使用的内存为128MB,在较大型的应用项目中内存是不够的所以需要调大,一般设置初始化内存为256MB,可以使用的最大内存为512MB。
#Linux# $vim /usr/local/tomcat8/bin/catalina.sh #在OS specific support. $var _must_ be set to either true or false.110行下面添加 JAVA_OPTS="-server -Xms1024m -Xmx1024m -Xmn256m -XX:NewRatio=4 -XX:SurvivorRatio=4 -XX:+UseParallelGC -XX:ParallelGCThreads=4 -XX:+UseParallelOldGC -XX:+UseParallelOldGC " #Windows# $vim /usr/local/tomcat8/bin/catalina.bat #在/bin目录下的catalina.bat可以直接通过Tomcat设置JVM内存参数 set "JAVA_OPTS=%JAVA_OPT% -server -Xms2048m -Xmx2048m -XX:PermSize=256m -XX:MaxPermSize=512m -Djava.awt.headless=true"
WeiyiGeek.
java 8开始PermSize被MetaspaceSize代替,MetaspaceSize共享heap不会再有java.lang.OutOfMemoryError:PermGen space可以不设置java8 开始已经移除MaxPermSize/UseParallelGCThreads=8Java 提供的垃圾回收机制虚拟机的堆大小决定了虚拟机花费在收集垃圾上的时间和频度并且收集垃圾可以接受的速度与应用有关如果堆(heap)的空间很大,那么完全垃圾收集(FULL GC)就会很慢,但是频度会降低。如果在客户系统中把堆的大小和内存的需要一致,完全收集就很快,但是会更加频繁。推荐把-Xms设置为应用所需的最小值,这样会产生高效的垃圾回收。
描述: 虽然tomcat也可以作web服务器但其处理静态html的速度比不上Nginx服务,并且为了更好的进行设置负载均衡,还是得和Nginx进行联用;
因此我们可以把 Nginx 和 Tomcat 集成起来, 将html与jsp的功能部分进行明确分工, 让tomcat只处理jsp部分,或者也可以由其它的由 apache, IIS 等这些 web服务器处理,由此大大节省了tomcat有限的工作线程。
禁用DNS查询
描述: 消除DNS查询对性能的影响我们可以关闭DNS查询优化: enableLookups="false"结果: 节省了网络带宽、查询时间和内存,而且更小的流量会使日志数据也会变得更少,显而易见也节省了硬盘空间调整线程数(需要根据压力测试进行调整)
描述: 可通过应用程序的连接器(Connector)进行性能控制的参数是创建的处理请求的线程数。在Java中线程是程序运行时的路径,是在一个程序中与其它控制线程无关的、能够独立运行的代码段。但是应防止流量不可控制(或者恶意的服务攻击),从而导致超出了虚拟机使用内存的大小;web server允许的最大连接数还受制于操作系统的内核参数设置,通常Windows是2000个左右,Linux是1000个左右。优化: 修改 minProcessors 和maxProcessors 的值来控制线程数结果: 它们共享相同的地址空间。多线程帮助程序员写出CPU最大利用率的高效程序,使空闲时间保持最低,从而接受更多的请求。NIO 配置
描述:NIO (No-blocking I/O)从JDK 1.4起,NIO API作为一个基于缓冲区,并能提供非阻塞I/O操作的API被引入[LD6];TOMCAT可以支持高并发的企业级应用,配置良好的tomcat都会使用APR(Apache Portable Runtime),APR是Apache HTTP Server2.x的核心,它是高度可移植的本地库,它使用高性能的UXIN I/O操作,低性能的java io操作。优化: protocol="org.apache.coyote.http11.Http11NioProtocol"结果: NIO使用单线程(单个CPU)或者只使用少量的多线程(多CPU)来接受Socket,而由线程池来处理堵塞在pipe或者队列里的请求。只要OS可以接受TCP的连接,web服务器就可以处理该请求。大大提高了web服务器的可伸缩性。ARP配置(推荐方式-但是需要安装额外的包):
描述: Tomcat APR 模式也是 Tomcat 在高并发下的首选运行模式优化: protocol="org.apache.coyote.http11.Http11AprProtocol"结果: 调用 httpd 核心链接库来读取或文件传输,从而提高 tomcat 对静态文件的处理性能Connector 属性 | 说明 | 值 |
---|---|---|
port|Tomcat启动监听端口| Default 8080 | protocol|Tomcat的3种运行状态协议| Default bio HTTP/1.1| acceptCount|监听端口队列最大数,满了之后客户请求会被拒绝(不能小于maxSpareThreads)| Default 100,建议设置1000| maxThreads|当前可以同时处理的最大用户访问数最大连接数配置(并发能力)| Default 200 ,建议设置1000| minSpareThreads| Tomcat初始化时创建的socket线程数,线程的最小运行数目 | Default 10 ,建议设置1000| maxSpareThreads| Tomcat连接器的最大空闲socket线程数,一旦创建的线程超过这个值将会关闭socket| 建议设置1000| minProcessors| 服务器创建时的最小处理线程数 | 建议设置 100| maxProcessors| 服务器同时最大处理线程数 | 建议设置 1000| enableLookups | 支持域名解析可把ip地址解析为主机名 | 建议设置false 关闭DNS反向查询| compression | 是否打开压缩功能 | on| compressionMinSize | 压缩的最小字节 | 2048| compressableMimeType | 压缩的MImeType类型 | text/html,text/xml,text/javascript,text/css,text/plain| connectionTimeout | 代表连接超时时间,单位为毫秒 | 默认值为60000。通常情况下设置为30000| disableUploadTimeout | 标志允许servlet在一个servlet执行的时候,使用一个不同的更长的连接超时。| 建议设为false| keepAliveTimeout|长连接超时时间 |常常设置-1永不过期| URIEncoding|URL统一编码|utf-8| redirectPort|在需要基于安全通道的场合,把客户请求转发到基于SSL的redirectPort端口|8443| prestartminSpareThreads | 在 Tomcat 初始化的时候就初始化 minSpareThreads 的 maxQueueSize | 最大的等待队列数,超过则拒绝请求 |
描述: 在tomcat中每一个用户请求都是一个线程,所以可以使用线程池提高性能。 修改server.xml文件:
$ vim ./conf/server.xml <!‐‐ 将注释打开(注释没打开的情况下默认10个线程,最小10,最大200)‐‐> <Executor name="tomcatThreadPool" namePrefix="catalina‐exec‐" maxThreads="500" minSpareThreads="50" prestartminSpareThreads="true" maxQueueSize="100"/> <Connector port="8080" #默认BIO/建议采用NIO或者arp提高并发处理能力 protocol="HTTP/1.1" #网络连接超时,单位:毫秒。设置为0表示永不超时(不推荐)) connectionTimeout="30000" maxHttpHeaderSize="32768" redirectPort="8443" #当前可以同时处理的最大用户访问数最大连接数配置(并发能力) maxThreads="1000" #Tomcat初始化时创建的线程数。最小空闲线程连接数用于优化线程池 minSpareThreads="100" #一旦创建的线程超过这个值,Tomcat就会关闭不再需要的socket线程。 maxSpareThreads="1000" acceptorThreadCount="2" #当所有的线程以分配,仍然允许连接进来,但是出于等待状态的用户数。 #等待线程数+工作线程数=总的可最大连接数,超过这个数的请求将不予处理。 acceptCount="2000" minProcessors="100" maxProcessors="2000" #为了消除DNS查询对性能的影响我们可以关闭DNS查询,关闭该功能在一定程度上提高了Tomcat服务器的性能; enableLookups="false" maxKeepAliveRequests="-1" keepAliveTimeout="-1" disableUploadTimeout="false" connectionUploadTimeout="150000" useSendfile="false" #Tomcat 压缩配置,建议在前端 nginx 上开启压缩。Tomcat 作为应用服务器本身就很繁忙了。 compression="on" compressionMinSize="2048" compressableMimeType="text/html,text/xml,application/javascript,application/json,text/javascript,text/css,text/plain,image/gif,image/png" URIEncoding="UTF-8" />
#1.下载编译apr依赖 cd /usr/local/src/ wget http://mirrors.tuna.tsinghua.edu.cn/apache/apr/apr-1.7.0.tar.gz wget http://mirrors.tuna.tsinghua.edu.cn/apache/apr/apr-util-1.6.1.tar.gz tar xf apr-1.7.0.tar.gz && tar xf apr-util-1.6.1.tar.gz cd apr-1.7.0 ./configure --prefix=/usr/local/apr make -j 2 && make install cd apr-util-1.6.1 ./configure --prefix=/usr/local/apr-util --with-apr=/usr/local/apr/ make -j2 && make install cp "/opt/tomcat/apache-tomcat-8.5.45/bin/tomcat-native.tar.gz" . tar xf tomcat-native.tar.gz && cd tomcat-native-1.2.23-src/native/ ./configure --prefix=/usr/local/apr --with-java-home=/opt/tomcat/jdk8/ make -j 2 && make install #添加apr path echo "export LD_LIBRARY_PATH=/usr/local/apr/lib" > /etc/profile source /etc/profile
配置arp模式:
$ cd /usr/local/tomcat/conf/ $ vim server.xml <Connector port="8080" protocol="org.apache.coyote.http11.Http11AprProtocol" connectionTimeout="20000" redirectPort="8443" /> #注意如果SSLEngine设置off会导致报错 <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
WeiyiGeek.
成功后查看启动日志:
$cat /opt/tomcat/apache-tomcat-8.5.45/logs/catalina.out 12-Sep-2019 12:37:47.381 INFO [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler ["http-apr-10.10.107.222-8080"] 12-Sep-2019 12:37:47.417 INFO [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler ["https-openssl-apr-443"] 12-Sep-2019 12:37:47.419 INFO [main] org.apache.catalina.startup.Catalina.start Server startup in 891 ms
描述:执行器(线程池)在tomcat中每一个用户请求都是一个线程,所以可以使用线程池提高性能。
#去掉下面两个元素注释并修改maxThreads: <Executor name="tomcatThreadPool" namePrefix="catalina-exec-" maxThreads="300" minSpareThreads="4"/> <Connector executor="tomcatThreadPool" port="8080" protocol="org.apache.coyote.http11.Http11NioProtocol" maxThreads="1000" minSpareThreads="100" maxSpareThreads="200" acceptCount="1000" disableUploadTimeout="true" connectionTimeout="30000" URIEncoding="UTF-8" enableLookups="false" compression="on" compressionMinSize="2048" compressableMimeType="text/html,text/xml,text/javascript,text/css,text/plain,image/gif,image/jpg,image/png" redirectPort="8443" />
WeiyiGeek.
Context元素reloadable属性会监视在 web-inf/classes 和 web-inf/lib 目录下class文件的改动,如果监测到有class文件被更新的,服务器会自动重新加载web应用。
在开发和调试阶段,将其改为true但是一般像Eclipse等开发环境都会默认改为true
在正式发布阶段,应将其该为false可以降低Tomcat的运行负荷,提高Tomcat的运行性能
$vim conf/server.xml #在</Host>之前加入类似以下内容:(重启生效) <context path="/bbs" docbase="bbs" reloadable="false"/>
描述:当你执行了 ./startup.sh 或者 ./catalina.sh start 后等待时间过长能要几分钟才能正常提供服务。 原因:在apache-tomcat 官方文档:如何让 tomcat 启动更快里面提到了一些启动时的优化项,其中一项是关于随机数生成时,采用的"熵源"(entropy source)的策略。
使用伪随机函数生成器:
通过修改 Tomcat 启动文件 -Djava.security.egd=file:/dev/urandom通过修改 JRE 中的 java.security 文件 securerandom.source=file:/dev/urandJAVA_OPTS="-server -Xms1024m -Xmx2048m -XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=80 -XX:-PrintGC -XX:-PrintGCDetails -XX:-PrintGCTimeStamps -Djava.security.egd=file:/dev/urandom"
WeiyiGeek.
增大/dev/random的熵池(推荐)
#安装熵池服务 rngd $yum -y install rng-tools $systemctl start rngd $systemctl enable rngd
启动服务后观察 cat/proc/sys/kernel/random/entropy_avail 基本在三千左右。
$cat /proc/sys/kernel/random/entropy_avail 3311
描述:加固依然分为身份鉴别、访问控制、安全审计、资源控制和入侵防范5个方面; 大部分加固基于xml配置文件进行修改,也应根据实际需求制定方案。
#寻找配置文件目录 find /-name *tomcat* #配置文件目录存放目录 ${tomcat_home}/conf/...
描述:口令要求:长度至少8位,并包括数字、小写字母、大写字母和特殊符号4类中至少3类。 修改tomcat配置文件/conf/tomcat-users.xml配置文件,要求usr1密码必须满足复杂度要求。
<user username="Tomcat1" password="12345qwe" roles="manager-gui"> <user username="Tomcat2" password="12345qwe" roles="admin-gui">
描述:Tomcat的主要管理界面被称为Manager应用程序
如果不使用manager来管理部署应用,建议修改tomcat配置文件/conf/tomcat-users.xml配置文件来禁用或者删除manager文件夹
如果使用该功能我们需要进行配置口令以及强密码包括访问控制,删除与工作无关的帐号以及应用。
#1.配置强密码登录manager后面 $vim tomcat_user.xml <?xml version="1.0" encoding="UTF-8"?> <tomcat-users xmlns="http://tomcat.apache.org/xml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://tomcat.apache.org/xml tomcat-users.xsd" version="1.0"> #角色如下并且要记得只赋予最小权限: # manager-gui:可以访问web界面 # manager-status:只可以访问“Server Status”页面 # manager-script:可以脚本文本界面和“Server Status”页面 # manager-jmx:可以访问JMX代理界面和“Server Status”页面 <role rolename="manager-gui"/> #host-manager页面 <role rolename="admin-gui"/> <!--密码复杂度需要满足等保要求--> <user username="admin" password="@weiyigeek@" roles="manager-gui,admin-gui"/> </tomcat-users> #2.访问控制设定(其实默认只能本机访问) $/opt/tomcat/apache-tomcat-8.5.45/webapps/manager/META-INF/ #采用正则添加匹配 <Valve className="org.apache.catalina.valves.RemoteAddrValve" allow="127.d+.d+.d+|::1|0:0:0:0:0:0:0:1" />
WeiyiGeek
描述:与manager管理一样如果使用的话进需要进行安全配置
不使用的话建议删除webapps应用目录下的host-manager
使用需要进行安全配置
#登录密码配置 $vim conf/tomcat-users.xml <role rolename="admin-gui"/> <user username="tomcat" password="s3cret" roles="admin-gui"/> #访问配置(其实默认只能本机访问) <Valve className="org.apache.catalina.valves.RemoteAddrValve" allow="127.d+.d+.d+|::1|0:0:0:0:0:0:0:1|10.d+.d+.d+" />
WeiyiGeek.
描述:建议使用专用用户 tomcat 或者 nobody 用户来启动 Tomcat,为了防止 Tomcat 被植入 web shell 程序后,可以修改项目文件。 因此我们要将 Tomcat 和项目的属主做分离(常常使upload目录可以有上传权限,但是不能有执行的权限))))),他也无法创建和编辑项目文件。
$ps -ef | grep tomcat|grep -v "grep" tomcat 13243 1 0 10:27 pts/0 00:00:02 /opt/tomcat/jdk8/jre/bin/java -Djava.util.logging.config.file=/opt/tomcat//apache-tomcat-8.5.45/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -server -Xms1024m -Xmx2048m -XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=80 -XX:-PrintGC -XX:-PrintGCDetails -XX:-PrintGCTimeStamps -Xloggc:../logs/gc.log -Djdk.tls.ephemeralDHKeySize=2048 -Djava.protocol.handler.pkgs=org.apache.catalina.webresources -Dorg.apache.catalina.security.SecurityListener.UMASK=0027 -Dignore.endorsed.dirs= -classpath /opt/tomcat//apache-tomcat-8.5.45/bin/bootstrap.jar:/opt/tomcat//apache-tomcat-8.5.45/bin/tomcat-juli.jar -Dcatalina.base=/opt/tomcat//apache-tomcat-8.5.45 -Dcatalina.home=/opt/tomcat//apache-tomcat-8.5.45 -Djava.io.tmpdir=/opt/tomcat//apache-tomcat-8.5.45/temp org.apache.catalina.startup.Bootstrap start
描述:Tomcat的日志文件存放于logs文件夹,里面包含了多种类型的日志,主要分为两类:
一是运行中的日志,它主要记录运行的一些信息,尤其是一些异常错误日志信息。二是访问日志信息,它记录的访问的时间,IP,访问的资料等相关信息。各个日志文件的作用:
localhost.2019-09-10.log:程序异常没有被捕获的时候抛出的地方catalina.2019-09-10.log:程序的输出,tomcat的运行日志manager.2019-09-10.log:manager项目专有的host-manager.2019-09-10.log:manager项目专有的localhost_access_log.2019-09-10.txt:访问日志记录编辑tomcat配置文件server.xml配置文件将以下内容的注释标记:
<!-- 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 "%r" %s %b" /> <!-- 每个字段的含义为 192.168.228.1 - - [29/Sep/2017:11:26:10 +0800] "GET / HTTP/1.1" 200 11418 %h:远程主机名或IP地址:192.168.228.1 %l:远程用户名,始终为“-” %u:已验证的远程用户,如果没有则为“-” %t:访问日期和时间:[29/Sep/2017:11:26:10 +0800] %r:http请求中的第一行:GET / HTTP/1.1 %s:http状态码:200 %b:发送的字节数:11418 -->
属性解释:
Directory:日志文件放置的目录,在tomcat下面有个logs文件夹,那里面是专门放置日志文件的,也可以修改为其他路径;Prefix:这个是日志文件的名称前缀,日志名称为localhost_access_log.2008-10-22.txt,前面的前缀就是这个localhost_access_log。Suffix: 文件后缀名。Pattern:common方式时,将记录访问源IP、本地服务器IP、记录日志服务器IP、访问方式、发送字节数、本地接收端口、访问URL地址等相关信息在日志文件中。resolveHosts:值为true时,tomcat会将这个服务器IP地址通过DNS转换为主机名,如果是false,就直接写服务器IP地址。Tomcat的运行日志有以下7个级别:
SEVERE > WARNING > INFO > CONFIG > FINE > FINER > FINEST
描述:Tomcat可能自带一些默认的web应用程序。如果不是一定需要,必须将它们移除。 移除${tomcat_home}/webapps中所有的默认的web应用程序有:ROOT、Documentation、Examples、Host Manager和Manager
#果不是一定需要,必须将它们移除。 rm -rf /opt/tomcat/apache-tomcat-8.5.45/webapps/*
描述:编辑tomcat配置文件/conf/web.xml文件,在最后一行之前加入以下内容,然后需要重新启动tomcat服务;
<error-page> <!-- 配置实现了将404未找到jsp网页的错误导向noFile.htm页面,还可以添加其多的错误代码导向页面,如403,500 --> <error-code>404</error-code> <location>/noFile.htm</location> </error-page> <error-page> <!--配置实现了当jsp网页出现java.lang.NullPointerException导常时,转向error.jsp错误页面 --> <exception-type>java.lang.NullPointerException</exception-type> <location>/error.jsp</location> </error-page>
当出现NullPointerException异常时tomcat会把网页导入到error.jsp,且会打印出出错信息。
<%@ pageerrorPage="/error.jsp" %> 典型的error.jsp错误页面的程序写法如下: <%@ pagecontentType="text/html;charset=GB2312"%> <%@ pageisErrorPage="true"%> <html> <head> <title>错误页面</title> </head> <body>出错了:</p>错误信息:<%= exception.getMessage() %> <br> Stack Trace is : <pre> <font color="red"><% java.io.CharArrayWritercw = new java.io.CharArrayWriter(); java.io.PrintWriterpw = new java.io.PrintWriter(cw,true); exception.printStackTrace(pw); out.println(cw.toString()); %> </font> </pre> </body> </html>
补充事项:
如果Manager应用程序没被移除,必须手动将位于 CATALINA_HOME/webapps/manager/WEB-INF/jsp/ 的错误页面里的Tomcat版本信息移除。
描述:Tomcat文件夹只能由tomcat用户本身访问,尤其是对于目录{tomcat_home}/conf /和{tomcat_home}/webapps当不需要通过应用程序服务器自动部署时,标准配置就是将所有Tomcat文件的所有者设置为root,并且所属群组设置为Tomcat,然后用chmod 740仅允许root用户编辑文件并允许Tomcat用户读取文件。
#(注意点)例外是临时和工作目录的所有者应该是Tomcat用户而不是root用户。 whown root:tomcat /opt/tomcat chmod 740 ${tomcat_home}/conf chmod 740 ${tomcat_home}/webapps
描述:所有的web应用程序的会话超时必须设置为20分钟可通过编辑 CATALINA_HOME/conf/web.xml 文件并做以下配置来实现:
<!-- Tomcat8默认的超时时间是半个小时 --> <session-config> <session-timeout>20</session-timeout> </session-config>
描述: Tomcat提供了防止恶意攻击或禁止某些机器访问的设置,限制手段来防止恶意的服务攻击; 可以让你过滤来自请求的主机或IP地址,并允许或拒绝哪些主机/IP。与之类似的在Apache的httpd文件里有对每个目录的允许/拒绝指定。
Tomcat提供了两个参数供你配置:RemoteHostValve 和RemoteAddrValve。 例如: 你可以把Admin Web application设置成只允许本地访问设置如下:
<Context path="/path/to/secret_files" > #如果没有给出允许主机的指定,那么与拒绝主机匹配的主机就会被拒绝,除此之外的都是允许的 <Valve className="org.apache.catalina.valves.RemoteAddrValve" allow="10.0.172.109" deny="" /> </Context>
描述:不要让连接器(connector)监听服务器上所有可用的网络接口和IP地址,而要让连接器监听指定的网络接口和IP地址采用address属性,防止应用程序意外地运行在某个开放的网络接口上。
#将默认值20000改成10000即可单位ms注意需要根据实际需求更改 $vim conf/server.xml <Connector port="8080" protocol="HTTP/1.1" connectionTimeout="10000" redirectPort="8443" address="127.0.0.1" />
描述:AJP(Apache JServer Protocol)AJPv13协议是面向包的。 WEB服务器和Servlet容器通过TCP连接来交互, 为了节省SOCKET创建的昂贵代价,WEB服务器会尝试维护一个永久TCP连接到servlet容器,并且在多个请求和响应周期过程会重用连接。
实际上我们一般使用Nginx+Tomcat架构所以用不着Ajp协议可以将其禁用。
# 编辑server.xml进行注释配置 $vim conf/server.xml <!-- <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" /> -->
WeiyiGeek.ajp
Tips : 禁用ajp后可以看节省了多少内存以及查询某个pid占用的内存。
描述:readonly参数默认是true即不允许delete和put操作 编辑web.xml文件查看org.apache.catalina.servlets.DefaultServlet是否存在如下配置
$vim conf/web.xml <init-param> <param-name>readonly</param-name> <param-value>true</param-value> </init-param>
描述:设置DefaultServlet的listings为false 这不仅仅是因为允许显示目录列表被认为是不安全的,而且还因为生成具有数千个文件的目录列表会消耗大量的CPU资源,相当于被DDoS攻击。 注意:Tomcat8默认是false并且更改后需要重新启动tomcat服务;
$vim conf/web.xml <!-- 同样也是在下面进行添加--> <servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class> <init-param> <param-name>listings</param-name> <param-value>false</param-value> </init-param>
描述:编辑tomcat配置文件conf/server.xml配置文件,shutdown的值为复杂的字符串:
#随机生成密码 $cat /dev/urandom | tr -dc '_a-zA-Z0-9' | head -c 12 r02BPRnHyq89 #配置如下:将默认的SHUTDOWN变成r02BPRnHyq89 <Serverport="8005" shutdown="r02BPRnHyq89"> #如果不需要该功能,必须要将其停用,设置如下: <Server port="-1" shutdown="SHUTDOWN"> #本地管理脚本可将服务器关闭,即使在关闭端口被禁用的情况下。
描述:修改以掩饰真实版本信息防止攻击者以版本的漏洞进行攻击,影响错误页面和响应头;
##(1)修改/lib/catalina.jar中org/apache/catalina/util/Serverinfo.properties问津中的以下参数 (推荐方式) $unzip catalina.jar $vim catalina/org/apache/catalina/util/Serverinfo.properties server.info=Nginx server.number=0.0.0.0 server.built=Apr 2 2017 07:25:00 UTC #将修改后的信息压缩回jar包 jar uvf catalina.jar org/apache/catalina/util/ServerInfo.properties
WeiyiGeek.
#(2)修改web.xml中国Connector链接器 <Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" URIEncoding="UTF-8" useBodyEncodingForURI="true" server="Microsoft-IIS/6.5"/> #关键点
WeiyiGeek.
描述:Tomcat允许在Tomcat运行时自动部署应用程序。为了防止被植入木马等恶意程序,因此我们要关闭自动部署。
$vim server.xml #将unpackWARs与autoDeploy的true值改成false; <Host name="localhost" appBase="webapps" unpackWARs="false" autoDeploy="false">
补充:在托管环境中Web应用程序可能不受信任,也可以设置deployXML属性为false来忽略context.xml以防给该web应用程序提高权限。
描述:采用HTTPS协议加密可以防止中间人攻击,以及数据的拦截和修改的验证导致攻击无效;
#(1)用JDK自带的keytool工具生成一个证书,默认三个月的有效期; $JAVA_HOME/bin/keytool -genkey -alias tomcat -keyalg RSA -keystore /tmp/keystore Enter keystore password: Re-enter new password: What is your first and last name? [Unknown]: Tomcat What is the name of your organizational unit? [Unknown]: CQ What is the name of your organization? [Unknown]: CQ What is the name of your City or Locality? [Unknown]: BEIJING What is the name of your State or Province? [Unknown]: XIZHIMEN What is the two-letter country code for this unit? [Unknown]: 408119 Is CN=Tomcat, OU=CQ, O=CQ, L=BEIJING, ST=XIZHIMEN, C=408119 correct? [no]: Y Enter key password for <tomcat> (RETURN if same as keystore password): Re-enter new password: #(2)修改tomcat安装目录下/conf/server.xml配置文件,更改为使用HTTPS方式,增加如下行: <Connector classname="org.apache.catalina.http.HttpConnector" port="443" protocol="HTTP/1.1" minProcessors="5" SSLEnabled="true" maxprocessors="100" enableLookups="true" acceptCount="10" debug="0" scheme="https" Factory_classname="org.apache.catalina.SSLServerSocketFactory" secure="true" clientAuth="false" keystoreFile="/tmp/keystore" keystorePass="weiyigeek" sslProtocol="TLS" /> #SSL Connector来指定可用的SSL加密方式: ciphers="SSL_RSA_WITH_RC4_128_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, SSL_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA"
也可以通过 https://10.10.107.222/manager/html/sslConnectorCerts 查看证书情况
WeiyiGeek.
补充:为了使托管在Tomcat上的所有web应用程序强制使用HTTPS,必须在每个 CATALINA_HOME/webapps/$WEBAPP/WEB-INF/web.xml 文件里每个security-constraint标签关闭(标签)之前包含以下内容:
<user-data-constraint> <transport-guarantee>Confidential</transport-guarantee> <user-data-constraint>
描述:对会话cookie自动启用HttpOnly的cookie标记,查看配置以确保该选项为被禁用。
#要启用HttpOnly设置使之全局应用于所有应用程序: <Context useHttpOnly='true'> ... <Context>
补充:如果应用程序需要通过JavaScript访问HttpOnly cookie,可以在METAINF/context.xml中一个单独的Context中定义一个异常。
描述:为保护应用程序必须启用Tomcat的跨站请求伪造防护。Tomcat8~9提供了基本的CSRF防护。可以在 CATALINA_BASE/conf/web.xml 中配置一个全局过滤器。
#该过滤器可以被每个使用 WEB-INF/web.xml 文件的应用程序覆盖。 <filter-mapping> <filter-name>CSRFPreventionFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
补充:使用CSRF防护可能会影响程序功能,必须要牢记这一点,尤其是在应用程序大量使用异步请求的情况下。
描述:以下是常规的默认配置并且默认情况下这些设置被认为是安全的,如有在项目中进行更改的建议进行整改和调整;
$vim $CATALINA_HOME/conf/server.xml <Connector #1.设置为空或者false allowTrace="false" />
$vim $CATALINA_HOME/conf/server.xml <Context #1.将privileged属性设置为false,除非像Manager应用程序那样需要权限: privileged="false" #2.确保crossContext值为空或被设为false, #crossContext值为true可能会导致允许恶意应用程序向受限应用程序发送请求。 crossContext="false" #3.确保allowLinking值为空或被设为false。 #allowLinking值为true可能会导致目录遍历和源代码泄露漏洞的产生。 allowLinking="false" />
#1.当RECYCLE_FACADES选项设置为true时,Tomcat会回收请求间会话外观(session facade),将导致请求间的信息泄漏 #默认情况下,此参数未被设置(确保使用的启动脚本不包含以下内容) Dorg.apache.catalina.connector.RECYCLE_FACADES = false #2.允许在Tomcat上指定不同的路径分隔符,可能会允许攻击者访问应用程序,该行为本该被代理程序(比如mod_proxy)阻止 #默认情况下,此参数未被设置(确保使用的启动脚本不包含以下内容) Dorg.apache.catalina.connector.CoyoteAdapter.ALLOW_BACKSLASH = FALSE Dorg.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH = FALSE #3.允许自定义header状态消息,使攻击者也能够插header。 #可能会导致XSS漏洞的产生。默认情况下此参数未被设置。 Dorg.apache.coyote.USE_CUSTOM_STATUS_MSG_IN_HEADER = false Dorg.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH= FALSE Dorg.apache.coyote.USE_CUSTOM_STATUS_MSG_IN_HEADER = false
描述:可用Java SecurityManager限制单个应用程序的功能。
$CATALINA_HOME/conf/catalina.policy 文件包含了Java SecurityManager使用的安全策略的配置一旦配置了catalina.policy 文件,便可以使用SecurityManager和–security选项启Tomcat。注意事项:
因为基本上所有的权限类型(比如访问单个文件和目录或Java包)都应该根据每个应用程序进行单独配置,所以这会大大增加操作成本。另外,限制过于严格的策略文件会影响应用程序的功能。描述:Tomcat可限制对某些Java包的访问。如果检测到受限制的包被访问,将抛出安全异常。 对Java包做访问限制,打开 $CATALINA_BASE/conf/catalina.properties 文件并添加不允许访问的包至package.access列表。
分析Java import可以列出哪些应用程序需要哪些包。在Unix系统上,可以使用以下例子来实现:
grep –R import ${tomcat_home}/webapps/WEBAPP
(1) 生产配置实例 描述 server.xml 配置文件:
[root@tomcat1 ~]# vim /usr/local/tomcat8/conf/server.xml <!-- 修改Connector元素 --> <Connector executor="tomcatThreadPool" port="8080" protocol="org.apache.coyote.http11.Http11NioProtocol" address="127.0.0.1" acceptCount="1000" connectionTimeout="20000" compression="on" compressionMinSize="2048" compressableMimeType="text/html,text/xml,text/javascript,text/css,text/plain,image/gif,image/jpg,image/png" disableUploadTimeout="true" enableLookups="false" maxThreads="1000" minSpareThreads="100" maxSpareThreads="200" maxKeepAliveRequests="1" redirectPort="8443" server="SecWAF/1.9" URIEncoding="UTF-8" /> <!-- # 参数说明: protocol : 协议调整工作模式为Nio (org.apache.coyote.http11.Http11Nio) port : 绑定监听端口 redirectPort :重定向端口 address : 绑定监听地址 acceptCount :当同时连接的人数达到`maxThreads`参数设置的值时其还可以接收排队的连接数量,超过这个连接的则直接返回拒绝连接。在实际应用中如果想加大Tomcat的并发数,应该同时加大 acceptCount 和 maxThreads 的值。 connectionTimeout : 连接超时时间单位毫秒,0代表不限制。 compression :启用压缩功能。 compressionMinSize :最小压缩大小单位Byte。 compressableMimeType :压缩的文件类型。 disableUploadTimeout:禁用上传超时时间 enableLookups :是否开启域名反查,一般设置为false来提高处理能力。 maxThreads :设置当前Tomcat的最大并发数,默认配置的最大请求数是150个,即同时能支持150个并发。 minSpareThreads :最小空闲线程数,设置当前Tomcat初始化时创建的线程数,默认值为25。 maxSpareThreads :最大空闲线程数,如果超过这个值会关闭无用的线程。 maxKeepAliveRequests : 最大保持活动请求数,并且以必须设置tomcat的超时时间`connectionTimeout`,避免tomcat产生大量的TIME_WAIT连接。 server : 设置server字段响应头; URIEncoding :URI地址编码使用UTF-8 -->
https://www.jianshu.com/p/d64b5909ec1b https://www.cnblogs.com/yechanglv/p/6941821.html