1、测试前准备html
一、记录性能测试时间;java
二、记录应用服务器、数据库服务器等CPU、内存等配置状况;mysql
三、修改tomcat的内存配置和最大链接数配置:linux
linux一个进程支持的最大线程数是1000;nginx
(1)tomcat的内存配置:在tomcat的bin/catalina.sh配置中web
JAVA_OPTS='-Xms2048m -Xmx4096m -XX:PermSize=1024M -XX:MaxNewSize=1024m -XX:MaxPermSize=1024m -Dfile.encoding=UTF-8 -Dglobal.config.path=/usr/local/jconfig'
sql
(2)最大链接数配置:tomcat配置文件server.xml数据库
maxThreads="1000" 最大并发数 后端
minSpareThreads="100"///初始化时建立的线程数浏览器
maxSpareThreads="500"///一旦建立的线程超过这个值,Tomcat就会关闭再也不须要的socket线程。
acceptCount="700"// 指定当全部可使用的处理请求的线程数都被使用时,能够放处处理队列中的请求数,超过这个数的请求将不予处理
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" acceptCount="500" maxThreads="600" acceptCount="800" maxSpareThreads="500" minSpareThreads="100"/>
四、运行LR的机器的配置及性能;
场景设置: 一个Vuser 完成登陆退出操做,执行时间为5分钟
result: 最大响应时间与最小响应时间,差距超大(120s,0.7s)
解决办法: 出现此状况为Run-Time settings -->General -->Pacing 没有配置
五、修改tomcat中web应用的log4j.xml日志级别为ERROR,将mysql数据库的输出日志级别改为ERROR;
mysql> show variables like '%log_error%';
+---------------+--------------------------------+
| Variable_name | Value |
+---------------+--------------------------------+
| log_error | /tmp/DB-Server.localdomain.err |
六、修改Linux的访问最大进程数
linux用户的最大进程数 ulimit须要修改,默认是1024,修改命令:ulimit -n 10240
七、安装数据库和linux相关监控工具;
(1)淘宝有一款开源监控工具orzdba
代码SVN地址:http://code.taobao.org/p/orzdba/src/trunk/
八、修改ngnix配置
若是须要获得请求处理的时间,须要在nginx log 里面加上$request_time,下面是个人log_format
nginx.conf
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent $request_body "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for" "$request_time"';
修改以后重启nginx,查看nginx log的时候,就能看到nginx处理请求所花的时间了,这个时间基本就是后端所花的时间,因此能够根据这个字段来获得响应慢的请求。
9.使用性能监控工具:zabbix、newrelix,国内的监控宝均可以考虑
2、性能测试分析
一、性能测试运行时应用数据库查看
例如:读写状况、并发数状况、数据库缓存状况、内存使用状况、cpu使用状况、网络状况
监控工具:zabbix
查看如下命令:查看MYSQL一些状态,有没有一些链接一直占用着;是否占用链接数达到限制;
(1)链接数查看命令:
while true; do mysqladmin -uroot -p'test@jushi!123' processlist|wc -l;sleep 3; done
(2)MySQL服务器的链接总数: show status like '%connect%';
Aborted_clients 因为客户没有正确关闭链接已经死掉,已经放弃的链接数量。
Aborted_connects 尝试已经失败的MySQL服务器的链接的次数。
Connections 试图链接MySQL服务器的次数。
Max_used_connections 同时使用的链接的最大数目。
Slow_queries 要花超过long_query_time时间的查询数量。
Threads_connected 当前打开的链接的数量。
Threads_running 不在睡眠的线程数量。
(3) 查看当前正在进行的进程,对于有锁表等状况的排查颇有用处
SHOW PROCESSLIST; 默认显示前100条
SHOW FULL PROCESSLIST; 显示全部
command列:显示当前链接的执行的命令,通常就是休眠(sleep),查询(query),链接(connect)。
(4) 显示当前mysql状态:mysqladmin -u -p -h status
[root@db ~]# mysqladmin -uroot -p -hlocalhost status
Enter password:
Uptime: 14604445 Threads: 208 Questions: 34034734 Slow queries: 179 Opens: 12553 Flush tables: 3 Open tables: 977 Queries per second avg: 2.330
(5)显示mysql的其余状态:mysqladmin -u -p -h extended-status
[root@db ~]# mysqladmin -uroot -p -hlocalhost extended-status
Enter password:
+------------------------------------------+--------------+
| Variable_name | Value |
+------------------------------------------+--------------+
| Aborted_clients | 53041 |
| Aborted_connects | 163 |
| Connections | 1116157 |
…… 略
| Threads_connected | 206 |
| Threads_created | 633 |
| Threads_running | 1 |
| Uptime | 14604661 |
| Uptime_since_flush_status | 14604661 |
+------------------------------------------+--------------+
(6)慢查询show global status like '%slow%';
(7)链接数
设置的最大链接数是500,而响应的链接数是498
max_used_connections / max_connections * 100% = 99.6% (理想值 ≈ 85%)
http://blog.csdn.net/zhangliangzi/article/details/51884863
(8)进程使用状况
若是咱们在MySQL服务器配置文件中设置了thread_cache_size,当客户端断开以后,服务器处理此客户的线程将会缓存起来以响应下一个客户而不是销毁(前提是缓存数未达上限)。Threads_created表示建立过的线程数,若是发现Threads_created值过大的话,代表 MySQL服务器一直在建立线程,这也是比较耗资源,能够适当增长配置文件中thread_cache_size值,查询服务器 thread_cache_size配置:
(9)表锁状况
Table_locks_immediate 表示当即释放表锁数,Table_locks_waited表示须要等待的表锁数,若是 Table_locks_immediate / Table_locks_waited > 5000,最好采用InnoDB引擎,由于InnoDB是行锁而MyISAM是表锁,对于高并发写入的应用InnoDB效果会好些.
(10) TPS(每秒事务量)
TPS = (Com_commit + Com_rollback) / seconds
mysql > show global status like 'Com_commit';
mysql > show global status like 'Com_rollback';
(11)Query Cache命中率
mysql> show status like 'Qcache%';
Query_cache_hits = (Qcahce_hits / (Qcache_hits + Qcache_inserts )) * 100%;
(12)查看linux实时内存及CPU状态:vmstat 3 50
二、性能测试运行时应用服务器查看
应用服务器:tomcat内存使用状况、CPU使用状况、读写状况、网络流量使用状况等;有没有dump日志
(1)查看linux内存:vmstat 3 50
98.7% id 空闲CPU百分比
top
进入top以后,按数字键1,你就能看到多个CPU了。
%CPU=(进程的生命周期中占用CPU的时间)*100/(进程的生命周期表明的时间长度)
好比一个进程的生命周期的时间长度是1000s,而后在这1000s内占用CPU的时间是500s,那么
%CPU=500*100/1000=50
即最后的结果表示50%
load average: 0.06, 0.60, 0.48 系统负载,即任务队列的平均长度。
三个数值分别为 1分钟、5分钟、15分钟前到如今的平均值。
Cpu(s): 0.3% us 用户空间占用CPU百分比
1.0% sy 内核空间占用CPU百分比
0.0% ni 用户进程空间内改变过优先级的进程占用CPU百分比
98.7% id 空闲CPU百分比
0.0% wa 等待输入输出的CPU时间百分比
(2)查看硬盘存储
df -h
(3)查看java进程实时状况
JVM进程情况工具:jps -m
查看19434的线程快照:jstack -l 19434
输出java堆栈信息打印日志:jstack 19434 >test.log
获取dump日志:jmap -dump:format=b,file=heap.dump 19434
用如下命令查看dump日志,会转成html:jhat {dump_file}
启动成功:浏览器访问:http://192.168.1.50:7000/便可查看;
(4)因为日志过多致使系统存储空间不足;
查看命令:df -h
(2)获取tomcat日志、数据库日志、ngnix日志并分析日志错误地方;
四、LR报告:
(1)LR中的最大响应时间参考价值不高;
(2)LR平均响应时间average transaction response time(整个场景测试中的平均响应时间)
采样时间可进行配置
Summary是按整个场景的时间来作平均的,最大最小值,也是从整个场景中取出来的。
而平均事务响应时间图里,是按频率来取值。这两个值没有什么可比性。也没有什么关系。
只是一堆数据的不一样计算方法。在取样时间内,有可能比summary里的高,有可能低,有可能持平。
(3)各参数说明
关于事务状况的总结
Total Passed(事务的总经过数)
Total Failed(事务的总失败数)
Total Stopped(事物的总中止数) 手工事务中没有此项
SLA Status(SLA状态)在SLA中的最终结果
Minimum(事务最小时间)
Average(事务平均时间)
Maximum(事务最大时间)
Average Transaction Response Time
Transactions per Second TPS吞吐量
Transaction Performance Summary
Throughput 带宽使用,该值越小说明系统对带宽依赖越小,此处使用的单位是字节(大B),百兆带宽指的是小b(位)
Connections per second 每秒链接数,此值与服务器的链接池大小有关,其中包括两个值,中断的链接数,新建的链接
数,当服务器中链接池用完时,服务器会返回504错误。
3、优化过程
一、问题一:
原代码
@Transactional(readOnly = false, propagation = Propagation.REQUIRES) public String getFuneralOrderNoSeq() throws ZdnstException { String seq = ""; try { int i=this.updateAddSeqNumBySeqId(Constants.SYS_FUNERAL_ORDERNO_SEQ); if(i==0){ SysSeq sysSeq=new SysSeq(); sysSeq.setSysSeqId(Constants.SYS_FUNERAL_ORDERNO_SEQ); sysSeq.setSeq("1"); sysSeqMapper.insert(sysSeq); } // 获取用户帐号 SysSeq sysSeq = sysSeqMapper.selectByPrimaryKey(Constants.SYS_FUNERAL_ORDERNO_SEQ); // 从新插入序列号 if(Integer.parseInt(sysSeq.getSeq())==9999){ sysSeq.setSeq("1"); sysSeq.setCreateTime(DateUtils.getCurTimestamp()); sysSeqMapper.updateByPrimaryKey(sysSeq); } String fSeq=this.gengercode(4, sysSeq.getSeq(),DateUtils.DATE_FORMAT_YYYYMMDD); return fSeq; } catch (ZdnstException e) { //打印服务层异常详情,注意第二个参数必须传打印异常堆栈 logger.error(Constants.EX_SERVICE_EXCEPTION + BaseCode.getDetailMsg(e), e); //必须抛出通知调用者 throw new ZdnstException(e.getCode(),e.getMessage()); } catch (Exception e) { //打印服务层异常详情,注意第二个参数必须传打印异常堆栈 logger.error(Constants.EX_SERVICE_EXCEPTION + BaseCode.getDetailMsg(e), e); //封装为服务层异常110网络超时后再抛出,必须抛出通知调用者 throw new ZdnstException(BaseCode.ERROR_CODE110,e.getMessage()); } }
修改位置:将这一块独立成一个新事物,具体修改是:将propagation = Propagation.REQUIRES修改为propagation = Propagation.REQUIRES_NEW
二、问题二
未完,待续……
性能测试调优应该注意的要点: