jmeter工具进行性能测试

jmeter工具进行性能测试

  • 性能测试理论概述
    • 背景
    • 性能测试指标
      • TPS
      • 平均响应时间
      • TOP响应时间
      • 其他指标
    • 性能监控指标
    • 性能测试流程
  • jmeter工具
    • jmeter常用组件
    • jmeter命令行运行
      • 基础知识
      • 命令行执行
      • 性能测试理论
  • Linux环境部署
    • Mysql
    • Tomcat
      • Tomcat 安装配置(原生方式)
      • Tomcat 安装配置(虚拟主机方式)
    • Nginx
      • Nginx 安装
      • Nginx 配置
      • Nginx 访问日志配置
      • Nginx 负载均衡策略配置
    • Redis
      • Redis安装
      • Redis 配置
      • Redis 启动
      • Redis常用命令
      • Redis持久化
      • 多实例部署
      • Redis 主从关系配置
      • Redis 其他配置
  • 性能监控
    • 操作系统监控
      • CPU
      • 内存
      • 网络
      • 磁盘
        • 磁盘io
        • 磁盘空间
      • 综合监控工具
        • vmstat
        • dstat
        • nmon
        • spotlight
        • 普罗米修斯
    • 程序监控
      • Java线程监控
        • Jvisualvm
        • jstack工具
      • JVM监控
        • 命令行工具
        • 图形界面
    • Redis监控
      • info
      • redis-stat
    • Nginx监控
      • netstat
    • Mysql监控
  • JVM内存结构和垃圾回收
    • JVM内存结构
      • 栈内存
      • 堆内存
      • 永久代
    • 垃圾回收-GC
      • 堆垃圾回收
        • 堆垃圾回收算法
      • 永久代的垃圾回收
      • 垃圾收集器
        • Serial收集器
        • ParNew收集器
        • CMS收集器
        • G1
    • 内存溢出
  • 性能案例分析
    • 内存泄露
    • 线程死锁
    • 线程阻塞
      • Log4j的线程阻塞问题
    • 响应时间过长
    • 数据库性能问题
      • 索引
      • 慢查询
      • 执行计划
      • 联合索引
      • 连接数
    • CPU消耗过高
  • 项目实战

性能测试理论概述

背景

性能测试的意义:
现状
互联网行业发展快,用户量大大增加;业务和系统架构越来越复杂,数据越来越多,用户不仅仅满足于功能的实现,在某些场景下,更在意系统性能。

什么是性能测试:
通过一定的手段,在多并发下情况下,获取被测系统的各项性能指标,验证被测系统在高并发下的处理能力、响应能力,稳定性等,能否满足预期。定位性能瓶颈,排查性能隐患,保障系统的质量,提升用户体验

什么样的系统需要做性能测试
◼ 用户量大,PV比较高的系统
◼ 系统核心模块/接口
◼ 业务逻辑/算法比较复杂
◼ 促销/活动推广计划
◼ 新系统,新项目
◼ 线上性能问题验证和调优
◼ 新技术选型
◼ 性能容量评估和规划
◼ 日常系统性能回归

性能测试指标

TPS

事务
在性能测试领域里,衡量一个系统性能的好坏,主要看的是单位时间内,系统可以处理多少业务量。各个系统的业务各不相同,为了方便使用统一指标来衡量业务的性能。用事务来代表业务操作,一个事务可以代表一个业务,也可以代表多个业务操作。事务是用户定义的,想测试什么业务的性能,就把该业务加到事务中。
单个接口和多个接口都定义为一个事务。

TPS/QPS(Transaction Per Second): 每秒处理的事务数

平均响应时间

jmeter工具进行性能测试_第1张图片

响应时间=网络传输的总时间+各组件业务处理时间
平均响应时间:测试过程中所有请求的平均耗时

TOP响应时间

将所有请求的响应时间先从大到小进行排序,计算指定比例的请求都是小于某个时间。该指标统计的是大多数请求的耗时。
Tp90(90%响应时间):90%的请求耗时都低于某个时间
Tp95(95%响应时间):95%的请求耗时都低于某个时间
Tp99(99%响应时间):99%的请求耗时都低于某个时间

其他指标

并发数/虚拟用户(Vuser):压测工具中设置的并发线程/进程数量
成功率:请求的成功率
PV(Page View):页面/接口的访问量
UV(Unique Visitor):页面/接口的每日唯一访客
吞吐量:网络中上行和下行的流量总和,吞吐量代表网络的流量,TPS越高,吞吐量越大
吞吐量单位一般为兆

TPS、响应时间、并发数的关系:
TPS=并发数/响应时间(响应时间单位为秒)

在系统达到性能瓶颈之前,TPS和并发数成正比关系
jmeter工具进行性能测试_第2张图片

性能监控指标

操作系统级别监控:
CPU使用率、内存使用率、网络IO(input/output)、磁盘(read/write/util)

中间件监控:
连接数、长短连接、使用内存

应用层监控:
线程状态、JVM参数、GC频率、锁

DB层监控:
连接数、锁、缓存、内存、SQL效率

性能测试流程

需求调研
测试计划
环境搭建
数据准备
脚本编写
压测执行
调优回归
测试报告

Created with Raphaël 2.2.0 开始 需求调研: 项目背景、测试范围、业务逻辑 & 数据流向、系统架构、配置信息、测试数据量(量级要一致) 外部依赖、系统使用场景,业务比例、日常业务量、预期指标、上线时间 测试计划: 项目描述、业务模型及性能指标、测试环境说明、测试资源、 测试方法以及场景设计原则:基准测试、单交易负载测试、混合场景测试、高可用性测试、异常 场景测试、稳定性测试、其他特殊场景 测试进度安排及测试准则 环境搭建: 测试机器硬件配置尽量和线上一致、系统版本与线上一致、测试环境部署线上最小单元模块、应 用 中间件 数据库配置要与线上一致、其他特殊配置 数据准备: 测试数据分为两部分:基础数据和参数化数据 通常采用以下三种方法进行构造 业务接口:适合数据表关系复杂;优点:数据完整性比较好 存储过程:适合表数量少,简单;优点:速度最快 脚本导入:适合数据逻辑复杂; 自由度比较高 脚本编写: 选择工具(Loadrunner、Jmeter、Locust等)、选择协议(Http、TCP、RPC)、参数化、关联 检查点、事务判断 压测执行: Linux机器内核参数优化、分布式执行、监控 -- Linux -- Jvm -- 数据库、收集测试结果、数据分析、瓶颈定位 调优回归: 性能调优需要整个团队完成 反复尝试、回归验证、监控工具、全链路排查、日志分析、模块隔离 测试报告: 概述、测试环境、结果与分析、调优说明、项目时间表、结论、建议 结束

jmeter工具

jmeter常用组件

组件使用参jmeter工具

jmeter命令行运行

基础知识

Jmeter线程组两种运行模式:
◼ 按照运行次数运行:线程组设置循环x次
◼ 按照运行时间运行
1> 线程组设置循环永远
2> 勾选调度器,设置持续时间,单位

线程组和请求设置逻辑:
关键逻辑
◼ 一个线程组内的多个请求是顺序执行的
◼ 不同线程组内的请求是并行执行的
实际工作中如何设置线程组和请求的关系?
◼ 如果多个接口之间没有强依赖关系,每个接口单独设置一个线程组
◼ 如果多个接口之间有依赖关系(数据关联),把有关联关系的接口按照顺放在同一个线程组内

