当前位置: 移动技术网 > IT编程>开发语言>Java > Tomcat构建企业级高负载WEB服务器

Tomcat构建企业级高负载WEB服务器

2020年09月29日  | 移动技术网IT编程  | 我要评论
Tomcat构建企业级高负载WEB服务器1.前言2.Tomcat部署2.1名词解释2.2官网地址2.3架构2.4部署2.5启动脚本3.Tomcat多实例4.JVM常用分析工具(扩展)5.JVM运维实用监控工具(扩展)1.前言什么是JAVA虚拟机所谓虚拟机,就是一台虚拟的计算机。他是一款软件,用来执行一系列虚拟计算机指令。大体上,虚拟机可以分为系统虚拟机和程序虚拟机。大名鼎鼎的VisualBox、VMware就属于系统虚拟机。他们完全是对物理计算机的仿真。提供了一个可以运行完整操作系统的软件平台。

1.前言

什么是JAVA虚拟机

所谓虚拟机,就是一台虚拟的计算机。他是一款软件,用来执行一系列虚拟计算机指令。大体上,虚拟机可以分为系统虚拟机和程序虚拟机。大名鼎鼎的VisualBox、VMware就属于系统虚拟机。他们完全是对物理计算机的仿真。提供了一个可以运行完整操作系统的软件平台。
程序虚拟机的典型代表就是Java虚拟机,它专门为执行单个计算机程序而设计,在Java虚拟机中执行的指令我们称为Java字节码指令。无论是系统虚拟机还是程序虚拟机,在上面运行的软件都呗限制于虚拟机提供的资源中。

JAVA如何做到跨平台

同一个JAVA程序(JAVA字节码的集合),通过JAVA虚拟机(JVM)运行于各大主流操作系统平台比如Windows、CentOS、Ubuntu等。程序以虚拟机为中介,来实现跨平台。
在这里插入图片描述

2.Tomcat部署

2.1名词解释

java容器、web容器,web中间件

Tomcat,Resin,JBOSS,WebSphere(IBM),Weblogic(Oracle )

Tomcat是Apache 软件基金会(Apache Software Foundation)的Jakarta 项目中的一个核心项目,由Apache、Sun 和其他一些公司及个人共同开发而成。由于有了Sun 的参与和支持,最新的Servlet 和JSP 规范总是能在Tomcat 中得到体现,Tomcat 5支持最新的Servlet 2.4 和JSP 2.0 规范。因为Tomcat 技术先进、性能稳定,而且免费,因而深受Java 爱好者的喜爱并得到了部分软件开发商的认可,成为目前比较流行的Web 应用服务器。

Resin是CAUCHO公司的产品,是一个非常流行的支持servlets和jsp的引擎,速度非常快。Resin本身包含了一个支持HTTP/1.1的WEB服务器。它不仅可以显示动态内容,而且它显示静态内容的能力也非常强,速度直逼APACHESERVER。许多站点都是使用该WEB服务器构建的,是一个基于J2EE的开放源代码的应用服务器。 JBoss代码遵循LGPL许可,可以在任何商业应用中免费使用。JBoss是一个管理EJB的容器和服务器,支持EJB 1.1、EJB 2.0和EJB3的规范。但JBoss核心服务不包括支持servlet/JSP的WEB容器,一般与Tomcat或Jetty绑定使用。

WebSphere 是 IBM 的软件平台。它包含了编写、运行和监视全天候的工业强度的随需应变 Web 应用程序和跨平台、跨产品解决方案所需要的整个中间件基础设施,如服务器、服务和工具。WebSphere 提供了可靠、灵活和健壮的软件。

WebLogic是美国Oracle公司出品的一个application server,确切的说是一个基于JAVAEE架构的中间件,WebLogic是用于开发、集成、部署和管理大型分布式Web应用、网络应用和数据库应用的Java应用服务器。将Java的动态功能和Java Enterprise标准的安全性引入大型网络应用的开发、集成、部署和管理之中。

2.2官网地址

tomcat下载地址
http://tomcat.apache.org/
在这里插入图片描述

JDK下载地址
http://www.oracle.com/technetwork/java/javase/downloads/
在这里插入图片描述

2.3架构

方案一

tomcat

方案二

                  Nginx 
                    |
    +-----------------------------+
    |               |             | 		
 Tomcat1 	     Tomcat2 	   Tomcat3
建议使用Nginx和Tomcat配合,Nginx处理静态,Tomcat处理动态程序

2.4部署

  • 1.Tomcat Http Server

环境:
6-8G内存

Ⅰ.部署JAVA环境

建议卸载默认安装的openjdk 软件

Java语言
Java语言的一个非常重要的特点就是与平台的无关性。而使用Java虚拟机是实现这一特点的关键。一般的高级语言如果要在不同的平台上运行,至少需要编译成不同的目标代码。而引入Java语言虚拟机后,Java语言在不同平台上运行时不需要重新编译。Java语言使用Java虚拟机屏蔽了与具体平台相关的信息,使得Java语言编译程序只需生成在Java虚拟机上运行的目标代码(字节码),就可以在多种平台上不加修改地运行。Java虚拟机在执行字节码时,把字节码解释成具体平台上的机器指令执行。这就是Java的能够“一次编译,到处运行”的原因。

JDK
简介:
JDK是 Java 语言的软件开发工具包,主要用于移动设备、嵌入式设备上的java应用程序。
JDK是整个java开发的核心,它包含了JAVA的运行环境(JVM+Java系统类库)和JAVA工具。
包括:
JVM是Java Virtual Machine(Java虚拟机)的缩写,
JVM是一种用于计算设备的规范,它是一个虚构出来的计算机,
是通过在实际的计算机上仿真模拟各种计算机功能来实现的。
JRE为Java Runtime Environment运行环境的简称,Java Runtime Environment(包括Java Plug-in)是Sun的产品,包括两部分:Java Runtime Environment和Java Plug-in。JavaRuntimeEnvironment(JRE)是可以在其上运行、测试和传输应用程序的Java平台。
在这里插入图片描述
JCreator
JCreator是Xinox Software公司开发的一个用于Java程序设计的集成开发环境(IDE),具有编辑、调试、运行Java程序的功能。
在这里插入图片描述

Java SE EE ME

Java SE
Java SE(Java Platform,Standard Edition),应该先说这个,因为这个是标准版本。
JavaSE 可以开发和部署在桌面、服务器、嵌入式环境和实时环境中使用的 Java 应用程序。是EE,和ME的基础。一般就是指JDK。就是Java的基础语法(变量、方法、类之间的调用、关系,继承、接口、线程之类的),工具包(java.util.* ),或者其他的一些封装,是学习其他的基础。

Java EE
Java EE (Java Platform,Enterprise Edition),java 的企业版本。
JavaEE,其实是一套规范,就是用java语言做企业开发(目前看来就是开发一些动态网站,或者对外提供调用服务的网站,或者其他没接触过的。。。)中的一整套规范,比如类怎么封装,网页的请求要用什么方法处理,语言编码一类的处理,拦截器啊什么的定义,请求返回得有什么信息。。。(具体看servlet的接口就知道了)
比如:tomcat就是按照这套规范开发的容器软件,还有什么weblogic,JBoss、Resin等等
正因为我们开发网站(使用JSP,Servelet。。或者封装了这些的框架:SSH。。。)可以放在tomcat,也可以放在JBoss。。。。,因为都是按照一个规范开发的东西,实际使用的还是JavaSE的那些东西,多出来的就是EE的一些规范类的封装代码。

Java ME
Java ME(Java Platform,Micro Edition),java的微型版本。
JavaME 是微型版本,顾名思义,使用在手机啊,小设备啊上面的Java版本,特点就是小,相比JavaSE精简了很大一部分东西,(增加了一些小设备上的专有API,这个不是很确定)。
安卓中既然用的是Java,那么Java的语法应该都是适用的。所以SE是核心基础。其他的都是使用方法方式不同。

解压安装包

[root@localhost ~]# tar xf jdk-8u151-linux-x64.tar.gz -C /usr/local
#8u均可

多版本部署Java

[root@localhost ~]# ln -s /usr/local/jdk1.8.0_151/ /usr/local/java

配置环境变量

[root@localhost ~]# vim /etc/profile
	JAVA_HOME=/usr/local/java
	PATH=$JAVA_HOME/bin:$PATH
	export JAVA_HOME PATH
[root@localhost ~]# source /etc/profile
[root@localhost ~]# env | grep JAVA
	JAVA_HOME=/usr/local/java

测试Java

[root@localhost ~]# java -version
	java version "1.8.0_151"
Java(TM) SE Runtime Environment (build 1.8.0_151-b12)
Java HotSpot(TM) 64-Bit Server VM (build 25.151-b12, mixed mode)

Ⅱ.安装Tomcat

[root@localhost ~]# tar xf apache-tomcat-7.0.42.tar.gz -C /usr/local/
[root@localhost ~]# ln -s /usr/local/apache-tomcat-7.0.42/ /usr/local/tomcat

定义Tomcat所需要的环境变量

[root@localhost ~]# vim /etc/profile
CATALINA_HOME=/usr/local/tomcat
	#Tomcat安装目录
export CATALINA_HOME	
[root@localhost ~]# source /etc/profile

Ⅲ.启动Tomcat

启动tomcat

[root@localhost ~]# bash  /usr/local/tomcat/bin/startup.sh 
	#输出提示
Using CATALINA_BASE: /usr/local/tomcat
Using CATALINA_HOME: /usr/local/tomcat
Using CATALINA_TMPDIR: /usr/local/tomcat/temp
Using JRE_HOME: /usr/local/java
Using CLASSPATH: /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar

检查端口

[root@localhost ~]# netstat -tnlp |grep java
tcp6       0      0 :::8080                 :::*                    LISTEN      1222/java           
tcp6       0      0 127.0.0.1:8005          :::*                    LISTEN      1222/java           
tcp6       0      0 :::8009                 :::*                    LISTEN      1222/java         

关于tomcat端口:
8005
是tomcat本身的端口
8080
tomcat负责建立HTTP连接。在通过浏览器访问Tomcat服务器的Web应用时,使用的就是这个连接器。 
8009
tomcat负责和其他的HTTP服务器建立连接。
如nginx和apache互通时使用

访问

http://192.168.0.104:8080/
注意服务器地址,注意端口
浏览器访问tomcat主页。注意关闭防火墙

关闭tomcat(否则会遇到500)

[root@localhost ~]# bash /usr/local/tomcat/bin/shutdown.sh

Ⅳ.关于Tomcat

tomcat主目录介绍

[root@localhost ~]# cd /usr/local/tomcat
[root@localhost tomcat]# tree -L 1
.
├── bin              #存放tomcat管理脚本
├── conf             # tomcat 配置文件存放目录
├── lib              # web应用调用的jar包存放路径
├── LICENSE
├── logs             # tomcat 日志存放目录,catalina.out 为主要输出日志
├── NOTICE
├── RELEASE-NOTES
├── RUNNING.txt
├── temp             # 存放临时文件
├── webapps          # web程序存放目录
└── work             # 存放编译产生的.java 与 .class文件

webapps目录介绍

[root@localhost tomcat]# cd webapps
[root@localhost webapps]# tree -L 1
.
├── docs            # tomcat 帮助文档
├── examples       # web应用示例
├── host-manager  # 主机管理
├── manager         # 管理
└── ROOT             # 默认站点根目录

默认网站的主目录(主页)

[root@localhost ~]# ls /usr/local/tomcat/webapps/ROOT

Tomcat配置文件目录介绍(conf)

[root@localhost conf]#  tree -L 1
.
├── Catalina
├── catalina.policy
├── catalina.properties
├── context.xml
├── logging.properties
├── logs
├── server.xml           # tomcat 主配置文件
├── server.xml.bak
├── server.xml.bak2
├── tomcat-users.xml    # tomcat 管理用户配置文件
├── tomcat-users.xsd
└── web.xml

Tomcat日志说明

查看日志

[root@localhost ~]# tailf /usr/local/tomcat/logs/catalina.out

发现启动时间较长,其中一项的启动时间占据绝大多数
发现耗时在这里:是session引起的随机数问题导致的。Tocmat的Session ID是通过SHA1算法计算得到的,计算Session ID的时候必须有一个密钥。为了提高安全性Tomcat在启动的时候会通过随机生成一个密钥。

解决tomcat启动慢的方法

Tomcat启动慢主要原因是生成随机数的时候卡住了,导致tomcat启动不了。是否有足够的值来用于产生随机数,可以通过如下命令来查看

[root@localhost ~]# cat /proc/sys/kernel/random/entropy_avail
6
[root@localhost ~]# vim $JAVA_HOME/jre/lib/security/java.security
securerandom.source=file:/dev/random
改为
securerandom.source=file:/dev/urandom
  • 2.安装MySQL
