omcat是Apache软件基金会(Apache Software Foundation)的Jakarta 项目中的一个核心项目,由Apache、Sun和其他一些公司及个人共同开发而成。
Tomcat服务器是一个免费的开放源代码的Web应用服务器,属于轻量级应用服务器。在中小型系统和并发访问用户不是很多的场合下被普遍应用,是开发和调试jsp程序的首选。
tomcat和nginx、Apache、(httpd)、Lighttpd等web服务器一样,具有处理html页面的功能,另外他还是一个servlet和jsp容器,独立的servlet容器是tomcat的默认模式。不过tomcat处理静态html的能力不如nginx/Apache服务器。
目前Tomcat最新版本为10.0。Java容器还有resin、weblogic等。
使用方案
方案一: Tomcat //单独使用 ----基本不用
方案二: Nginx+Tomcat //反向代理和负载均衡
建议使用Nginx和Tomcat配合,Nginx处理静态,Tomcat处理动态程序
方案三中后端Tomcat可以运行在单独的主机,也可以是同一台主机上的多实例
JDK是 Java 语言的软件开发工具包,主要用于移动设备、嵌入式设备上的java应用程序。JDK是整个java开发的核心,它包含了JAVA的运行环境(JVM+Java系统类库)和JAVA工具。
jdk包含了一批用于java开发的组件,其中包括
jdk中还包括完整的jre(java runtime environment),java运行环境,也被称为private runtime。包括用于产品环境的各种库类,如基础类库rt.jar,以及给开发人员使用的补充库,如国际化与本地化的类库、IDL库等。
JDK下载面页:
http://www.oracle.com/technetwork/java/javase/downloads/index.html
端口:
tomcat自身服务的端口:8005
tomcat和其他应用通信的端口:8009
tomcat给客户端浏览器访问页面使用的端口:8080
JVM 虚拟机常识
作为了解jvm虚拟机的开始。我们有必要弄明白一下两个问题。
所谓虚拟机,就是一台虚拟的计算机。他是一款软件,用来执行一系列虚拟计算机指令。大体上,虚拟机可以分为系统虚拟机和程序虚拟机。大名鼎鼎的VisualBox、VMware就属于系统虚拟机。他们完全是对物理计算机的仿真。提供了一个可以运行完整操作系统的软件平台。
程序虚拟机的典型代表就是Java虚拟机,它专门为执行单个计算机程序而设计,在Java虚拟机中执行的指令我们称为Java字节码指令。无论是系统虚拟机还是程序虚拟机,在上面运行的软件都限制于虚拟机提供的资源中。
同一个JAVA程序(JAVA字节码的集合),通过JAVA虚拟机(JVM)运行于各大主流操作系统平台
比如Windows、CentOS、Ubuntu等。程序以虚拟机为中介,来实现跨平台。
我们要对JVM虚拟机的结构有一个感性的认知。毕竟我们不是编程人员,认知程度达不到那么深入。
类加载子系统
负责从文件系统或者网络中加载Class(类)信息,加载的类信息存放于一块称为方法区的内存空间。除了类信息外,方法区中可能还会存放运行时常量池信息,包括字符串字面量和数字量。
Java堆
在虚拟机启动的时候建立,它是Java程序最主要的内存工作区域。几乎所有的Java对象实例都放Java堆中。堆空间是所有线程共享的,这是一块与Java应用密切相关的内存区间。
Java的NIO库(直接内存)
允许Java程序使用直接内存。直接内存是在Java堆外的、直接向系统申请的内存区间。通常访问直接内存的速度会优于Java堆。因此出于性能考虑,读写频繁的场合可能会考虑使用直接内存。由于直接内存在Java堆外,因此它的大小不会受限于Xmx指定的最大堆大小。但是系统内存是有限的,Java堆和直接内存的总和依然受限于操作系统能给出的最大内存。
垃圾回收系统
垃圾回收系统是Java虚拟机的重要组成部分,垃圾回收器可以对方法区、Java堆和直接内存进行回收。
Java栈
每一个Java虚拟机线程都有一个私有的Java栈。一个线程的Java栈在线程创建的时候被创建。Java保存着帧信息,Java栈中保存着局部变量、方法参数,同时和Java方法的调用、返回密切相关。
JVM中堆空间可以分成三个大区,年轻代、老年代、永久代(方法区)。
新生代(年轻代):新生区
类在这里产生和应用,最后被垃圾回收。所有的类在伊甸区被new出来,当伊甸区满了,GC会对该区不用的对象销毁,剩余有用的转到幸存区。
老年代:老年区(养老区)
用于存放生成周期比较长的对象。
永久代:永久区
存放JDK自带的class,interface。
tomcat和jdk解压即安装。tomcat解析.war包 jdk解析.jar包,tomcat+jdk运行项目,两者版本必须一致
将jdk和tomcat的tar.gz包上传服务器
[root@localhost ~]# ls
anaconda-ks.cfg jdk-8u211-linux-x64.tar.gz apache-tomcat-8.5.69.tar.gz
[root@localhost ~]# tar zxf jdk-8u211-linux-x64.tar.gz -C /usr/loacl
[root@localhost ~]# tar zxf apache-tomcat-8.5.69.tar.gz -C /usr/loacl
[root@localhost ~]# cd /usr/local
将tomcat和jdk的目录改名,方便我们日后的使用可以通过mv改名,也可以通过创建软链接
# ln -s /usr/local/jdk-8u211 /usr/local/java
# ln -s /usr/local/apache-tomcat-8.5.69 /usr/local/tomcat
我选择改名
[root@localhost local]# mv jdk-8u211 java
[root@localhost local]# mv apache-tomcat-8.5.69 tomcat
修改环境变量
[root@localhost local]# vim /etc/profile
....在最后一行添加内容
JAVA_HOME=/usr/local/java
TOMCAT_HOME=/usr/local/tomcat
PATH=$JAVA_HOME/bin:$PATH
PATH=$TOMCAT_HOME/bin:$PATH
export JAVA_HOME TOMCAT_HOME PATH
[root@localhost local]# source /etc/profile 让环境变量生效
检测一下
[root@localhost local]# java -version
java version "1.8.0_211"
Java(TM) SE Runtime Environment (build 1.8.0_211-b12)
Java HotSpot(TM) 64-Bit Server VM (build 25.211-b12, mixed mode)
启动tomcat
两种方法
# /usr/local/tomcat/bin/startup.sh
# /usr/local/tomcat/bin/catalina.sh start
关闭tomcat
# /usr/local/tomcat/bin/shutdown.sh
# /usr/local/tomcat/bin/catalina.sh stop
[root@localhost local]# netstat -lnpt|grep java
tcp6 0 0 :::8080 :::* LISTEN 22846/java
tcp6 0 0 127.0.0.1:8005 :::* LISTEN 22846/java
tcp6 0 0 ::1:8009 :::* LISTEN 22846/java
关于tomcat的端口:
tomcat服务器通过connector连接器组件与客户程序建立连接,connector组件负责接受客户的请求,以及把tomcat服务器的响应结果发送给客户。默认情况下,tomcat在server.xml中配置了两种连接器:
第一个连接器监听的是8080端口,负责建立http连接。通过浏览器访问tomcat服务器的web应用时,使用的就是这个连接器。
第二个连接器监听的是8009端口,负责和其他的http服务器建立连接。在把tomcat与其他http服务器集成时,就需要用到这个端口。
8005是tomcat本身的端口
浏览器访问测试:
[root@localhost ~]# cd /usr/local/tomcat/
[root@localhost tomcat]# tree -L 1
.
├── bin #存放tomcat的管理脚本
├── BUILDING.txt
├── conf #存放tomcat的配置文件的目录
├── CONTRIBUTING.md
├── lib #web应用调用的jar包存放路径
├── LICENSE
├── logs #tomcat日志存放目录,catalina.out日志主要输出日志
├── NOTICE
├── README.md
├── RELEASE-NOTES
├── RUNNING.txt
├── temp #存放临时文件
├── webapps #默认网站发布目录
└── work #存放编译生成的.java与.class文件
[root@localhost tomcat]# cd webapps/
[root@localhost webapps]# tree -L 1
.
├── docs #tomcat的帮助文件
├── examples #web应用实例
├── host-manager #主机管理
├── manager #管理
└── ROOT #默认站点根目录
[root@localhost tomcat]# cd conf/
[root@localhost conf]# tree -L 1
.
├── Catalina
├── catalina.policy
├── catalina.properties
├── context.xml
├── jaspic-providers.xml
├── jaspic-providers.xsd
├── logging.properties
├── server.xml #主配置文件
├── tomcat-users.xml #tomcat 管理用户配置文件
├── tomcat-users.xsd
└── web.xml
Tomcat的配置文件默认存放在/usr/local/tomcat/conf目录中,主要有以下几个:
server.xml: Tomcat的主配置文件,包含Service, Connector, Engine, Realm, Valve, Hosts主组件的相关配置信息;
web.xml:遵循Servlet规范标准的配置文件,用于配置servlet,并为所有的Web应用程序提供包括MIME映射等默认配置信息;
tomcat-user.xml:Realm认证时用到的相关角色、用户和密码等信息;Tomcat自带的manager默认情况下会用到此文件;在Tomcat中添加/删除用户,为用户指定角色等将通过编辑此文件实现;
catalina.policy:Java相关的安全策略配置文件,在系统资源级别上提供访问控制的能力;
catalina.properties:Tomcat内部package的定义及访问相关的控制,也包括对通过类装载器装载的内容的控制;Tomcat6在启动时会事先读取此文件的相关设置;
logging.properties: Tomcat6通过自己内部实现的JAVA日志记录器来记录操作相关的日志,此文件即为日志记录器相关的配置信息,可以用来定义日志记录的组件级别以及日志文件的存在位置等;
context.xml:所有host的默认配置信息;
server.xml: Tomcat的主配置文件,包含server,Service, Connector, Engine, Realm, Valve, Hosts主组件的相关配置信息;
[root@localhost conf]# vim server.xml
这是我将所有注释去掉后的内容
1、 server组件
server是server.xml的根元素,用于创建一个server实例,默认使用的实现类是org.apache.catalina.core.StandarServer。
...
标签属性和子元素:
2、service组件
Service主要用于关联一个引擎和与此引擎相关的连接器,每个连接器通过一个特定的端口和协议接收入站请求交将其转发至关联的引擎进行处理。因此,Service要包含一个引擎、一个或多个连接器。
如上面示例中的定义:
这定义了一个名为Catalina的Service,此名字也会在产生相关的日志信息时记录在日志文件当中。
Service相关的属性:
className: 用于实现service的类名,一般都是org.apache.catalina.core.StandardService。
name:此服务的名称,默认为Catalina;
...
3、Connector组件:
Connector 用于创建链接器实例。默认情况下,server.xml 配置了两个链接器,一个支持HTTP协议,一个支持AJP协议。因此大多数情况下,我们并不需要新增链接器配置, 只是根据需要对已有链接器进行优化。
进入Tomcat的请求可以根据Tomcat的工作模式分为如下两类:
Tomcat应该考虑工作情形并为相应情形下的请求分别定义好需要的连接器才能正确接收来自于客户端的请求。一个引擎可以有一个或多个连接器,以适应多种请求方式。
定义连接器可以使用多种属性,有些属性也只适用于某特定的连接器类型。一般说来,常见于server.xml中的连接器类型通常有4种:
扩展
4、Engine组件:
Engine是Servlet处理器的一个实例,即servlet引擎,默认为定义在server.xml中的Catalina
Engine需要defaultHost属性来为其定义一个接收所有发往非明确定义虚拟主机的请求的host组件。如前面示例中定义的:
...
5、Host组件:
位于Engine容器中用于接收请求并进行相应处理的主机或虚拟主机,如前面示例中的定义:
unpackWars:在启用此webapps时是否对WAR格式的归档文件先进行展开,直接从WAR文件中运行应用程序;默认为true;
autoDeploy:在Tomcat处于运行状态时放置于appBase目录中的应用程序文件是否自动进行deploy;默认为true;
name:当前Host通用的网络名称,必须与DNS服务器上的注册信息一致。 Engine中包含的Host必须存在一个名称与Engine的defaultHost设置一致。
appBase:当前Host的应用基础目录,当前Host上部署的Web应用均在该目录下(可以是绝对目录,相对路径),默认为webapps。
tail -f /usr/local/tomcat/logs/catalina.out
manager] has finished in [21] ms
04-Jul-2019 22:40:00.026 INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory [/data/application/tomcat/webapps/manager]
04-Jul-2019 22:40:00.042 INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory [/data/application/tomcat/webapps/manager] has finished in [16] ms
04-Jul-2019 22:40:00.048 INFO [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler ["http-nio-8080"]
04-Jul-2019 22:40:00.058 INFO [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler ["ajp-nio-8009"]
04-Jul-2019 22:40:00.062 INFO [main] org.apache.catalina.startup.Catalina.start Server startup in 479 ms
发现启动时间较长,其中有一项的启动时间占据了绝大多数
24-Nov-2017 15:09:50.629 INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployWAR Deployment of web application archive /application/apache-tomcat-8.0.27/webapps/memtest.war has finished in 58,892 ms
发现耗时在这里:是session引起的随机数问题导致的。Tocmat的Session ID是通过SHA1算法计算得到的,计算Session ID的时候必须有一个密钥。为了提高安全性Tomcat在启动的时候会通过随机生成一个密钥。
解决Tomcat启动慢的方法
Tomcat启动慢主要原因是生成随机数的时候卡住了,导致tomcat启动不了。
是否有足够的熵来用于产生随机数,可以通过如下命令来查看
[root@java-tomcat1 ~]# cat /proc/sys/kernel/random/entropy_avail
1065
为了加速/dev/random提供随机数的速度,你可以通过操作设备的外设,让其产生大量的中断,网络传输数据,按键,移动鼠标,在命令行敲几个不同的命令,俗称聚气。
方法一:(比较复杂不建议用)
vim $TOMCAT_HOME/bin/catalina.sh ---添加如下内容
if [[ "$JAVA_OPTS" != *-Djava.security.egd=* ]]; then
JAVA_OPTS="$JAVA_OPTS -Djava.security.egd=file:/dev/urandom"
fi
这个系统属性egd表示熵收集守护进程(entropy gathering daemon)
方法二:
yum install rng-tools # 安装rngd服务(熵服务,增大熵池)
systemctl start rngd # 启动服务
安装MySQL(略) 使用mysql(略)/或者使用mariadb
[root@localhost ~]# yum -y install mariadb mariadb-server
[root@localhost ~]# systemctl start mariadb
mariadb使用跟mysql基本相同,mariadb没有出师密码,并且支持使用弱密码
[root@localhost ~]# mysqladmin -u root password '123'
[root@localhost ~]# mysql -u root -p123
MariaDB [(none)]> create database jspgou default charset=stf8;
产品上线,先把产品的压缩包上传到服务器(过程略)
[root@localhost ~]# ls
anaconda-ks.cfg jspgouV6-ROOT.zip
[root@localhost ~]# unzip jspgouV6-ROOT.zip
[root@localhost ~]# ls
anaconda-ks.cfg ROOT jspgouV6-ROOT.zip DB 必读.txt
在将数据导入对应数据库以及更换站点根目录之前我们需要停止tomcat服务,不然会出现错误,如果已经关闭,则不需要关闭
[root@localhost ~]# /usr/local/tomcat/bin/shutdown.sh
[root@localhost ~]# rm -rf /usr/local/tomcat/webapps/ROOT
[root@localhost ~]# cp -r ROOT /usr/local/tomcat/webapps/
然后我们需要更改数据库连接
[root@localhost ~]# vim /usr/local/tomcat/webapps/ROOT/WEB-INF/config/jdbc.properties
....找到以下内容
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://127.0.0.1:3306/jspgou?characterEncoding=UTF-8
jdbc.username=root
jdbc.password=123 #因为数据库与tomcat在一台服务器上,所以我们只需要添加密码就行
接下来把数据导入对应数据库
[root@localhost ~]# ls
anaconda-ks.cfg ROOT jspgouV6-ROOT.zip DB 必读.txt
[root@localhost ~]# cd DB
[root@localhost DB]# ls
jspgou.sql
[root@localhost ~]# mysql -u root -p123 -D jspgou < jspgou.sql
做完上面的步骤后才能启动tomcat
[root@localhost ~]# /usr/loca/tomcat/bin/startup.sh
浏览器访问测试
报错解决
在数据库导入是如果出现以下错误,需要在数据库的配置文件中添加如下内容:
错误:Invalid default value for 'api_call_time'
解决方法:
vim /etc/my.cnf
sql_mode=STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUB
explicit_defaults_for_timestamp=1
修改完配置文件后重新启动服务后在导入数据库
多实例:
1.单机多实例,发布网站的目录不动
2.tomcat在不同服务器上,通过共享网站目录实现不同tomcat主机访问统一网站
同一台服务器
tomcat
webapps------- tomcat
tomcat
Tomcat 一机多实例
多实例运行不同的应用(类似虚拟主机)
多实例运行相同的应用(实现负载均衡,支持高并发处理,session问题)
会话保持(nginx负载均衡算法:ip_hash、sticky)
tomcat单机多实例配置(该实验是以上面那个实验为基础的)
[root@localhost ~]# mdkir -pv /usr/local/tomcat/instance1/{conf,logs,temp,work}
修改8080端口为8081,修改8005端口为8091,注释掉8009端口
[root@localhost ~]# mdkir -pv /usr/local/tomcat/instance2/{conf,logs,temp,work}
修改8080端口为8082,修改8005端口为8092,注释掉8009端口
[root@localhost ~]# /usr/local/tomcat/bin/shutdown.sh
[root@localhost ~]# cp -r /usr/local/tomcat/conf/* /usr/local/tomcat/instance1/conf/
[root@localhost ~]# cp -r /usr/local/tomcat/conf/* /usr/local/tomcat/instance2/conf/
[root@localhost ~]# cp -r /usr/local/tomcat/temp/* /usr/local/tomcat/instance1/temp/
[root@localhost ~]# cp -r /usr/local/tomcat/temp/* /usr/local/tomcat/instance2/temp/
[root@localhost ~]# cp -r /usr/local/tomcat/work/* /usr/local/tomcat/instance1/work/
[root@localhost ~]# cp -r /usr/local/tomcat/work/* /usr/local/tomcat/instance2/work/
每个实例对应的server.xml都要修改 8005 8080;删除8009 【修改网站发布目录】
[root@localhost ~]# vim /usr/local/tomcat/instance1/conf/server.xml
//修改8005
注释8009的配置
......
[root@localhost ~]# vim /usr/local/tomcat/instance2/conf/server.xml
//修改8005
注释8009的配置
......
用脚本管理tomcat实例是最简单的方法,因为每个实例都有一个对应的工作目录也就是(BASE),通过脚本可以对每个实例单独管理,简单方便使用,我们要做的就是修改每个脚本中的BASE和CATALINA_HOME的路径;所以在实例管理整个位置直接使用脚本,不要考虑其他的,在企业中如果用到tomcat多实例,也是用脚本管理,但绝大多数是多台tomcat服务器。
直接使用/usr/local/tomcat/bin/catalina.sh start 只能启动tomcat自身,不能启动tomcat实例
脚本内容这个脚本在每个实例中都要有
[root@localhost ~]# vim /usr/local/tomcat/instance1/ins1.sh
#!/bin/bash
. /etc/init.d/functions
export CATALINA_BASE="/usr/local/tomcat/instance1"
export CATALINA_HOME="/usr/local/tomcat"
case $1 in
start)
$CATALINA_HOME/bin/startup.sh
;;
stop)
$CATALINA_HOME/bin/shutdown.sh
;;
restart)
$CATALINA_HOME/bin/shutdown.sh
sleep 5
$CATALINA_HOME/bin/startup.sh
;;
esac
[root@localhost ~]# vim /usr/local/tomcat/instance2/ins2.sh
#!/bin/bash
. /etc/init.d/functions
export CATALINA_BASE="/usr/local/tomcat/instance2"
export CATALINA_HOME="/usr/local/tomcat"
case $1 in
start)
$CATALINA_HOME/bin/startup.sh
;;
stop)
$CATALINA_HOME/bin/shutdown.sh
;;
restart)
$CATALINA_HOME/bin/shutdown.sh
sleep 5
$CATALINA_HOME/bin/startup.sh
;;
esac
因为我们刚才修改了tomcat的默认发布目录为/webapps,所以我们要把原来的webapps目录拷贝到/目录下
[root@localhost ~]# cp -r /usr/local/tomcat/webapps /
启动测试
[root@localhost ~]# /usr/local/tomcat/bin/startup.sh
[root@localhost ~]# /usr/local/tomcat/instance1/ins1.sh start
[root@localhost ~]# /usr/local/tomcat/instance2/ins2.sh start
[root@localhost ~]# netstat -lnpt|grep java
tcp6 0 0 :::8080 :::* LISTEN 22846/java
tcp6 0 0 :::8081 :::* LISTEN 20631/java
tcp6 0 0 :::8082 :::* LISTEN 20661/java
tcp6 0 0 127.0.0.1:8091 :::* LISTEN 20631/java
tcp6 0 0 127.0.0.1:8092 :::* LISTEN 20661/java
tcp6 0 0 127.0.0.1:8005 :::* LISTEN 22846/java
tcp6 0 0 ::1:8009 :::* LISTEN 22846/java
看到这些内容说明我们的部署成功了,浏览器访问测试
在上面tomcat单机多实例的基础上,我们用另一台服务器部署负载均衡。
在另一台服务器上安装nginx,启动nginx
[root@localhost ~]# vim /etc/nginx/nginx.conf
... 在http全局块添加upstream模块
upstream tomcat {
server 192.168.242.138:8081 weight=1 max_fails=1 fail_timeout=2s;
server 192.168.242.138:8082 weight=1 max_fails=1 fail_timeout=2s;
}
[root@localhost ~]# rm -rf /etc/nginx/conf.d/*
[root@localhost ~]# vim /etc/nginx/conf.d/tomcat.conf
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://tomcat;
proxy_set_header Host $host:$server_port;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
[root@localhost ~]# nginx -s reload
浏览器访问测试
部署tomcat服务,项目做到用https访问,使用nginx去做,访问任意一个子网站,都是https。
(这个实验是单机:tomcat多实例+nginx负载均衡+https),首先,我们要在云服务器上部署好tomcat多实例+nginx负载均衡,实验步骤跟上面几个实验差不多,只有在数据库使用的时候有点区别,我们需要在云数据库RDS上创建对应库,对应用户,将jspgou的初始数据导入对应的库中,然后在每个tomcat实例的/usr/local/tomcat/webapps/ROOT/WEB-INF/config/jdbc.properties文件中,将数据库的ip改为云数据库的私有IP,用户与密码也要对应修改。在浏览器能够正常访问到实例的前提下,我们部署https。
原有的负载均衡地址池以及主配置文件,我们不需要修改,只需要在子配置文件的server块中添加443端口,以及相关配置
[root@ecs-280855 ~]# vim /etc/nginx/conf.d/tomcat.conf
server {
listen 80;
server_name www.dianye.xyz;
location / {
# proxy_pass http://124.71.107.22:8080; 这个代理我们可以取消掉
return 301 https://www.dianye.xyz$request_uri;
}
}
server {
listen 443 ssl;
server_name www.dianye.xyz;
ssl_certificate /etc/nginx/www.dianye.xyz_server.crt;
ssl_certificate_key /etc/nginx/www.dianye.xyz_server.key;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
location / {
proxy_pass http://tomcat;
}
}
排错
云数据库RDS连接不上可能的原因:安全组(ECS+RDS)数据库信息(IP,用户名,密码,库名(需要用户授权)(ECS与RDS是否匹配)),如果有数据导入,确定是否完整;ECS+RDS要在同一个地域,同一个VPC
示例:
[root@ecs-280855 ~]# vim /usr/local/tomcat/conf/server.xml
....
....
日志参数解释:
%a - 远程IP地址
%A - 本地IP地址
%b - 发送的字节数,不包括HTTP头,或“ - ”如果没有发送字节
%B - 发送的字节数,不包括HTTP头
%h - 远程主机名
%H - 请求协议
%l (小写的L)- 远程逻辑从identd的用户名(总是返回' - ')
%m - 请求方法
%p - 本地端口
%q - 查询字符串(在前面加上一个“?”如果它存在,否则是一个空字符串
%r - 第一行的要求
%s - 响应的HTTP状态代码
%S - 用户会话ID
%t - 日期和时间,在通用日志格式
%u - 远程用户身份验证
%U - 请求的URL路径
%v - 本地服务器名
%D - 处理请求的时间(以毫秒为单位)
%T - 处理请求的时间(以秒为单位)
%I (大写的i) - 当前请求的线程名称
GC日志:jvm垃圾回收,记录jvm的运行状态,oom内存溢出的报错信息等。(跟踪JAVA虚拟机的垃圾回收)
[root@java-tomcat1 bin]# vim catalina.sh
在空白地方添加
JAVA_OPTS="$JAVA_OPTS -Xms1024m -Xmx1024m -Xloggc:/usr/local/tomcat/logs/gc-%t.log"
注意:开启GC日志,是为了给开发人员做代码调优用的。
用来查看Java进程的具体状态, 包括进程ID,进程启动的路径及启动参数等等,与unix上的ps类似,只不过jps是用来显示java进程,可以把jps理解为ps的一个子集。
常用参数如下:-q:忽略输出的类名、Jar名以及传递给main方法的参数,只输出pid
-m:输出传递给main方法的参数,如果是内嵌的JVM则输出为null
-l:输出完全的包名,应用主类名,jar的完全路径名
-v:输出传给jvm的参数
注意: 使用jps 时的运行账户要和JVM 虚拟机启动的账户一致。若启动JVM虚拟机是运行的账户为www,那使用jps指令时,也要使用www 用户去指定。 sudo -u www jps
示例:
[root@ecs-280855 ~]# jps -q
20003
758
20151
20250
21725
[root@ecs-280855 ~]# jps -m
20003 Bootstrap start
758 WrapperSimpleApp CloudResetPwdUpdateAgent
20151 Bootstrap start
21737 Jps -m
20250 Bootstrap start
[root@ecs-280855 ~]# jps -l
20003 org.apache.catalina.startup.Bootstrap
21749 sun.tools.jps.Jps
758 org.tanukisoftware.wrapper.WrapperSimpleApp
20151 org.apache.catalina.startup.Bootstrap
20250 org.apache.catalina.startup.Bootstrap
[root@ecs-280855 ~]# jps -v
21761 Jps -Dapplication.home=/usr/local/java -Xms8m
20003 Bootstrap -Djava.util.logging.config.file=/usr/local/tomcat/instance1/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=/usr/local/tomcat/instance1 -Dcatalina.home=/usr/local/tomcat -Djava.io.tmpdir=/usr/local/tomcat/instance1/temp
758 WrapperSimpleApp -Dorg.tanukisoftware.wrapper.WrapperSimpleApp.maxStartMainWait=40 -Xms16m -Xmx64m -Djava.library.path=../lib -Dwrapper.key=-MSCLK_dviFK4d2n -Dwrapper.backend=pipe -Dwrapper.disable_console_input=TRUE -Dwrapper.pid=590 -Dwrapper.version=3.5.26 -Dwrapper.native_library=wrapper -Dwrapper.arch=x86 -Dwrapper.service=TRUE -Dwrapper.cpu.timeout=180 -Dwrapper.jvmid=1
20151 Bootstrap -Djava.util.logging.config.file=/usr/local/tomcat/instance2/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=/usr/local/tomcat/instance2 -Dcatalina.home=/usr/local/tomcat -Djava.io.tmpdir=/usr/local/tomcat/instance2/temp
20250 Bootstrap -Djava.util.logging.config.file=/usr/local/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=/usr/local/tomcat -Dcatalina.home=/usr/local/tomcat -Djava.io.tmpdir=/usr/local/tomcat/temp
有几个参数我们要知道是什么意思
-Xloggc:eclipse_gc.log (设置垃圾回收日志打印的文件,文件名称可以自定义)
-XX:+PrintGCTimeStamps (打印垃圾回收时间信息时的时间格式)
-XX:+PrintGCDetails (打印垃圾回收详情)
-XX:PermSize:设置永久代(perm gen)初始值。默认值为物理内存的1/64。
-XX:MaxPermSize:设置持久代最大值。物理内存的1/4。
-Xms:初始堆大小,默认为物理内存的1/64(<1GB)
-Xmx:最大堆大小
-Xmn:新生代的内存空间大小,注意:此处的大小是(eden+ 2 survivor space)。与jmap -heap中显示的New gen是不同的。整个堆大小=新生代大小 + 老生代大小
jstack用于打印出给定的java进程ID或远程调试服务的Java堆栈信息。此信息通常在运维的过程中被保存起来(保存故障现场),以供 RD (开发人员)们去分析故障。
常用参数如下:
jstack
jstack [-l] //长列表. 打印关于锁的附加信息
jstack [-F] //当’jstack [-l] pid’没有响应的时候强制打印栈信息
上策:优化代码
该项需要开发经验足够丰富,对开发人员要求较高
中策:jvm**优化机制** 垃圾回收机制 把不需要的内存回收
优化jvm--优化垃圾回收策略
优化catalina.sh配置文件。在catalina.sh配置文件中添加以下代码
# tomcat分配1G内存模板
JAVA_OPTS="-Djava.awt.headless=true -Dfile.encoding=UTF-8 -server -Xms1024m -Xmx1024m -XX:NewSize=512m -XX:MaxNewSize=512m -XX:PermSize=512m -XX:MaxPermSize=512m"
# 重启服务
su -c '/home/tomcat/tomcat8_1/bin/shutdown.sh' tomcat
su -c '/home/tomcat/tomcat8_1/bin/startup.sh' tomcat
下策:加足够大的内存
该项的资金投入较大
下下策:每天0**点定时重启tomcat**
使用较为广泛