Tomcat
- tomcat部署
- 目录结构
- 配置tomcat管理功能
- 部署jpress
- tomcat多实例
- tomcat监控
- tomcat安全优化
0、LNMT简介
-
JAVA:LNMT(tomcat)
- tomcat
- resin
- weblogic
PHP:LNMP LAMP
| 环境 | 处理模型 | 处理用户请求区别 |
| ---- | ---------------------------- | ----------------------- |
| lnmp | epoll(异步)缓存 | 通过fastcgi(php-fpm) |
| lamp | select(同步)遇到一个处理一个 | 通过apache模块与php沟通 |
1、tomcat简介
-
jvm:(java virtual machine) java虚拟机
- 代码的可移植性,1份代码处处使用
- 占用内存
- 代码的可移植性,1份代码处处使用
-
jdk:(java development) java开发环境
java命令
jvm
-
jdk
Oracle jdk
openjdk
2、tomcat搭建
-
web
#上传软件包至/opt目录下 [root@docker01 opt]# pwd /opt [root@docker01 opt]# ll apache-tomcat-8.5.47.tar jdk-8u11-linux-x64.tar.gz -rw------- 1 root root 15124480 Oct 23 11:16 apache-tomcat-8.5.47.tar -rw------- 1 root root 159019376 Aug 21 15:32 jdk-8u11-linux-x64.tar.gz [root@docker01 opt]#
-
jdk
#解压缩jdk [root@docker01 opt]# mkdir /application [root@docker01 opt]# tar xf jdk-8u11-linux-x64.tar.gz -C /application/ [root@docker01 opt]# cd /application/ [root@docker01 application]# ls jdk1.8.0_11 [root@docker01 application]# ln -s jdk1.8.0_11 jdk [root@docker01 application]# ll total 0 lrwxrwxrwx 1 root root 11 Oct 23 11:35 jdk -> jdk1.8.0_11 drwxr-xr-x 8 10 143 255 Jun 17 2014 jdk1.8.0_11 #环境变量 cat >>/etc/profile<<'EOF' export JAVA_HOME=/application/jdk export PATH=$JAVA_HOME/bin:$JAVA_home/jre/bin:$PATH export CLASSPATH=.:$JAVA_HOME/lib:$JAVA_HOME/jre/lib:$JAVA_HOME/lib/tools.jar EOF [root@docker01 application]# tail -n 3 /etc/profile export JAVA_HOME=/application/jdk export PATH=$JAVA_HOME/bin:$JAVA_home/jre/bin:$PATH export CLASSPATH=.:$JAVA_HOME/lib:$JAVA_HOME/jre/lib:$JAVA_HOME/lib/tools.jar [root@docker01 application]# #测试 [root@docker01 application]# source /etc/profile [root@docker01 application]# java -version java version "1.8.0_11" Java(TM) SE Runtime Environment (build 1.8.0_11-b12) Java HotSpot(TM) 64-Bit Server VM (build 25.11-b03, mixed mode)
-
Tomcat
#解压缩tomcat [root@docker01 opt]# tar xf apache-tomcat-8.5.47.tar -C /application [root@docker01 opt]# cd /application/ [root@docker01 application]# ls apache-tomcat-8.5.47 jdk jdk1.8.0_11 [root@docker01 application]# ln -s apache-tomcat-8.5.47 tomcat [root@docker01 application]# ll total 0 drwxr-xr-x 9 root root 220 Oct 23 11:38 apache-tomcat-8.5.47 lrwxrwxrwx 1 root root 11 Oct 23 11:35 jdk -> jdk1.8.0_11 drwxr-xr-x 8 10 143 255 Jun 17 2014 jdk1.8.0_11 lrwxrwxrwx 1 root root 20 Oct 23 11:38 tomcat -> apache-tomcat-8.5.47 #测试部署环境 [root@docker01 application]# /application/tomcat/bin/version.sh Using CATALINA_BASE: /application/tomcat Using CATALINA_HOME: /application/tomcat Using CATALINA_TMPDIR: /application/tomcat/temp Using JRE_HOME: /application/jdk Using CLASSPATH: /application/tomcat/bin/bootstrap.jar:/application/tomcat/bin/tomcat-juli.jar Server version: Apache Tomcat/8.5.47 Server built: Oct 7 2019 13:30:46 UTC Server number: 8.5.47.0 OS Name: Linux OS Version: 3.10.0-957.el7.x86_64 Architecture: amd64 JVM Version: 1.8.0_11-b12 JVM Vendor: Oracle Corporation #启动 [root@docker01 application]# /application/tomcat/bin/startup.sh Using CATALINA_BASE: /application/tomcat Using CATALINA_HOME: /application/tomcat Using CATALINA_TMPDIR: /application/tomcat/temp Using JRE_HOME: /application/jdk Using CLASSPATH: /application/tomcat/bin/bootstrap.jar:/application/tomcat/bin/tomcat-juli.jar Tomcat started. [root@docker01 application]# ss -lntupl|grep 8080 tcp LISTEN 0 100 :::8080 :::* users:(("java",pid=7622,fd=52)) [root@docker01 application]# ps -ef|grep java root 7622 1 4 11:39 pts/0 00:00:02 /application/jdk/bin/java -Djava.util.logging.config.file=/application/tomcat/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djdk.tls.ephemeralDHKeySize=2048 -Djava.protocol.handler.pkgs=org.apache.catalina.webresources -Dorg.apache.catalina.security.SecurityListener.UMASK=0027 -Dignore.endorsed.dirs= -classpath /application/tomcat/bin/bootstrap.jar:/application/tomcat/bin/tomcat-juli.jar -Dcatalina.base=/application/tomcat -Dcatalina.home=/application/tomcat -Djava.io.tmpdir=/application/tomcat/temp org.apache.catalina.startup.Bootstrap start root 7689 7523 0 11:40 pts/0 00:00:00 grep --color=auto java #停止 [root@docker01 application]# /application/tomcat/bin/shutdown.sh Using CATALINA_BASE: /application/tomcat Using CATALINA_HOME: /application/tomcat Using CATALINA_TMPDIR: /application/tomcat/temp Using JRE_HOME: /application/jdk Using CLASSPATH: /application/tomcat/bin/bootstrap.jar:/application/tomcat/bin/tomcat-juli.jar #核心脚本自行了解 cat /application/tomcat/bin/catalina.sh
3、目录结构
[root@docker01 tomcat]# ll
total 124
drwxr-x--- 2 root root 4096 Oct 23 11:38 bin
-rw-r----- 1 root root 19318 Oct 7 21:33 BUILDING.txt
drwx------ 3 root root 254 Oct 23 11:39 conf
-rw-r----- 1 root root 5407 Oct 7 21:33 CONTRIBUTING.md
drwxr-x--- 2 root root 4096 Oct 23 11:38 lib
-rw-r----- 1 root root 57011 Oct 7 21:33 LICENSE
drwxr-x--- 2 root root 197 Oct 23 11:39 logs
-rw-r----- 1 root root 1726 Oct 7 21:33 NOTICE
-rw-r----- 1 root root 3255 Oct 7 21:33 README.md
-rw-r----- 1 root root 7136 Oct 7 21:33 RELEASE-NOTES
-rw-r----- 1 root root 16262 Oct 7 21:33 RUNNING.txt
drwxr-x--- 2 root root 30 Oct 23 11:38 temp
drwxr-x--- 7 root root 81 Oct 7 21:31 webapps
drwxr-x--- 3 root root 22 Oct 23 11:39 work
-
bin(tomcat管理命令startup.sh shutdown.sh catalina.sh)
- catalina.sh是startup.sh、shutdown.sh调用的
- tomcat优化(jvm使用最小、最大内存和配置监控功能)
-
conf
server.xml 主配置文件
web.xml 增加插件优化
-
tomcat-users.xml 管理端配置文件
#1.添加访问用户 [root@docker01]# vim /application/tomcat/conf/tomcat-users.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"> <role rolename="manager-gui"/> <role rolename="manager-script"/> <role rolename="manager-jmx"/> <role rolename="manager-status"/> <role rolename="admin-gui"/> <role rolename="admin-script"/> <user username="admin" password="123456" roles="manager-gui,manager-script,manager-jmx,manager-status,admin-gui,admin-script"/> </tomcat-users> #2.如果不执行这步. 则只能localhost访问manager. [root@docker01]# vim /application/tomcat/webapps/manager/META-INF/context.xml <?xml version="1.0" encoding="UTF-8"?> <Context antiResourceLocking="false" privileged="true" > <Valve className="org.apache.catalina.valves.RemoteAddrValve" allow="^.*$" /> <Manager sessionAttributeValueClassNameFilter="java\.lang\.(?:Boolean|Integer|Long|Number|String)|org\.apache\.catalina\.filters\.CsrfPreventionFilter\$LruCache(?:\$1)?|java\.util\.(?:Linked)?HashMap"/> </Context> #3.如果不执行这步. 则只能localhost访问manager. [root@docker01]# vim /application/tomcat/conf/Catalina/localhost/manager.xml <Context privileged="true" antiResourceLocking="false" docBase="${catalina.home}/webapps/manager"> <Valve className="org.apache.catalina.valves.RemoteAddrValve" allow="^.*$" /> </Context> /application/tomcat/bin/shutdown.sh /application/tomcat/bin/startup.sh
-
server.xml 主配置文件
#shutdown端口(连接端口输入SHUTDOWN即可关闭tomcat,限制127.0.0.1) <Server port="8005" shutdown="SHUTDOWN"> #管理端用户配置 <GlobalNamingResources> <!-- Editable user database that can also be used by UserDatabaseRealm to authenticate users --> <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> #线程设置 <Executor name="tomcatThreadPool" namePrefix="catalina-exec-" maxThreads="150" minSpareThreads="4"/> #端口号8080,加密8443 <Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" /> #与apache沟通端口 <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" /> #虚拟主机目录 <Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true"> #日志格式 <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" prefix="localhost_access_log" suffix=".txt" pattern="%h %l %u %t "%r" %s %b" />
-
-
logs
catalina.out(tomcat的核心日志,持续增加)
catalina.2019-10-23.log日志切割
-
localhost_access_log.2019-10-23.txt访问日志
#系统日志切割 [root@docker01 ~]# cat /etc/logrotate.d/syslog /var/log/cron /var/log/maillog /var/log/messages /var/log/secure /var/log/spooler { missingok sharedscripts postrotate /bin/kill -HUP `cat /var/run/syslogd.pid 2> /dev/null` 2> /dev/null || true endscript } #logrotate日志切割 [root@docker01 ~]# vim /etc/logrotate.d/tomcatlog /application/tomcat/logs/catalina.out { daily rotate 15 missingok dateext compress notifempty copytruncate } [root@docker01 ~]# logrotate -f /etc/logrotate.d/tomcatlog [root@docker01 ~]# cat /var/lib/logrotate/logrotate.status #解释 daily 指定转储周期为每天 rotate 15 指定日志文件删除之前转储的次数,0指没有备份,15指保留15个备份 missingok 如果日志不存在则忽略该警告信息 dateext 文件后缀是日期格式,也就是切割后文件是:xxx.log-20191023.gz compress 通过gzip压缩转储以后的日志(gzip -d xxx.gz解压) notifempty 如果是空文件的话,不转储 copytruncate 用于还在打开中的日志文件,把当前日志备份并截断 /application/tomcat/logs/catalina.out 指定catalina.out的路径
webapps 工作目录
4、部署jpress
#1.创建数据库及用户
MariaDB [(none)]> create database jpress
MariaDB [(none)]> grant ALL on jpress.* to jpress@'localhost' identified by 'jpress';
MariaDB [(none)]> flush privileges;
MariaDB [(none)]> exit
Bye
[root@docker01 ~]# mysql -ujpress -p
#2.上传war包至tomcat的webapp目录下
/application/tomcat/webapps/jpress-v2.0.8
[root@docker01 ~]# /application/tomcat/bin/shutdown.sh
[root@docker01 ~]# /application/tomcat/bin/startup.sh
#3.登陆html进行调试
http://127.0.0.1:8080/jpress-v2.0.8
5、多实例
#创建
[root@docker01 opt]# tar -xf apache-tomcat-8.5.47.tar
[root@docker01 opt]# ls
apache-tomcat-8.5.47 apache-tomcat-8.5.47.tar backup_172.16.1.41 bak jdk-8u11-linux-x64.tar.gz
[root@docker01 opt]# cp -a apache-tomcat-8.5.47 /application/tomcat_8081
[root@docker01 opt]# cp -a apache-tomcat-8.5.47 /application/tomcat_8082
[root@docker01 opt]# sed -i 's#8080#8081#g' /application/tomcat_8081/conf/server.xml
[root@docker01 opt]# sed -i 's#8005#8006#g' /application/tomcat_8081/conf/server.xml
[root@docker01 opt]# sed -i 's#8009#8010#g' /application/tomcat_8081/conf/server.xml
[root@docker01 opt]# sed -i 's#8080#8082#g' /application/tomcat_8082/conf/server.xml
[root@docker01 opt]# sed -i 's#8005#8007#g' /application/tomcat_8082/conf/server.xml
[root@docker01 opt]# sed -i 's#8009#8011#g' /application/tomcat_8082/conf/server.xml
[root@docker01 opt]# /application/tomcat/bin/startup.sh
[root@docker01 opt]# /application/tomcat_8081/bin/startup.sh
[root@docker01 opt]# /application/tomcat_8082/bin/startup.sh
#监控
[root@docker01 opt]# ps -ef|grep '/tomcat/'
6、tomcat监控
简单命令
现成脚本
-
通过zabbix进行监控
自定义监控(jmap -heap ID自定义监控)
-
通过jmx
服务端(zabbix-java-gateway)
-
客户端tomcat开启jvm监控功能
#catalina.sh CATALINA_OPS="$CATALINA_OPTS -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=12345 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Djava.rmi.server.hostname=172.16.1.161" #解释说明 CATALINA_OPS="$CATALINA_OPTS 修改tomcat启动参数 -Dcom.sun.management.jmxremote 开启tomcat远程管理功能 -Dcom.sun.management.jmxremote.port=12345 除了12345端口还会生成2个随机端口 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Djava.rmi.server.hostname=172.16.1.161" 指定本机IP地址 jconsole连接查看
-
jps(java ps)
-
jps -lvm
[root@docker01 conf]# jps -lvm 10113 org.apache.catalina.startup.Bootstrap start -Djava.util.logging.config.file=/application/tomcat_8081/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djdk.tls.ephemeralDHKeySize=2048 -Djava.protocol.handler.pkgs=org.apache.catalina.webresources -Dorg.apache.catalina.security.SecurityListener.UMASK=0027 -Dignore.endorsed.dirs= -Dcatalina.base=/application/tomcat_8081 -Dcatalina.home=/application/tomcat_8081 -Djava.io.tmpdir=/application/tomcat_8081/temp 10165 org.apache.catalina.startup.Bootstrap start -Djava.util.logging.config.file=/application/tomcat_8082/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djdk.tls.ephemeralDHKeySize=2048 -Djava.protocol.handler.pkgs=org.apache.catalina.webresources -Dorg.apache.catalina.security.SecurityListener.UMASK=0027 -Dignore.endorsed.dirs= -Dcatalina.base=/application/tomcat_8082 -Dcatalina.home=/application/tomcat_8082 -Djava.io.tmpdir=/application/tomcat_8082/temp 10373 sun.tools.jps.Jps -lvm -Denv.class.path=.:/application/jdk/lib:/application/jdk/jre/lib:/application/jdk/lib/tools.jar -Dapplication.home=/application/jdk1.8.0_11 -Xms8m 10089 org.apache.catalina.startup.Bootstrap start -Djava.util.logging.config.file=/application/tomcat/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djdk.tls.ephemeralDHKeySize=2048 -Djava.protocol.handler.pkgs=org.apache.catalina.webresources -Dorg.apache.catalina.security.SecurityListener.UMASK=0027 -Dignore.endorsed.dirs= -Dcatalina.base=/application/tomcat -Dcatalina.home=/application/tomcat -Djava.io.tmpdir=/application/tomcat/temp
-
jmap
jmap -heap 10165 [root@docker01 conf]# jmap -heap 10165 Attaching to process ID 10165, please wait... Debugger attached successfully. Server compiler detected. JVM version is 25.11-b03 using thread-local object allocation. Mark Sweep Compact GC Heap Configuration: MinHeapFreeRatio = 40 MaxHeapFreeRatio = 70 MaxHeapSize = 478150656 (456.0MB) NewSize = 1310720 (1.25MB) MaxNewSize = 159383552 (152.0MB) OldSize = 30146560 (28.75MB) NewRatio = 2 SurvivorRatio = 8 MetaspaceSize = 21807104 (20.796875MB) CompressedClassSpaceSize = 1073741824 (1024.0MB) MaxMetaspaceSize = 17592186044415 MB G1HeapRegionSize = 0 (0.0MB) Heap Usage: New Generation (Eden + 1 Survivor Space): capacity = 1179648 (1.125MB) used = 203776 (0.1943359375MB) free = 975872 (0.9306640625MB) 17.274305555555557% used Eden Space: capacity = 1048576 (1.0MB) used = 198688 (0.189483642578125MB) free = 849888 (0.810516357421875MB) 18.9483642578125% used From Space: capacity = 131072 (0.125MB) used = 5088 (0.004852294921875MB) free = 125984 (0.120147705078125MB) 3.8818359375% used To Space: capacity = 131072 (0.125MB) used = 0 (0.0MB) free = 131072 (0.125MB) 0.0% used tenured generation: capacity = 30146560 (28.75MB) used = 12813544 (12.219947814941406MB) free = 17333016 (16.530052185058594MB) 42.50416631283967% used 13991 interned Strings occupying 1301008 bytes.
-
jstack(导出java进程信息)
jstack 10165
-
故障案例:系统负载高,发现tomcat占用cpu较高。
- jps/top/htop精确定位哪个java进程导致
- jstack导出java详细信息
- 查看catalina.out日志
- jmap导出jvm信息通过mat进行分析
7、安全优化
-
jvm
#catalina.sh JAVA_OPTS="-Xms256m -Xmx512m -Xss1024K -XX:PermSize=128m -XX:MaxPermSize=256m" #解释 -Xms 为jvm启动时分配的初始内存 比如-Xms200m,表示分配200M -Xmx 为jvm运行分配的最大内存 比如-Xms500m,表示jvm进程最多只能够占用500M内存 -Xss 每个线程堆栈的大小 一般情况下256K是足够了。影响了此进程中并发线程数大小 -XX PermSize=64M JVM初始分配的非堆内存 -XX MaxPermSize=128M JVM最大允许分配的非堆内存,按需分配
-
内存管理机制
堆(Heap)和非堆(Non-heap)内存 按照官方的说法:“Java 虚拟机具有一个堆,堆是运行时数据区域,所有类实例和数组的内存均从此处分配。堆是在 Java 虚拟机启动时创建的。” “在JVM中堆之外的内存称为非堆内存(Non-heap memory)”。 简单来说堆就是Java代码可及的内存,是留给开发人员使用的;非堆就是JVM留给自己用的。 所以方法区、JVM内部处理或优化所需的内存(如JIT编译后的代码缓存)、每个类结构(如运行时常数池、字段和方法数据)以及方法和构造方法的代码都在非堆内存中。 1. 堆内存分配 JVM初始分配的堆内存由-Xms指定,默认是物理内存的1/64; JVM最大分配的堆内存由-Xmx指定,默认是物理内存的1/4。 默认空余堆内存小于40%时,JVM就会增大堆直到-Xmx的最大限制; 空余堆内存大于70%时,JVM会减少堆直到-Xms的最小限制。 因此服务器一般设置-Xms、-Xmx 相等以避免在每次GC 后调整堆的大小。 说明:如果-Xmx 不指定或者指定偏小,应用可能会导致java.lang.OutOfMemory错误,此错误来自JVM,不是Throwable的,无法用try...catch捕捉。 2. 非堆内存分配 JVM使用-XX:PermSize设置非堆内存初始值,默认是物理内存的1/64; 由XX:MaxPermSize设置最大非堆内存的大小,默认是物理内存的1/4。 XX:MaxPermSize设置过小会导致java.lang.OutOfMemoryError: PermGen space 就是内存益出。 说说为什么会内存益出: (1)这一部分内存用于存放Class和Meta的信息,Class在被 Load的时候被放入PermGen space区域,它和存放Instance的Heap区域不同。 (2)GC(Garbage Collection)不会在主程序运行期对PermGen space进行清理,所以如果你的APP会LOAD很多CLASS 的话,就很可能出现PermGen space错误。 这种错误常见在web服务器对JSP进行pre compile的时候
安全优化