[root@localhost ~]# yum install -y mariadb-server mariadb
#该步骤出错,检查yum源配置
[root@localhost ~]# systemctl start mariadb
[root@localhost ~]# mysqladmin -u root password 123
[root@localhost ~]# mysql -u root -p123
MariaDB [(none)]> create database jspgou character set = utf8;
MariaDB [(none)]> show create database jspgou; 
#查看创建过程
  • 3.部署jspgou电子商城

Ⅰ.解压源码包

[root@localhost ~]# unzip jspgouV6-ROOT.zip 

Ⅱ.更改数据库链接

提示:在解压缩后的文件中,修改连接数据库的信息

[root@localhost local]# vim ROOT/WEB-INF/config/jdbc.properties 
jdbc.url=jdbc:mysql://127.0.0.1:3306/jspgou?characterEncoding=UTF-8
jdbc.username=root
jdbc.password=123

Ⅲ.导入数据

[root@localhost ~]# mysql -u root -p123 -D jspgou  < DB/jspgou.sql

使用MySQL数据库时,可能会发生错误
使用MySQL作为数据库时,如果导入数据失败
1.修改mysql配置文件
my.cnf中的max_allowed_packet参数为64m,默认为1m
2.DB/jspgou.sql里面的默认值改一下
把所有datetime类型的字段默认值改为CURRENT_TIMESTAMP

将程序解压后的ROOT文件夹,拷贝到tomcat安装目录下的webapps文件夹下

[root@localhost ~]# \cp -r ROOT  /usr/local/tomcat/webapps/
	#不使用cp的别名。 alias cp=‘cp -i’

Ⅳ.部署网站

启动tomcat

[root@localhost ~]# bash /usr/local/tomcat/bin/startup.sh

输入以下地址:
http://192.168.0.104:8080/jeeadmin/jspgou/index.do
注意服务器地址
用户名:admin
密 码:123456
在这里插入图片描述
在这里插入图片描述

2.5启动脚本

1.创建启动脚本
# vim /etc/init.d/tomcat
#!/bin/bash
# Init file for Tomcat server daemon					
#																		
# chkconfig: 2345 96 14								    	
# description: Tomcat server daemon			    	
JAVA_OPTS='-Xms64m -Xmx128m'						
JAVA_HOME=/usr/java/jdk1.7.0_11/				    	
CATALINA_HOME=/usr/local/tomcat				    	
export JAVA_OPTS JAVA_HOME CATALINA_HOME  
exec $CATALINA_HOME/bin/catalina.sh $*			

2.修改权限
# chmod a+x /etc/init.d/tomcat 

3.添加到chkconfig管理
# chkconfig --add tomcat
# chkconfig tomcat --list
tomcat          0:关闭  1:关闭  2:启用  3:启用  4:启用  5:启用  6:关闭
# chkconfig tomcat on
# 
# service tomcat stop
Using CATALINA_BASE:   /usr/local/tomcat
Using CATALINA_HOME:   /usr/local/tomcat
Using CATALINA_TMPDIR: /usr/local/tomcat/temp
Using JRE_HOME:        /usr/java/jdk1.7.0_11
Using CLASSPATH:       /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar

# service tomcat start
Using CATALINA_BASE:   /usr/local/tomcat
Using CATALINA_HOME:   /usr/local/tomcat
Using CATALINA_TMPDIR: /usr/local/tomcat/temp
Using JRE_HOME:        /usr/java/jdk1.7.0_11
Using CLASSPATH:      /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar

3.Tomcat多实例

关闭主站

[root@localhost ~]# bash /usr/local/tomcat/bin/shutdown.sh 

准备多实例主目录

[root@localhost ~]# mkdir  /usr/local/tomcat/instance{1..3}

制作实例工作目录

[root@localhost ~]# cp -r /usr/local/tomcat/{conf,logs,temp,work} /usr/local/tomcat/instance1/
[root@localhost ~]# cp -r /usr/local/tomcat/{conf,logs,temp,work} /usr/local/tomcat/instance2/
[root@localhost ~]# cp -r /usr/local/tomcat/{conf,logs,temp,work} /usr/local/tomcat/instance3/
[root@localhost ~]# tree -d -L 2 /usr/local/tomcat/
/usr/local/tomcat/
├── bin
├── instance1
│   ├── conf
│   ├── logs
│   ├── temp
│   └── work
├── instance2
│   ├── conf
│   ├── logs
│   ├── temp
│   └── work
├── instance3
│   ├── conf
│   ├── logs
│   ├── temp
│   └── work
└── lib