jmeter工具进行性能测试_第3张图片

压力机:产生压力的机器,即jmeter所在的系统,可以是Windows系统或Linux系统。
服务器:部署项目的系统
压力机和服务器不能是一台机器
jmeter工具进行性能测试_第4张图片

命令行执行

准备工作

1,压力机安装并配置好JDK、jmeter:
(1)上传jdk-8u221-linux-x64.tar.gz和 apache-jmeter-5.1.1.zip到Linux的/usr/local目录下
(2)解压:tar xvf jdk-8u221-linux-x64.tar.gz unzip apache-jmeter-5.1.1.zip
(3)修改配置文件:vi /etc/profile
(4)光标移动到最后一行,添加以下配置
JAVA_HOME=/usr/local/tools/jdk1.8.0_241
JMETER_HOME=/usr/local/tools/apache-jmeter-5.1.1
CLASSPATH=$:CLASSPATH:$JAVA_HOME/lib/
PATH=$PATH:$JAVA_HOME/bin:$JMETER_HOME/bin
export PATH JAVA_HOME CLASSPATH
jmeter工具进行性能测试_第5张图片
(5)退出vi,执行命令source /etc/profile,让配置生效
(6)进到Jmeter 根目录下需要添加执行权限 chmod +x ./*
(7)执行java-version、jmeter -v命令,如果能看到版本信息,配置成功

3、将项目pinter.jar上传至Linux服务器,启动项目
4,在windows下调试好jmeter脚本,并上传至Linux下

Jmeter参数优化
文件路径:/usr/local/tools/apache-jmeter-5.1.1/bin/jmeter.properties
1,控制台取样间隔的设置
summariser.interval=10,默认为30s,最低可修改为6s
2,Jvm参数优化
bin目录下,vi jmeter,修改HEAP的size大小,默认1024M,可以设置成2048M(前提是内存够)
HEAP="-Xms2g -Xmx2g -XX:MaxMetaspaceSize=256m“
3,默认编码修改
sampleresult.default.encoding=UTF-8

单机器测试步骤
jmeter -n -t pinter.jmx -l result.jtl
-n: 命令行模式启动jmeter,no-gui
-t:jmx脚本路径;
-l:jtl结果文件存放路径

概要日志:
jmeter工具进行性能测试_第6张图片
分布式测试步骤
分布式压测:多台压力机同时对服务器施加压力。

分布式测试步骤:
系统、etc/hosts文件中进行类似 本机IP 主机名的配置,如10.0.0.23 zhoucentos,否则启动jmeter server会报错!
jmeter工具进行性能测试_第7张图片

1,在每台机器上都部署 jmeter
2,如果是java脚本,将java脚本和相关lib包都放在jmeter目录lib/ext下
3,将jmeter的场景文件jmx上传到主jmeter的任意位置,参数文件放到每一台压力机上(存放目录要相同)
4,修改jmeter.properties文件,ssl.disable=true(去掉注释)
5,在每台机器上进入到jmeter的bin目录下,都启动nohup ./jmeter-server &(后台启动jmeter-server服务)
在这里插入图片描述

6,在主jmeter的bin目录下,修改jmeter.properties,将其中的remote_hosts修改为作为压力机的两台机器ip,remote_hosts=127.0.0.1,192.168.0.102
7、关闭压力机的防火墙
8,在主jmeter的机器上,执行jmeter -n -t pinter.jmx -l result.jtl -r(示例,具体目录和路径自定义)

注意:
1、如果是http脚本,在controller的机器上有脚本文件即可;
2、如果是Java脚本,在每一台机器上都得有脚本文件和依赖的jar包

jmeter工具进行性能测试_第8张图片

结果报表
三种方式来获取Jmeter的结果报表
一、在GUI模式下跑Jmeter的脚本,用tps插件实时展示图表(不建议使用)
二、在命令行模式下跑Jmeter的脚本,生成的jtl文件,在GUI界面的聚合报告里打开,可以展示tps和响应时间等数据
jmeter工具进行性能测试_第9张图片
如果多个接口一起压测,jtl文件显示的是综合数据,聚合报告可以显示单个接口的数据
jmeter工具进行性能测试_第10张图片

jmeter工具进行性能测试_第11张图片

三、在命令行模式下跑Jmeter的脚本,生成的jtl文件,通过Jmeter自带命令,生成html报表

html报表
Html报表生成步骤:
1、进入jmeter的bin目录下,修改reportgenerator.properties
2、修改jmeter.reportgenerator.overall_granularity=1000(报表中数据展示间隔1秒)(根据压测时间自行修改)
3、创建一个存放数据报表的文件夹 mkdir report
4、执行命令:jmeter -g result.jtl -o ./report
其中:
-g 指定jtl文件的路径
-o 指定html报表生成到哪个文件夹下,report文件夹必须为空
5、压缩文件report:zip -r ./report.zip ./report
6、下载,解压,打开
jmeter工具进行性能测试_第12张图片

注意:只有Jmeter3.0版本以上支持此功能

Linux下排查错误方法
1、jmeter.log(单机压测)/jmeter-server.log(分布式压测)查看是否有error
2、jtl文件查看failureMessage
3、windows界面查看:下载error.xml——》新建“查看结果树”——》浏览选择error.xml文件

cat命令适合查看短文件
more命令适合查看长文件
在这里插入图片描述
在这里插入图片描述

性能测试理论

*** 性能测试目的***
测试系统最大处理能力
寻找系统最大的TPS,判断TPS和对应响应时间是否满足预期

测试系统支持最高并发
寻找系统最高能支持多少并发,当系统出现宕机、进程崩溃、报错率持续上升、响应时间超过可忍受范围、程序无响应等情况,即可认为系统达到了可支持的最高并发

性能测试场景
三个基本压测场景
1、先进行单接口测试
2、再按照一定的并发比例,进行多接口混合测试
3、最后按照混合场景比例,进行长时间稳定性测试(12h),稳定性测试关注tps和响应时间是否稳定波动是否大

其他压测场景
根据自己的业务情况,选择不同业务场景的压测

性能测试执行策略
加压策略
从小并发开始,逐步增加并发,寻找性能拐点

执行策略
试压阶段:寻找拐点,记录拐点数据
收集数据:选择拐点前后5组数据,按照固定时间(3-5分钟)重新跑一次,记录详细数据

性能拐点

并发数 TPS 平均响应时间(ms)
10 21 54
20 45 67
30 95 123
40 150 167
50 290 205
60 241 287
70 196 324
80 151 386

再谈TPS、响应时间、并发

注册用户 > 在线用户 > 并发用户
并发用户又分为真实并发用户和服务端并发用户
真实并发用户 > 服务端并发

jmeter工具进行性能测试_第13张图片
总结:
在压测工具中设置的并发数,其实就是服务端的并发数
不需要关注真实用户并发,关注服务端并发即可
一个系统的性能好坏,不能用支持的并发数还衡量,而是以TPS、响应时间来衡量
性能测试没必要过分关注并发数,而是更应该关注业务性能指标TPS、响应时间
性能差的系统,比性能好的系统支持更高的并发数
如果想让一个系统支持更高的并发数,只需要将系统的响应时间变长即可

Linux环境部署

软件 地址
Mysql VMwareCentOs7-002:192.168.74.133; 安装包: /usr/local/tools
Tomcat/项目 VMwareCentOs7-003:192.168.74.134; tomcat:/home/services; 项目:/home/app
Nginx VMwareCentOs7:192.168.74.132; nginx: /etc/nginx
Redis VMwareCentOs7-002:192.168.74.133; 安装包/源码: /usr/local/tools/redis-5.0.8; 安装位置:/usr/local/bin

Mysql

MySQL 安装配置:
1、 将群文件中的mysql-community-5.7- Linux -rpm.zip文件上传到Linux下的/usr/local/src
目录下(其他目录也可以)
2、 对压缩包进行解压 unzip mysql-community-5.7-rpm.zip,里面包含 4 个安装包
jmeter工具进行性能测试_第14张图片

3、 分别执行以下命令安装四个包(严格按照顺序执行)
rpm -ivh mysql-community-common-5.7.28-1.el7.x86_64.rpm --force --nodeps
rpm -ivh mysql-community-libs-5.7.28-1.el7.x86_64.rpm --force --nodeps
rpm -ivh mysql-community-client-5.7.28-1.el7.x86_64.rpm --force --nodeps
rpm -ivh mysql-community-server-5.7.28-1.el7.x86_64.rpm --force --nodeps
4、 启动 MySQL
systemctl start mysqld
启动成功后,执行 ps -ef|grep mysql 命令查看进程是否存在
在这里插入图片描述

5、 查找生成的临时密码,并记录下来,如下图
grep ‘temporary password’ /var/log/mysqld.log

在这里插入图片描述

6、 登录 MySQL
mysql -u root -p
粘贴刚才记录的临时密码

jmeter工具进行性能测试_第15张图片

7、 修改密码(注意密码长度大于 8 位,包含大小写字母+特殊符号+数字),以分号结尾
ALTER USER ‘root’@‘localhost’ IDENTIFIED BY ‘388712sunSXF#’;
8、 设置权限,允许用户远程访问
GRANT ALL PRIVILEGES ON *.* TO ‘root’@’%’ IDENTIFIED BY ‘388712sunSXF#’ WITH GRANT OPTION;

jmeter工具进行性能测试_第16张图片

9、 退出 MySQL
exit

jmeter工具进行性能测试_第17张图片

10、关闭防火墙
systemctl stop firewalld.service

11、navicat连接数据库
jmeter工具进行性能测试_第18张图片

Tomcat

提供了作为 Web 服务器的一些特有功能,如 Tomcat 管理和控制平台、安全域管理和 Tomcat 附加组件等。
web项目中间件,负责业务之外的底层逻辑处理,处理用户的并发访问,链接数,tcp请求转换。url映射

Tomcat 安装配置(原生方式)

1、 先将项目放到 Linux (VMwareCentOs7)上tomcat的webapps目录下,/home/app/services/apache-tomcat-8.5.38-pinter/webapps
注意:如果项目是 war 包形式的,需要在webapps目录下先创建 pinter 文件夹,然后在文件夹内对 war 包进行解压:unzip pinter.war
jmeter工具进行性能测试_第19张图片

2、配置项目的数据库连接信息
jmeter工具进行性能测试_第20张图片

jmeter工具进行性能测试_第21张图片
3、启动tomcat,查看日志
jmeter工具进行性能测试_第22张图片
jmeter工具进行性能测试_第23张图片

4、访问项目
jmeter工具进行性能测试_第24张图片

Tomcat 安装配置(虚拟主机方式)

单项目部署(pinter 项目)
1、 先将项目放到 Linux (VMwareCentOs7-003)上某个目录下,如/home/app/pinter
注意:如果项目是 war 包形式的,需要先创建 pinter 文件夹,然后在文件夹内对 war 包
进行解压:unzip pinter.war

jmeter工具进行性能测试_第25张图片

2、 修改 tomcat 的 conf/server.xml 文件,在标签内,添加如下配置

注意:docBase部分改为自己项目的目录
jmeter工具进行性能测试_第26张图片

jmeter工具进行性能测试_第27张图片

3、 进到 bin 目录下,执行命令:
./startup.sh & tail -f …/logs/catalina.out
注意:第一次启动 tomcat 的时候,没有 catalina.out 文件,只需要执行./startup.sh
4、 查看控制台日志,项目是否启动成功
5、 关闭防火墙,浏览器访问 pinter 项目进行验证
http://{ip}:{port}/index
jmeter工具进行性能测试_第28张图片

多项目部署(增加 TestOA 项目)
1、 将 OA 项目放到 Linux 目录下(和 pinter 同级目录)
jmeter工具进行性能测试_第29张图片

2、 配置 OA 项目所需要的数据库信息(数据库必须启动,且已经导入了 oa.sql)
TestOA/WEB-INF/classes/jdbc.properties 文件,修改数据库的连接信息
jmeter工具进行性能测试_第30张图片

3、 复制一份 tomcat,重命名为 tomcat-oa
cp -r apache-tomcat-8.5.38-pinter/ apache-tomcat-8.5.38-oa

jmeter工具进行性能测试_第31张图片

4、 修改 tomcat-oa 的 conf/server.xml 文件
a> 将 8005 改为其他的
b> jmeter工具进行性能测试_第32张图片

jmeter工具进行性能测试_第33张图片
jmeter工具进行性能测试_第34张图片
jmeter工具进行性能测试_第35张图片

5、 启动 tomcat,查看控制台日志,项目是否启动成功

6、 浏览器访问 OA 项目进行验证
http://{ip}:{port}/homeAction_index.action

jmeter工具进行性能测试_第36张图片

Tomcat 访问日志配置
tomcat 的 logs 目录下 localhost_access_log.xxxx-xx-xx.txt 里记录了访问 tomcat 的日志,可
以通过配置,使访问日志中显示请求耗时
修改 tomcat 的 conf 目录下 server.xml 文件,在 pattern 属性里添加%T
prefix=“localhost_access_log.” suffix=".txt"
pattern="%h %l %u %t “%r” %s %b %T" />
重启 tomcat,查看 access 日志,红框里代表就是请求的耗时,单位秒

jmeter工具进行性能测试_第37张图片

jmeter工具进行性能测试_第38张图片

Nginx

Nginx:高性能反向代理服务器,官网数据显示每秒tps在50w左右
代理客户端是正向代理,代理服务端是反向代理
作用:提供了一种统一的访问地址;负载均衡
web服务器:转发请求,nginx,apache,类似于服务员/中介
应用服务器:tomcat,处理动态的语言,处理逻辑,类似于厨师/房东
官网:https://www.nginx.com/

jmeter工具进行性能测试_第39张图片

Nginx 安装

Nginx 安装前需要先安装 pcre、openssl、zlib 等模块,手动安装比较繁琐,所以推荐使用
yum 进行安装
1、 默认情况下 CentOS7 中没有 nginx 的下载源,先手动添加官方源
rpm -Uvh http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm
2、 安装 Nginx
yum install -y nginx

Nginx 配置

Nginx 默认安装到/etc/nginx 目录下,nginx.conf 为主配置文件
编辑 nginx.conf
修改 worker_processes 为当前系统的 CPU 核数

jmeter工具进行性能测试_第40张图片

在 Nginx 中,每个项目都有自己的一个配置文件,配置了本项目的访问方式
1、进入 nginx 目录下的 conf.d 文件夹,包含了一个默认配置文件模板 default.conf
2、重命名配置文件
mv default.conf pinter.conf
3、 编辑 pinter.conf 配置文件,在 server 模块前面新增
upstream www.pinter.com {
server 192.168.74.134:8080 weight=10 max_fails=2 fail_timeout=30s;
server 192.168.74.134:8100 weight=10 max_fails=2 fail_timeout=30s;
}
注意:红色字体根据实际情况修改,两个 ip 为本项目部署在哪些服务器上
4、 将 server_name 修改为 www.pinter.com(根据实际情况修改),access.log 的注释去掉,
后面文件名称改为项目名称

jmeter工具进行性能测试_第41张图片

5、将 location 中的 root、index 注释掉,新增 proxy_pass http://www.pinter.com;
注意:proxy_pass 后的域名名称必须和 upstream 名称保持一致
6、 conf.d 目录下可以放多个项目,配置方法同上
7、 启动 nginx
在任意目录下执行命令:nginx
如果没有任何报错,就代表启动成功了,nginx默认是80端口
nginx -s reload:重启 nginx
nginx -s stop:停止 nginx
jmeter工具进行性能测试_第42张图片

8、 在本机(Windows/Mac),修改 host 文件,配置两个项目的 ip 和域名映射关系
Windows 系统 host 文件在 C:\Windows\System32\drivers\etc\hosts
Mac 系统在/etc/hosts

jmeter工具进行性能测试_第43张图片

9、在浏览器中,通过域名的方式,分别访问两个项目,搞定
http://www.pinter.com/index
http://www.oa.com/homeAction_index.action

jmeter工具进行性能测试_第44张图片

jmeter工具进行性能测试_第45张图片

Nginx 访问日志配置

用户每次访问 nginx,都会在项目的 access.log 里记录一行日志。
jmeter工具进行性能测试_第46张图片

jmeter工具进行性能测试_第47张图片
可以在访问日志里记录请求耗时,这样方便排查问题
配置响应时间/请求耗时方法:在 Nginx 的主配置文件中:/etc/nginx/nginx.conf

jmeter工具进行性能测试_第48张图片

重启 nginx,在项目 access.log 里,可以看到每个请求的耗时了
jmeter工具进行性能测试_第49张图片

Nginx 负载均衡策略配置

在 upstream 模块中,添加负载均衡策略
四种策略:
轮询:默认策略
ip_hash:根据 ip 进行 hash 算法,固定的 ip 分配到固定的后端 server
fair:根据后端 server 的响应时间来分配请求,响应时间短的优先分配
url_hash:根据 url 进行 hash 算法,固定的 url 分配到固定的后端 server
jmeter工具进行性能测试_第50张图片

Redis

Redis是当前使用最广泛的NoSQL,而就Redis技术而言,它的性能十分优越,可以支持每秒十几万次的读/写操作,其性能远超数据库,并且还支持集群、分布式、主从同步等配置,原则上可以无限扩展,让更多的数据存储在内存中,更让人欣慰的是它还支持一定的事务能力,这保证了高并发的场景下数据的安全和一致性。
redis的数据存在内存中

Redis应用场景
1、缓存
2、消息队列,比如支付
3、活动排行榜或计数
4、发布,订阅消息(消息通知)
5、商品列表,评论列表等
6、有效期控制

Redis安装

Yum 官方源里没有 redis,所以采用手动源码安装
1、 上传 redis 安装包到 Linux 任意目录下,解压 tar xvf redis-5.0.7.tar.gz
2、 安装 gcc(redis 安装依赖 C 语言环境,需要先安装 gcc)
yum install -y gcc
3、 进入解压后的 redis 目录下,执行编译操作
make MALLOC=libc
4、 执行安装命令
make install
5、 安装成功

Redis 配置

1、 在 redis 目录下,新建 conf 文件夹,将 redis.conf 配置文件拷贝到 conf 文件夹下,并重
命名为 6379.conf
mkdir conf
cp redis.conf ./conf/6379.conf
2、 修改 redis.conf 配置文件
daemonize 改为 yes
dbfilename 改为 dump_6379.rdb
将 bind 127.0.0.1 注释掉
protected-mode 改为 no

jmeter工具进行性能测试_第51张图片
jmeter工具进行性能测试_第52张图片

jmeter工具进行性能测试_第53张图片

jmeter工具进行性能测试_第54张图片

Redis 启动

1、 先启动 server,在 conf 目录下,执行
redis-server ./6379.conf

jmeter工具进行性能测试_第55张图片

2、 使用自带的客户端登录 redis,默认连接的是 6379 端口的 redis 实例
redis-cli

jmeter工具进行性能测试_第56张图片

3、 关闭 redis-server
redis-cli shutdown

Redis常用命令

传统关系型数据库

id name age address phone
1 sxf 18 杭州市 15988861234
2 xfsun 20 上海市 15988865678

redis中string数据结构

key value
id_1 sxf ,18, 杭州市, 15988861234
id_2 xfsun ,20 ,上海市,15988865678

Redis中List数据类型
在这里插入图片描述
Redis中Hash数据结构
jmeter工具进行性能测试_第57张图片

对String数据类型的操作
set key value:给名称为key的String值赋值为value
get key:返回名称为key的value值
keys *:查看所有的key(公司中慎用,可能造成redis卡死)

jmeter工具进行性能测试_第58张图片

对List数据类型的操作
rpush key value:在名称为key的List尾部添加一个值为value的元素
lpush key value:在名称为key的List头部添加一个值为value的元素
llen key:返回名称为key的List的长度
lrange key start end:返回名称为key的List中start至end之间的元素
lset key index value:给名称为key的list中index位置的元素赋值为value
rpop:返回并删除名称为key的list中的尾元素

对Hash数据类型的操作
hset key field value:向名称为key的hash中添加元素field<—>value
hget key field:返回名称为key的hash中field对应的value
hgetall:返回名称为key的hash中所有的键(field)及其对应的value
hlen key:返回名称为key的hash中元素个数
hdel key field:删除名称为key的hash中键为field的域

对全局value的操作
exists key:确认一个key是否存在
del key:删除一个key
type key:返回值的类型
keys pattern:返回满足给定pattern的所有key
dbsize:返回当前数据库中key的数目
select dbindex:切换数据库
flushdb:删除当前选择数据库中的所有key(危险操作)
flushall:删除所有库中的所有key(危险操作)
jmeter工具进行性能测试_第59张图片

Redis持久化

持久化:将内存中的数据保存到磁盘中
Redis的两种持久化机制
rdb:在指定的时间间隔内将内存中的数据集快照写入磁盘
优点:性能最大化 、如果数据集很大,RDB的启动效率会更高
缺点:数据安全性差

jmeter工具进行性能测试_第60张图片

aof:以日志的形式记录服务器所处理的每一个写、删除操作,查询操作不会记录
优点:数据安全性高
缺点:对于相同数量的数据集而言,AOF文件通常要大于RDB文件。恢复数据慢

jmeter工具进行性能测试_第61张图片
jmeter工具进行性能测试_第62张图片

多实例部署

多实例:一个服务器启动多个redis

由于redis服务端是单线程实现的,因此只能占用CPU的单核,为了充分利用CPU资源,可以在一台服务器上同时启动多个redis-server实例

1、 在 conf 目录下,拷贝一份配置文件,如
cp 6379.conf 6380.conf
2、 修改 6380.conf 文件
port 修改为 6380
dbfilename 修改为 dump_6380.rdb
3、 启动 redis-server
redis-server ./6380.conf
4、 使用客户端登录 redis
redis-cli -p 6380

Redis 主从关系配置

读写分离 备份数据
在从 redis 中,新增 slaveof 127.0.0.1 6379,指向主 redis 的 ip 和端口

Redis 其他配置

maxclient:最大连接数,默认是 10000
maxmemory:最大内存
requirepass:设置密码(redis-cli -a 密码),主redis配置密码后,从redis需要在配置文件中修改masterauth项添加密码才能同步数据

性能监控

操作系统监控

性能监控是性能测试过程中非常重要的一个环节,当在压测过程中出现性能瓶颈时,需要综合详细的监控数据对问题进行分析。整个系统架构中的每一个环节都需要做监控(压力机、网络、各中间件、各服务器硬件资源等)。性能监控做好了,就能帮助你快速的定位问题,找到系统的性能瓶颈。

jmeter工具进行性能测试_第63张图片

CPU

tpo命令
jmeter工具进行性能测试_第64张图片

jmeter工具进行性能测试_第65张图片

内存

free命令

free -m 以MB为单位显示系统内存的使用情况,同理,也可以使用-k、-g等其他的单位显示

在这里插入图片描述
buffer和cache:两者都是Linux下的缓存机制,其中buffer为写操作的缓存,cache为读操作的缓存
swap:交换空间,磁盘上的一块空间,当系统内存不足时,会使用交换空间

网络

磁盘

磁盘io

iostat命令
安装:yum install sysstat
iostat命令可以查看当前机器磁盘io的数据
jmeter工具进行性能测试_第66张图片
iostat -x -k 1
-x:展示磁盘的扩展信息
-k:以k为单位展示磁盘数据
1:每1秒刷新一次

jmeter工具进行性能测试_第67张图片

展示结果
util:磁盘IO使用率,单位%,反映磁盘的繁忙程度,上限100%
r/s:每秒读请求数
w/s:每秒写请求数
rkb:每秒写磁盘字节数
wkb:每秒读磁盘字节数

磁盘空间

df命令
df命令可以查看当前系统磁盘空间的使用情况
命令:df -h

jmeter工具进行性能测试_第68张图片

du -sh * 查看当前目录下占用磁盘的情况

jmeter工具进行性能测试_第69张图片

磁盘速度测试
命令:dd if=/dev/zero of=/export/ddtest bs=8k count=1000000 oflag=direct

jmeter工具进行性能测试_第70张图片

综合监控工具

vmstat

vmstat命令综合了CPU、进程、内存、磁盘IO等信息
vmstat 1

jmeter工具进行性能测试_第71张图片
r 表示运行队列(就是说多少个进程真的分配到 CPU),我测试的服务器目前 CPU 比较空闲,
没什么程序在跑,当这个值超过了 CPU 数目,就会出现 CPU 瓶颈 了。这个也和 top 的负载
有关系,一般负载超过了 3 就比较高,超过了 5 就高,超过了 10 就不正常了,服务器的状
态很危险。top 的负载类似每秒的运行队 列。如果运行队列过大,表示你的 CPU 很繁忙,
一般会造成 CPU 使用率很高。
b 表示阻塞的进程,这个不多说,进程阻塞,大家懂的。

dstat

dstat是一个全能监控工具,整合了CPU、内存、磁盘、网络等几乎所有的监控项,支持实时刷新
dstat需要先进行安装:yum install -y dstat
监控命令:dstat -tcmnd --disk-util

jmeter工具进行性能测试_第72张图片

nmon

nmon是IBM公司开发的Linux性能监控工具,可以实时展示系统性能情况,也可以将监控数据写入文
件中,并使用nmon分析器做数据展示
官网下载地址:http://nmon.sourceforge.net/pmwiki.php?n=Site.Download
jmeter工具进行性能测试_第73张图片
jmeter工具进行性能测试_第74张图片

./nmon_x86_64_centos7即可查看监控数据

jmeter工具进行性能测试_第75张图片

jmeter工具进行性能测试_第76张图片

报表模式:
命令:./nmon -ft -s 5 -c 1000
Nmon文件需要关注的标签页
1、cpu_all
2、diskbusy
3、net
4、mem

jmeter工具进行性能测试_第77张图片

下载文件用Excel分析器打开
jmeter工具进行性能测试_第78张图片
jmeter工具进行性能测试_第79张图片

spotlight

添加用户命令:useradd xfsun
设置密码命令:passwd xfsun
388712sun

jmeter工具进行性能测试_第80张图片

jmeter工具进行性能测试_第81张图片

普罗米修斯

普罗米修斯监控平台可以对集群多台机器的系统资源进行监控

普罗米修斯官网:https://prometheus.io/
grafana官网:https://grafana.com/

平台监控原理

jmeter工具进行性能测试_第82张图片

部署前的准备:
1、 关闭所有 Linux 机器的防火墙:systemctl stop firewalld.service
2、 保证所有 Linux 机器的时间是准确的,执行 date 命令检查;如果不准确,建议使用
ntp 同步最新网络时间
安装:yum install -y ntp
同步时间:ntpdate pool.ntp.org

jmeter工具进行性能测试_第83张图片

部署 Linux 操作系统监控组件

  1. 下载监控 Linux 的 exporter
    https://github.com/prometheus/node_exporter/releases/download/v0.18.1/node_expor
    ter-0.18.1.linux-amd64.tar.gz
  2. 将 node_exporter 包上传到需要被监控的 Linux 服务器上任意目录下,执行解压命令
    tar xvf node_exporter-0.18.1.linux-amd64.tar.gz

jmeter工具进行性能测试_第84张图片

  1. 进入到解压后的文件夹中,执行启动脚本
    nohup ./node_exporter &
    查看 nohup 日志:tail -100 nohup.out,出现如下日志,代表启动成功

jmeter工具进行性能测试_第85张图片

部署 prometheus

1、 下载包
https://github.com/prometheus/prometheus/releases/download/v2.15.2/promethe
us-2.15.2.linux-amd64.tar.gz
2、 将 prometheus 上传到一台单独的 Linux 机器上,执行解压操作
tar xvf prometheus-2.15.2.linux-amd64.tar.gz
3、 进入到解压后的文件夹中,修改配置文件,添加要监控的服务器信息 10.0.0.71
vi prometheus.yml

在 scrape_configs 配置项下添加 Linux 监控的 job,其中
IP 修改为上面部署 node_exporter 机器的 ip,端口号为 9100,注意缩进
- job_name: ‘node’
static_configs:
- targets: [‘10.0.0.71:9100’]

jmeter工具进行性能测试_第86张图片

4、 保存配置文件,启动 prometheus
nohup ./prometheus &
检查 nohup.out 日志,如果有以下信息,启动成功

jmeter工具进行性能测试_第87张图片

在浏览器中访问部署的 prometheus:http://10.0.0.45:9090
jmeter工具进行性能测试_第88张图片

部署 Grafana

1、 下载安装包
https://dl.grafana.com/oss/release/grafana-6.5.3-1.x86_64.rpm
2、 将 grafana 安装包上传至 Linux 服务器(和 prometheus 使用同一台即可)
3、 安装 grafana
yum localinstall -y grafana-6.5.3-1.x86_64.rpm
4、 启动 grafana
systemctl start grafana-server
在浏览器访问:http://10.0.0.45:3000/
输入用户名/密码:admin/admin 登录

jmeter工具进行性能测试_第89张图片

jmeter工具进行性能测试_第90张图片

5、 添加数据源,选择 prometheus
jmeter工具进行性能测试_第91张图片
jmeter工具进行性能测试_第92张图片

进行数据源配置,因为我的 prometheus 和 grafana 装在同一台机器上,所以 ip 写
的是 localhost,如果没在一台机器上,写上 prometheus 的 IP
点击“save and test”,如果提示 success,代表配置成功
jmeter工具进行性能测试_第93张图片

6、 导入监控模板
打开 grafana 官网,查找官网提供的 prometheus 监控模板
https://grafana.com/grafana/dashboards
点击 Linux 服务器监控的中文模板,记录该模板的 id:8919

jmeter工具进行性能测试_第94张图片

jmeter工具进行性能测试_第95张图片

在 grafana 系统页面中,通过 id 导入该模板,即可在 grafana 中看到 10.0.0.71 机器
的性能监控数据

jmeter工具进行性能测试_第96张图片
jmeter工具进行性能测试_第97张图片
jmeter工具进行性能测试_第98张图片

将数据更新频率设置为 5s,展示最近 5 分钟的数据,就可以看到实时的、最近 5 分
钟的各项性能指标。包含了 CPU、Load、内存、网络、磁盘、IO 耗时等指标。监控
数据永久保存,可以随时查看任意时间点内的历史统计数据,非常方便。

jmeter工具进行性能测试_第99张图片

附录:添加对 MySQL 的监控

1、 下载 MySQL 的 exporter
https://github.com/prometheus/mysqld_exporter/releases/download/v0.12.1/mysqld_exporter-0.12.1.linux-amd64.tar.gz
2、 上传至 MySQL 服务器上,解压包
tar xvf mysqld_exporter-0.12.1.linux-amd64.tar.gz
3、 执行命令
export DATA_SOURCE_NAME=‘root:Testfan#123@(127.0.0.1:3306)/’
标红部分根据实际情况修改,其中:
root 为数据库用户名
Testfan#123 为数据库密码
127.0.0.1 为数据库 IP
3306 为数据库端口号
4、 启动 mysql exporter
进入到解压后的文件夹中,执行命令
nohup ./mysqld_exporter &
监控 nohup.out 日志,有如下日志代表成功

jmeter工具进行性能测试_第100张图片

修改 prometheus 的配置文件 prometheus.yml
vi prometheus.yml
增加监控 MySQL 的 job(注意缩进格式)
- job_name: ‘mysql’
static_configs:
- targets: [‘10.0.0.71:9104’]

jmeter工具进行性能测试_第101张图片

targets 中的 IP 为 mysql_exporter 的 IP,端口号固定为 9104
重启 prometheus,进入 prometheus 的 UI 界面,在 status-targets 页面下,可以看到 MySQL exporter 的状态

jmeter工具进行性能测试_第102张图片

5、 在 Grafana 中添加 MySQL 的监控模板
在 grafana 官网模板中找到 MySQL 监控模板 Mysql Overview,id 为 7362,并导入
到 Grafana 中(具体操作步骤参考上面导入 Linux 监控模板操作)
jmeter工具进行性能测试_第103张图片

这样在 grafana 中,就可以轻松监控 MySQL 的连接数、内存、表锁、慢查询、网
络、查询缓存等监控数据

jmeter工具进行性能测试_第104张图片

程序监控

Java线程监控

线程的五种状态

  • 新建:new
  • 运行:runnable
  • 等待:waitting(无限期等待),timed waitting(限期等待)
  • 阻塞:blocked
  • 结束:terminated

jmeter工具进行性能测试_第105张图片

Jvisualvm

无需安装,jdk自带,只能监控tomcat部署的项目
图形界面工具,只能在windows/mac系统使用,监控之前先对jvm加监控参数,在tomcat的bin目录下,catalina.sh文件中,第二行
添加:
JAVA_OPTS="-Dcom.sun.management.jmxremote.port=10086 -Dcom.sun.management.jmxremote.ssl=false -
Dcom.sun.management.jmxremote.authenticate=false -
Djava.rmi.server.hostname=10.0.0.9"

注意:
1-改port
2-改hostname为本机ip

jmeter工具进行性能测试_第106张图片

启动项目后,windows控制台输入jvisualvm,系统会自动打开界面
jmeter工具进行性能测试_第107张图片

jmeter工具进行性能测试_第108张图片

jmeter工具进行性能测试_第109张图片
jmeter工具进行性能测试_第110张图片

jmeter工具进行性能测试_第111张图片

jar包的项目也可以使用jvisualvm监控进程,启动命令:java -jar -Dcom.sun.management.jmxremote.port=10086 -Dcom.sun.management.jmxremote.ssl=false -
Dcom.sun.management.jmxremote.authenticate=false -
Djava.rmi.server.hostname=192.168.74.134 pinter.jar

jvisualvm添加远程主机即可(参上)

jstack工具

命令:jstack

jmeter工具进行性能测试_第112张图片

nid=0x15cf:对应系统线程id(NativeThread ID),和top命令查看的线程pid对应,不过一个是
10进制,一个是16进制。
通过命令:top -H -p pid,可以查看该进程的所有线程信息

jmeter工具进行性能测试_第113张图片
保存监控线程状态:jstack 2991 > dump.txt

jmeter工具进行性能测试_第114张图片

JVM监控

命令行工具

监控jvm的GC情况
jstat -gcutil pid 2000 1000
监控2000次 1000ms刷新一次

jmeter工具进行性能测试_第115张图片

S0:s0区当前使用比例
S1:s1区当前使用比例
E:伊甸园区使用比例
O:老年代使用比例
M:元空间区使用比例
CCS:压缩使用比例
YGC:年轻代垃圾回收次数
YGCT:年轻代垃圾回收消耗时间
FGC:老年代垃圾回收次数
FGCT:老年代垃圾回收消耗时间
GCT:垃圾回收消耗总时间

查看jvm配置信息
jmap -heap pid
可以看到java进程的堆的配置信息,各区的空间大小和配置信息

查看jvm中类和对象的占用情况
(一)jmap -histo 5279 | head -20:查看jvm中各个类的实例数、占用内存数量以及类的全名

jmeter工具进行性能测试_第116张图片

(二)堆文件dump
jmap -dump:format=b,file=m.hdump 17777
对堆内存进行dump,以文件的形式进行保存下来,可以用jvisualvm等工具对文件进行分析
此命令与在Jvisualvm中点击堆 Dump功能一样,都会产生一个文件

图形界面

Jvisualvm

jmeter工具进行性能测试_第117张图片
jmeter工具进行性能测试_第118张图片

堆Dump
jmeter工具进行性能测试_第119张图片
jmeter工具进行性能测试_第120张图片

jmeter工具进行性能测试_第121张图片

jmeter工具进行性能测试_第122张图片

Redis监控

info

jmeter工具进行性能测试_第123张图片

jmeter工具进行性能测试_第124张图片

比较重要的一些参数:
Clients
connected_clients:已连接客户端的数量
blocked_clients:正在等待阻塞命令(BLPOP、BRPOP、BRPOPLPUSH)的客户端的数量
Memory
used_memory_rss_human:以人类可读的格式,从操作系统的角度,返回 Redis 已分配的内
存总量(俗称常驻集大小)。这个值和 top 、 ps 等命令的输出一致。
Stats
keyspace_hits:命中次数
keyspace_misses:没命中次数

redis-stat

界面形式展示redis监控数据
下载redis-stat-0.4.14.jar
在redis服务器上执行:java -jar redis-stat-0.4.14.jar --server [–auth 密码]
关闭Linux防火墙,在浏览器输入
http://192.168.2.241:63790/

jmeter工具进行性能测试_第125张图片

jmeter工具进行性能测试_第126张图片

监控其他端口redis:java -jar redis-stat-0.4.14.jar 127.0.0.1:6380 --server [–auth 密码]

Nginx监控

Nginx重点监控链接数,一般是通过netstat命令来监控

netstat

监控80端口的连接数情况
netstat -anp | grep :80

查看80端口总连接数
netstat -anp | grep :80 | wc -l

查看nginx所有连接数的状态,分类展示
netstat -anp | grep :80 | awk ‘{print $6}’ | sort | uniq -c | sort -rn

jmeter工具进行性能测试_第127张图片

Mysql监控

参普罗米修斯

JVM内存结构和垃圾回收

JVM内存结构

Java内存管理结构
Java采用了自动管理内存的方式
Java程序是运行在Jvm之中的
Java的跨平台的基于Jvm的跨平台特性
内存的分配和对象的创建是在Jvm中
用户可以通过一系列参数来配置Jvm

jvm运行时区域

jmeter工具进行性能测试_第128张图片

Jvm内存结构
jmeter工具进行性能测试_第129张图片

栈内存

特点:
• 线程私有,每个线程都有自己的栈内存,不能使用其他栈内存的数据
• 生命周期和线程相同,线程结束时内存随即消失

主要存放内容:
➢ 基本数据类型(int,char,float,double…)
➢ 对象的引用,指向了对象在堆内存中起始地址
➢ 通过-Xss参数配置

堆内存

jmeter工具进行性能测试_第130张图片
堆内存 = 年轻代+老年代
年轻代 = Eden+Survivor
Survivor = From Space(s0)+To Space(s1)

特点:
• 堆内存是Jvm中空间最大的区域
• 所有线程共享堆
• 所有的数组以及内存对象的实例都在此区域分配
• 堆内存大小通过参数进行配置
-Xmx:最大堆内存
-Xms:最小堆内存

Object o = new Object()
其中,o存放在栈内存中,new Object()存放在堆内存中,变量o是Object对象的引用,o上存放
了Object对象占用内存的起始地址

永久代

特点:
• 永久代也叫(Method Area)
• 各线程共享,主方法区要存放类信息、常量、静态变量,如public static int a = 10
• 垃圾回收行为比较少见

Java8新变化:
Java8从Jvm中移除了PermGen,使用Metaspace(元空间)来代替永久代
Metaspace不存在Jvm中,而是存在本地内存中
配置元空间初始值和最大值参数:
-XX:MetaspaceSize=64m
-XX:MaxMetaspaceSize=64m

垃圾回收-GC

三个问题
• 哪些内存需要回收?
• 什么时候回收?
• 如何回收?

堆垃圾回收

◼ 新生代引发的GC叫YoungGC
◼ 老年代引发的GC叫FullGC,FullGC会引起整个Jvm的用户线程暂停,待垃圾回收完毕后,才继续运行

对象存活状态判断
确定对象“存活”还是“死去”
1、引用计数算法(如果reference类型的数据中存储的数值代表的是另外一块内存的起始地址,就称这块内存代表一个引用)
2、根搜索算法(GC Roots)
jmeter工具进行性能测试_第131张图片

堆垃圾回收算法

标记-清除算法(Mark-Swap)

jmeter工具进行性能测试_第132张图片

特点
– 分为“标记”和“清除”两个阶段
– 标记完成后,统一回收

缺点
– 效率,标记和清除过程效率都不高
– 空间,标记清除后会产生大量不连续的内存碎片

复制算法

jmeter工具进行性能测试_第133张图片

特点:
– 内存分为相等的两块
– 当一块内存用完,将存活对象复制到另外一块中,原内存一次性清理掉
– 复制时按照顺序分配内存,无内存碎片问题
– 新生代使用此算法

缺点:
– 将内存分为两半,利用率低

标记-压缩算法
jmeter工具进行性能测试_第134张图片

特点:
– 先对存活对象进行标记
– 让所有存活对象向一边移动
– 清理掉存活对象边界外的所有内存
注:老年代使用此算法

分代收集算法
当代的商业虚拟机都采用“分代收集”
• 根据对象的存活周期的不同将内存划分成几块,一般Java堆分为新生代和老年代
• 新生代采用复制算法
• 老年代采用标记-压缩算法

永久代的垃圾回收

永久代回收“性价比”比较低
主要回收:
–废弃的常量
– 无用的类
• 类的所有实例都已经被回收
• 加载该类的ClassLoader已经被回收
• 该类的Class对象没有在任何地方被引用

垃圾收集器

垃圾收集器是内存回收算法的具体实现
• 没有完美的收集器
• Jvm不同的区域可以采用不同的垃圾收集器组合,主要有:
– Serial收集器(串行)
– ParNew收集器(并行)
– CMS收集器(并发)
– G1(时间优先)

Serial收集器

• 单线程收集器
• 用户线程全部停止(Stop the world)
• Client模式下,新生代默认收集器
• 优点:简单、高效

jmeter工具进行性能测试_第135张图片

ParNew收集器

并行收集器,Serial收集器的多线程版本
• Server模式下Jvm默认的新生代收集器
• 默认开启的垃圾回收线程与cpu核数一致

jmeter工具进行性能测试_第136张图片

CMS收集器

并发收集器(ConcurrentMarkSweep)
• 采用了标记-清除、标记-压缩算法
• 并发收集、低停顿
• 缺点:
– 消耗cpu
– 会产生内存碎片
– 浮动垃圾(Concurrent Mode Failure)

jmeter工具进行性能测试_第137张图片

G1

G1全称是Garbage First Garbage Collector,在jdk1.7u4中开始支持。Java9中默认的垃圾收集器。
◼ G1的设计原则就是简化性能优化的复杂性

内存溢出

堆内存溢出(一般运行过程中会出现此问题)
– 堆内存中存在大量对象,这些对象都有被引用,当所有对象占用空间达到堆内存的最大值,
就会出现内存溢出OutOfMemory:Java heap space

永久代溢出(一般启动阶段会出现此问题)
– 类的一些信息,如类名、访问修饰符、字段描述、方法描述等,所占空间大于永久代最大
值,就会出现OutOfMemoryError:PermGen space

内存溢出的检测方法
Jdk/bin目录下有很多检测工具
• 图形界面:
– Jconsole
– Jvisualvm
• 命令行工具
– Jstat –gcutil pid 1000 100
– Jmap –histo pid | head -20
– Jmap –heap pid
FullGC频率:建议单次FullGC时间<200ms

Jvm常见参数一:
• -Xms2048m,初始堆大小,建议<物理内存的1/4,默认值为物理内存的1/64
• -Xmx2048m,最大堆大小,建议与-Xms保持一致,默认值为物理内存的1/4
• -Xmn512m,新生代大小,建议不超过堆内存的1/2
• -Xss256k,线程堆栈大小,建议256k
• -XX:PermSize=256m,永久代初始值,默认值为物理内存的1/64
• -XX:MaxPermSize=256m,永久代最大值,默认值为物理内存的1/4
• -XX:SurvivorRatio=8:年轻带中Eden区和Survivor区的比例,默认为8:1:1,即Eden(8),
From Space(1),ToSpace(1)
•-XX:MaxTenuringThreshold=15:晋升到老年代的对象年龄,每个对象坚持过一次MinorGC后对象
年龄+1,默认值是15,年龄超过15进入到老年代,该参数在串行GC时有效
•-XX:PretenureSizeThreshold=3145728:单位字节,只对Serial和ParNew两款收集器有效,新生代
采用Parallel Scavenge GC时无效,大于这个值的对象直接在老年代进行分配
• -XX:+UseConcMarkSweepGC:开启CMS垃圾回收器

JAVA_OPTS="-Xms256m -Xmx256m -XX:MetaspaceSize=64m -XX:MaxMetaspaceSize=64m -Xss1024k -XX:+UseConcMarkSweepGC"

jmeter工具进行性能测试_第138张图片
jmeter工具进行性能测试_第139张图片

Jvm常见参数二:
CMS相关参数:
-XX:+UseConcMarkSweepGC:默认关闭,ParNew+CMS+Serial Old,当CMS收集器出现
ConcurrentModeFailure错误(Jvm预留空间不足以容纳程序使用),采用后备收集器Serial Old

-XX:CMSInitiatingOccupancyFraction=80:CMS收集器在老年代空间被使用多少时触发FullGC,默认为92

-XX:+UseCMSCompactAtFullCollection:CMS收集器在FullGC时开启内存碎片的压缩,默认关闭

-XX:CMSFullGCsBeforeCompaction=8:执行多少次不压缩FullGC后,进行一次压缩,默认是0(代表每次FullGC都进行压缩)

-XX:+UseCMSInitiatingOccupancyOnly:使用手动定义初始化定义开始,禁止hostspot自行触发CMS GC

-XX:ParallelGCThreads=8:并行收集器的线程数,此值最好配置与处理器数目相等 同样适用于CMS

日志参数:
-XX:+HeapDumpOnOutOfMemoryError:当发生内存溢出时,进行堆内存dump-XX:+PrintGCDetails:打印GC的详细信息

某测试环境服务器jvm配置
-server -Xms1028m -Xmx1028m -XX:PermSize=256m -XX:MaxPermSize=256m -Xmn512m
-XX:MaxDirectMemorySize=1g -XX:SurvivorRatio=10 -XX:+UseConcMarkSweepGC
-XX:+UseCMSCompactAtFullCollection -XX:CMSMaxAbortablePrecleanTime=5000
-XX:+CMSClassUnloadingEnabled -XX:CMSInitiatingOccupancyFraction=80
-XX:+UseCMSInitiatingOccupancyOnly -XX:ParallelGCThreads=8
-Xloggc:/home/admin/logs/gc.log -XX:+PrintGCDetails -XX:+PrintGCDateStamps
-XX:+HeapDumpOnOutOfMemoryError-XX:HeapDumpPath=/home/admin/logs/java.hprof

性能案例分析

内存泄露

内存泄露的现象
1,tps出现大幅波动,并慢慢降低,甚至降为0,响应时间随之波动,慢慢升高
2,通过jstat命令看到,Jvm中Old区不断增加,FullGC非常频繁,对应的FullGC消耗的时间也不
断增加
3,通过jconsole/jvisualvm可以看到,堆内存曲线不断上升,接近上限时,变成一条直线
4,日志报错java.lang.OutOfMemoryError: Java heap space

jmeter工具进行性能测试_第140张图片
jmeter工具进行性能测试_第141张图片

内存泄露怎么定位
1,通过jmap命令:jmap -histo pid | head -20,查看当前堆内存中实例数和占用内存最多的前20
个对象
2,通过jvisualvm,进行远程堆dump,然后把dump文件下载下来,用jvisualvm打开进行分析,可
以看到更直观的jvm中对象的信息

内存泄露的场景
在什么样的场景下监控内存泄露问题?
1,在试压阶段,或任意场景都可以考虑通过jvisualvm和jstat监控jvm的情况
2,在稳定性场景中,一定要关注Jvm内存使用的情况,在长时间的压测下,最容易看出内存泄露的问题

线程死锁

定义
线程死锁就是有两个线程,一个线程锁住了资源A,又想去锁定资源B,另外一个线程锁定了资源B,又想去锁定资源A,两个线程都想去得到对方的资源,而又不愿释放自己的资源从而造成一种互相等待,无法执行的情况

现象
出现死锁后,tps降为0,压力测试工具无法得到服务器的响应,服务器硬件资源空闲,通过jvisualvm去查看线程情况,至少两个线程一直处于红色的阻塞状态。死锁经常表现为程序的停顿,或者不再响应用户的请求。从操作系统上观察,对应进程的CPU占用率为零。

在这里插入图片描述

只要是是死锁必定有block,出现死锁后必须重启项目才能恢复正常

定位方法
通过jvisualvm或者jstack,进行线程dump,对线程状态进行分析,获取到哪行代码导致的死锁,如:

jmeter工具进行性能测试_第142张图片

在这里插入图片描述

jmeter工具进行性能测试_第143张图片

解决思路
避免嵌套加锁
减小锁粒度

线程阻塞

定义
在多线程情况下,如果一个线程对拥有某个资源的锁,那么这个线程就可以运行资源相关的代码。而
其他线程就只能等待其执行完毕后,才能继续争夺资源锁,从而运行相关代码。

Log4j的线程阻塞问题

Log4j的日志级别
ALL 各级包括自定义级别
DEBUG 指定细粒度信息事件是最有用的应用程序调试
ERROR 错误事件可能仍然允许应用程序继续运行
FATAL 指定非常严重的错误事件,这可能导致应用程序中止
INFO 指定能够突出在粗粒度级别的应用程序运行情况的信息的消息
OFF 这是最高等级,为了关闭日志记录
TRACE 指定细粒度比DEBUG更低的信息事件
WARN 指定具有潜在危害的情况

级别越低,日志越多,日志量:ALL > DEBUG > INFO > WARN > ERROR > FATAL

线程阻塞问题排查流程
1、做线程dump
2、在dump文件中搜索关键字"BLOCKED"、“TIME_WAITTING”,查看每种状态的count数量
3、按照上述关键字搜索,查看跟本系统有关的业务代码堆栈信息

解决方案
1、减少代码中没有必要的日志输出
2、如果可以,提升日志级别,以减少日志
3、如果可以,更换其他的日志组件,如Log4j2、Logback等

响应时间过长

数据库性能问题

索引

慢查询

执行计划

联合索引

连接数

CPU消耗过高

现象
压测过程中,发现应用服务器的CPU使用率比较高(>90%)

两种情况
1、接口的性能非常好,比如响应时间<10ms,tps很高,此时CPU使用率高是正常的,不需要优化
2、接口性能不好,比如响应时间>200ms,tps很低,此时需要考虑优化

CPU消耗高可能的原因
1、使用了复杂的算法,比如加密、解密
2、压缩、解压、序列化等操作
3、代码bug,比如死循环

项目实战

你可能感兴趣的:(java,编程语言,postman)