修改端口

#将web配置文件拷贝3份,分别修改为不同端口
[root@localhost ~]# vim /usr/local/tomcat/instance1/conf/server.xml
#服务端口8080改为8081
#修改前
 <!--   <Connector port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" />        -->
#修改后
<Connector port="8081" protocol="HTTP/1.1" 
               connectionTimeout="20000"
               redirectPort="8443" />		-->
               
#程序工作端口
<!-- <Server port="8005" shutdown="SHUTDOWN"> -->
#8005改为8091
<!-- <Server port="8091" shutdown="SHUTDOWN"> -->

#网站目录
appBase="webapps"
#替换成另一个目录
appBase="/webapps"

[root@localhost ~]# cp /usr/local/tomcat/instance1/conf/server.xml  /usr/local/tomcat/instance2/conf/
<Connector port="8081" protocol="HTTP/1.1"  
#服务端口替换成 8082
<Connector port="8082" protocol="HTTP/1.1"  

<Server port="8091" shutdown="SHUTDOWN">
#程序工作端口替换成 8092
<Server port="8092" shutdown="SHUTDOWN">

[root@localhost ~]# cp /usr/local/tomcat/instance1/conf/server.xml  /usr/local/tomcat/instance3/conf/
<Connector port="8081" protocol="HTTP/1.1"  
#服务端口替换成 8083
<Connector port="8083" protocol="HTTP/1.1"  

<Server port="8091" shutdown="SHUTDOWN">
#程序工作端口替换成 8093
<Server port="8093" shutdown="SHUTDOWN">

启动脚本

[root@localhost ~]# vim /usr/local/tomcat/instance1/ins1.sh
#function系统自带脚本,功能函数。
#!/bin/bash
#instance1
. /etc/init.d/functions
export CATALINA_BASE="/usr/local/tomcat/instance1"

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
export JAVA_OPTS='-Xms64m -Xmx128m'

[root@localhost ~]# cp /usr/local/tomcat/instance1/ins1.sh /usr/local/tomcat/instance2/ins2.sh
#!/bin/bash
#instance2              #####
. /etc/init.d/functions
export CATALINA_BASE="/usr/local/tomcat/instance2"    #####

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 ~]# cp /usr/local/tomcat/instance1/ins1.sh /usr/local/tomcat/instance3/ins3.sh
#!/bin/bash
#instance3
. /etc/init.d/functions
export CATALINA_BASE="/usr/local/tomcat/instance3"

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
export JAVA_OPTS='-Xms64m -Xmx128m'

赋权

[root@localhost ~]# chmod +x /usr/local/tomcat/instance1/ins1.sh 
[root@localhost ~]# chmod +x /usr/local/tomcat/instance2/ins2.sh 
[root@localhost ~]# chmod +x /usr/local/tomcat/instance3/ins3.sh 

网站源码

[root@localhost ~]# mkdir /webapps
[root@localhost ~]# cp -r /usr/local/tomcat/webapps/ROOT/ /webapps/

启动

[root@localhost ~]# /usr/local/tomcat/instance1/ins1.sh start
[root@localhost ~]# /usr/local/tomcat/instance2/ins2.sh start
[root@localhost ~]# /usr/local/tomcat/instance3/ins3.sh start

测试

[root@localhost ~]# netstat -antp | grep 8081
[root@localhost ~]# netstat -antp | grep 8082
[root@localhost ~]# netstat -antp | grep 8083
[root@localhost ~]# netstat -antp | grep 8091
[root@localhost ~]# netstat -antp | grep 8092
[root@localhost ~]# netstat -antp | grep 8093

浏览

http://192.168.0.104:8081
http://192.168.0.104:8082
http://192.168.0.104:8083

4.JVM常用分析工具(扩展)

4.1jps

简介

用来查看所有的jvm进程,包括进程ID,进程启动的路径等。
jps(Java Virtual Machine Process Status Tool)是JDK 1.5提供的一个显示当前所有java进程pid的命令,简单实用,非常适合在linux/unix平台上简单察看当前java进程的一些简单情况。
ps命令我们经常用到,这个命令主要是用来显示当前系统的进程情况。比如有哪些进程及其 id。jps命令也是一样,它的作用是显示当前系统的java进程情况及其id号。我们可以通过它来查看我们到底启动了几个java进程(因为每一个java程序都会独占一个java虚拟机实例)以及他们的进程号(为下面几个程序做准备),并可通过opt来查看这些进程的详细启动参数。

语法

jps [-q] [-mlvV] [<hostid>]
-q  安静,只显示pid,不显示class名称,jar文件名和传递给main 方法的参数
-m  输出传递给main 方法的参数,在嵌入式jvm上可能是null
-l (显示完整路径)
-v (显示传递给JVM的命令行参数)
-V (显示通过flag文件传递给JVM的参数)
hostid是主机id,默认localhost

例子

[root@localhost ~]# jps 
4214 Bootstrap 
18096 jar 
26423 Jps 
#默认显示 进程ID 和 启动类的名称

[root@localhost ~]# jps -q 
4214 
18096 
26438 
#-q 只输出进程ID,而不显示出类的名称

[root@localhost ~]# jps -m 
4214 Bootstrap start 
18096 jar 
26453 Jps -m 
#-m 可以输出传递给 Java 进程(main 方法)的参数

[root@localhost ~]# jps -l 
4214 org.apache.catalina.startup.Bootstrap 
18096 logmon.jar 
26468 sun.tools.jps.Jps 
#-l 可以输出主函数的完整路径(类的全路径)

[root@localhost ~]# jps -v 
#-v 可以显示传递给 Java 虚拟机的参数。

[root@localhost ~]# jps -V 
4214 Bootstrap 
26512 Jps 
18096 jar
#-V 显示通过flag文件传递给JVM的参数

4.2jinfo

简介

负责观察进程运行环境参数,包括Java System属性和JVM命令行参数。当系统崩溃时,jinfo可以从core文件里面知道崩溃的Java应用程序的配置信息。

语法

jinfo [ option ] pid
jinfo [ option ] executable core
jinfo [ option ] [server-id@]remote-hostname-or-IP
pid   进程号
executable    产生 core dump 的 java executable
core   core file
remote-hostname-or-IP   主机名或ip
server-id   远程主机上的debug server的唯一id
-flags         打印命令行参数
-sysprops      打印系统属性

例子

[root@localhost ~]# jinfo 4214 
#这个命令包含了 JDK 和 JVM 运行起来时的一些属性,4214 JAVA进程号。

4.3jstack

简介

用来观察 jvm 中当前所有线程的运行情况和线程当前状态。

语法

jstack [ option ] pid
jstack [ option ] executable core
jstack [ option ] [server-id@]remote-hostname-or-IP
core 将被打印信息的core dump文件
remote-hostname-or-IP 远程debug服务的主机名或ip
server-id 唯一id,假如一台主机上多个远程debug服务
pid    需要被打印配置信息的java进程id,可以用jps查询
-F     当’jstack [-l] pid’没有相应的时候强制打印栈信息
-l     长列表. 打印关于锁的附加信息,例如属于java.util.concurrent的ownable synchronizers列表.
-m     打印java和native c/c++框架的所有栈信息.

例子

[root@localhost ~]# jstack -F 18096 
#18096  JAVA进程号

4.4jstat

简介

用于输出指定 java 进程的统计信息
利用JVM内建的指令对Java应用程序的资源和性能进行实时的命令行的监控,包括了对进程的classloader,compiler情况;可以用来监视VM内存内的各种堆和非堆的大小及其内存使用量,以及加载类的数量。

语法

jstat -<option> [-t] [-h<lines>] <vmid> [<interval> [<count>]]
class:统计classloader的行为
compiler:统计hotspot just-in-time编译器的行为
gc:统计gc行为
gccapacity:统计堆中代的容量、空间
gccause:垃圾收集统计,包括最近引用垃圾收集的事件,基本同gcutil,比gcutil多了两列
gcnew:统计新生代的行为
gcnewcapacity:统计新生代的大小和空间
gcold:统计旧生代的行为
gcoldcapacity:统计旧生代的大小和空间
gcpermcapacity:统计永久代的大小和空间
gcutil:垃圾收集统计
printcompilation:hotspot编译方法统计
-h n 每n个样本,显示header一次
-t n 在第一列显示时间戳列,时间戳时从jvm启动开始计算
<vmid>   就是进程号
<interval> interval是监控时间间隔,单位为微妙,不提供就意味着单次输出
<count>      count是最大输出次数,不提供且监控时间间隔有值的话, 就无限打印

例子

[root@localhost ~]# jstat -class 4214 2000 10 
	#(每隔2秒监控一次,一共做10次) 
	Loaded Bytes Unloaded Bytes  Time 
	9197   18418.   0 0    0.0  12.49 
	9197   18418.   0 0    0.0  12.49
	
	列名介绍:
	Column 	Description
	Loaded 	被读入类的数量
	Bytes 	被读入的字节数(K)
	Unloaded 	被卸载类的数量
	Bytes 	被卸载的字节数(K)
	Time 	花费在load和unload类的时间

4.5jmap

简介

用来监视进程运行中的jvm物理内存的占用情况,该进程内存内,所有对象的情况,例如产生了哪些对象,对象数量。当系统崩溃时,jmap 可以从core文件或进程中获得内存的具体匹配情况,包括Heap size, Perm size等。

语法

jmap [option] <pid>
jmap [option] <executable <core>
jmap [option] [server_id@]<remote server IP or hostname>
-dump:format=b,file=<filename> pid    
# dump堆到文件,format指定输出格式,live指明是活着的对象,file指定文件名
-finalizerinfo  
# 打印等待回收对象的信息
-heap           
# 打印heap的概要信息,GC使用的算法,heap的配置及wise heap的使用情况,可以用此来判断内存目前的使用情况以及垃圾回收情况
-histo[:live]   
# 打印堆的对象统计,包括对象数、内存大小等等 (因为在dump:live前会进行full gc,因此不加live的堆大小要大于加live堆的大小 )
-permstat       
# 打印classload类装载器和 jvm heap长久层的信息. 包含包括每个装载器的名字,活跃,地址,父装载器,和其总共加载的类大小。另外,内部String的数量和占用内存数也会打印出来. 
-F              
# 强制,强迫.在pid没有相应的时候使用-dump或者-histo参数. 在这个模式下,live子参数无效.  
-J              
# 传递参数给jmap启动的jvm. ,如:-J-Xms256m

例子

[root@localhost ~]# jmap -heap 4214 
	Attaching to process ID 4214, please wait... 
	Debugger attached successfully. 
	Server compiler detected. 
	JVM version is 24.55-b03 
	 
	using parallel threads in the new generation. 
	using thread-local object allocation. 
	Concurrent Mark-Sweep GC 
	 
	Heap Configuration:                        # 堆配置情况
	MinHeapFreeRatio = 40                      #  最小堆的使用比例
	MaxHeapFreeRatio = 70                      # 最大堆的可用比例
	MaxHeapSize = 2684354560 (2560.0MB)        # 最大堆空间大小
	NewSize = 713031680 (680.0MB)              # 新生代分配大小
	MaxNewSize = 713031680 (680.0MB)           # 最大可用新生代分配大小 
	OldSize = 5439488 (5.1875MB)               # 老年代大小
	NewRatio = 2                               # 新生代比例
	SurvivorRatio = 8                          # 新生代与suvivor的比例
	PermSize = 251658240 (240.0MB)             # perm区大小
	MaxPermSize = 251658240 (240.0MB)          # 最大可分配perm区大小
	G1HeapRegionSize = 0 (0.0MB)               # G1堆区大小
	 
	Heap Usage:                                # 堆使用情况
	New Generation (Eden + 1 Survivor Space):  # 新生代(伊甸区 + survior空间)
	capacity = 641728512 (612.0MB)             # 伊甸区容量
	used = 507109064 (483.6168899536133MB)     # 已经使用大小
	free = 134619448 (128.38311004638672MB)    # 剩余容量
	79.0223676394793% used                     # 使用比例
	Eden Space:                                # 伊甸区
	capacity = 570425344 (544.0MB)             # 伊甸区容量
	used = 503156488 (479.84741973876953MB)    # 伊甸区使用
	free = 67268856 (64.15258026123047MB)      # 伊甸区当前剩余容量
	88.2072462755091% used                     # 伊甸区使用情况
	From Space:                                # survior1区
	capacity = 71303168 (68.0MB)               # survior1区容量
	used = 3952576 (3.76947021484375MB)        # surviror1区已使用情况
	free = 67350592 (64.23052978515625MB)      # surviror1区剩余容量
	5.543338551240809% used                    # survior1区使用比例
	To Space:                                  # survior2 区
	capacity = 71303168 (68.0MB)               # survior2区容量
	used = 0 (0.0MB)                           # survior2区已使用情况
	free = 71303168 (68.0MB)                   # survior2区剩余容量
	0.0% used                                  # survior2区使用比例
	concurrent mark-sweep generation:          # 老生代使用情况
	capacity = 1971322880 (1880.0MB)           # 老生代容量
	used = 1514740296 (1444.5689163208008MB)   # 老生代已使用容量
	free = 456582584 (435.4310836791992MB)     # 老生代剩余容量
	76.83877214472345% used                    # 老生代使用比例
	Perm Generation:                           # perm区使用情况
	capacity = 251658240 (240.0MB)             # perm区容量
	used = 57814400 (55.1361083984375MB)       # perm区已使用容量
	free = 193843840 (184.8638916015625MB)     # perm区剩余容量
	22.973378499348957% used                   # perm区使用比例
	 
	28645 interned Strings occupying 3168232 bytes.

5.JVM运维实用监控工具(扩展)

VirtualVM

简介

VisualVM 是一款免费的性能分析工具。它通过 jvmstat、JMX、SA(Serviceability Agent)以及 Attach API 等多种方式从程序运行时获得实时数据,从而进行动态的性能分析。同时,它能自动选择更快更轻量级的技术尽量减少性能分析对应用程序造成的影响,提高性能分析的精度。

性能分析的主要方式

监视

监视是一种用来查看应用程序运行时行为的一般方法。通常会有多个视图(View)分别实时地显示 CPU 使用情况、内存使用情况、线程状态以及其他一些有用的信息,以便用户能很快地发现问题的关键所在。

转储

转储:性能分析工具从内存中获得当前状态数据并存储到文件用于静态的性能分析。Java 程序是通过在启动 Java 程序时添加适当的条件参数来触发转储操作的。它包括以下三种:

系统转储:JVM 生成的本地系统的转储,又称作核心转储。一般的,系统转储数据量大,需要平台相关的工具去分析,如 Windows 上的 windbg 和 Linux 上的 gdb。

Java 转储:JVM 内部生成的格式化后的数据,包括线程信息,类的加载信息以及堆的统计数据。通常也用于检测死锁。
堆转储:JVM 将所有对象的堆内容存储到文件

快照

快照:应用程序启动后,性能分析工具开始收集各种运行时数据,其中一些数据直接显示在监视视图中,而另外大部分数据被保存在内部,直到用户要求获取快照,基于这些保存的数据的统计信息才被显示出来。快照包含了应用程序在一段时间内的执行信息,通常有 CPU 快照和内存快照两种类型。

CPU 快照:主要包含了应用程序中函数的调用关系及运行时间,这些信息通常可以在 CPU 快照视图中进行查看。

内存快照:主要包含了内存的分配和使用情况、载入的所有类、存在的对象信息及对象间的引用关系等。这些信息通常可以在内存快照视图中进行查看。

性能分析

性能分析:性能分析是通过收集程序运行时的执行数据来帮助开发人员定位程序需要被优化的部分,从而提高程序的运行速度或是内存使用效率,主要有以下三个方面:

CPU 性能分析:CPU 性能分析的主要目的是统计函数的调用情况及执行时间,或者更简单的情况就是统计应用程序的 CPU 使用情况。通常有 CPU 监视和 CPU 快照两种方式来显示 CPU 性能分析结果。

内存性能分析:内存性能分析的主要目的是通过统计内存使用情况检测可能存在的内存泄露问题及确定优化内存使用的方向。通常有内存监视和内存快照两种方式来显示内存性能分析结果。

线程性能分析:线程性能分析主要用于在多线程应用程序中确定内存的问题所在。一般包括线程的状态变化情况,死锁情况和某个线程在线程生命期内状态的分布情况等

图示

内存分析
在这里插入图片描述
在这里插入图片描述

CPU分析
在这里插入图片描述

线程分析
在这里插入图片描述

快照功能
在这里插入图片描述

转储功能
线程转储的生成与分析
VisualVM 能够对正在运行的本地应用程序生成线程转储,把活动线程的堆栈踪迹打印出来,帮助我们有效了解线程运行的情况,诊断死锁、应用程序瘫痪等问题。
在这里插入图片描述

本文地址:https://blog.csdn.net/qq_43734923/article/details/108837057

如您对本文有疑问或者有任何想说的,请点击进行留言回复,万千网友为您解惑!

相关文章:

验证码:
移动技术网