JAVA程序性能分析及调优浅析

17 篇文章 0 订阅
[b]搬掉绊脚石,将内容不断靠近用户![/b]

[b][size=medium]keep it simple, stupid[/size]![/b]

关键词:[u][color=red]CPU时间占比、当前执行的SQL语句、执行时间过长的方法、代码屏蔽[/color][/u]

1. [b]性能分析本质[/b]

[color=red]寻找系统的性能瓶颈(木桶理论/短板效应),并处理系统的性能瓶颈[/color]

2. [b]性能分析主要指标[/b]

[color=red]负载、响应和服务器CPU\MEM\IO等的使用率[/color]

3. [b]性能分析主要工具[/b]

[color=red]LoadRunner、VisualVM、MySql 客户端工具(或类似工具)和Linux命令(或监控工具)[/color]

4. [b]性能分析及处理思路[/b]

4.1. 代码

[u][color=red]避免代码里面的循环数据库查询[/color][/u](梳理业务,基本都可以实现为非循环方式)

避免代码里面的循环数据库更新处理(插入、更新等),尽量采用批量方式

[color=red]注意合并类似的SQL语句(主要是谓词,即查询条件大致相同),[/color]将某些计算放置到程序中,减少对数据库的查询等操作

避免生产新的、耗时和耗内存的对象,即消耗内存,又消耗CPU
比如获取方法调用栈轨迹,有人采用new Throwable().getStackTrace() 方式来获取,就比较有问题了,该对象的生成相对来说很耗资源,测试某个长事务过程中,CPU占比达整个的4%,实际上可以采用Thread.currentThrread.getStackTrace() 来处理该需求

[u][color=red]使用private、final和static方法,即使代码结构合理,也能运行更有效率[/color][/u]

[u][color=red]采用必要的缓存[/color][/u](主要针对不易变化的,非实时性要求的数据,比如字典表,排名等)

[color=red]前台能处理的,尽量放到前台[/color],以充分利用客户电脑,节约带宽及服务器CPU\MEM等资源

4.2. 业务

业务是否可以简化?
简化之后是不是可以去掉不必要的代码?是不是可以实现更简单,逻辑更清晰?
[u][color=red]对代码的调整很多其实也是对业务的精炼![/color][/u]

4.3. SQL(MySql)

1、[u][color=red]开启慢查询[/color][/u](捕获慢查询SQL语句)
在my.cnf文件[mysqld]后面,添加如下:
slow_query_log
slow_query_log_file=/export/servers/mysql/mysql_slow.log
long_query_time=0.1

2、[u][color=red]show full processlist[/color][/u]
压力测试期间,捕获当前执行SQL语句,重点关注state列和info列
[table]
|Id|User|Host|db|Command Time|State|Info
|318236|root|…|db_name|7085|sending data|SELECT …
[/table]
state列正常情况下应该都是空(应为执行都很快),但假如你看到了sending data, statistics等,很不幸(如果很多),这往往伴随着CPU时间占比很高,这个时候往往表明你需要调整该SQL语句,或者相关调用代码或者其余处理措施(当然,有时候是负载实在太高了!)
Info列则是当前执行的SQL语句,show full processlist中的full的作用就是你可以查看完整的SQL语句

3、[u][color=red]解释相关SQL语句[/color][/u]
Explain/相关MySql客户端工具

4、show index from tbname/alter table tbname add index idx_idxname(colname)
[color=red]根据explain和show index等,对相关sql语句进行索引优化[/color]

4.4. 配置

1、数据库服务器配置,重点关注以下配置(具体参数配置标准请google):
max_connections=1000
key_buffer_size = 16M :主要针对MyISAM存储引擎
table_open_cache=10000
[u][color=red]innodb_buffer_pool_size[/color][/u] = 10g :主要针对InnoDB存储引擎
[u][color=red]query_cache_size[/color][/u]=32m
可通过SHOW GLOBAL STATUS LIKE 'qcache%';查看查询缓存的使用情况,单交易压力
测试表征意义不大,要在混合场景稳定性测试等环境中观察

2、应用服务器配置(内存、线程池)
请参考TOMCAT6性能优化文档 [url]http://shuhucy.iteye.com/admin/blogs/1709296[/url]

3、数据库连接池
根据实际需要配置、调整,(一般小于线程池数目,可设置为其一半)

5. [b]瓶颈定位方式[/b]

5.1. [u][color=red]基于单交易压力测试[/color][/u]
单交易压力测试等,最好排除相关影响因数,比如你要测试一个添加,但你需要先进入一个列表,才能处理添加,这个时候,你可能需要在脚本里面将这个列表的代码去掉,避免该处代码对添加事务的影响,使添加事务更纯净,更易于定位问题

5.2. [u][color=red]监控相关服务器资源使用情况[/color][/u]
重点关注CPU时间占比,内存等使用情况,可通过top、vmstat等命令监控
比如此次性能分析过程中数据库库服务器CPU占比很容易很高(往往解决了一个又来了另一个),这时可以通过数据库客户端工具摘取当前执行SQL语句,并通过工具分析(或者自己explain),查看索引使用情况,如果没有索引或不存在有效索引,则添加相关索引,并且注意调用该语句的代码是否是循环处理的,如果是循环处理,请提炼至循环外层

5.3. [u][color=red]通过VisualVM进行CPU、内存使用采样及垃圾回收监控[/color][/u]
比如通过CPU采用,分析相关方法执行CPU占比,定位执行时间过长的方法,进行相关优化。
[img]http://dl.iteye.com/upload/attachment/0078/8287/e39e7017-6de0-3e87-aebf-2d9c583f1efb.png[/img]

5.4. [u][color=red]通过代码屏蔽方式定位[/color][/u]
可以通过屏蔽代码的方式以定位瓶颈点或者确认瓶颈点

[b]注意事项:[/b]
1、[u][color=red]避免压力测试脚本问题及其与环境、配置问题[/color][/u]
比如压力测试脚本不纯净,服务器对某一IP过多访问存在限制、线程池配置太小,数据库连接池配置太小,文件打开数超过系统限制等
2、[u][color=red]避免问题定位错误[/color][/u]
某次压测发现CPU占比很高(90%),进行过一定的分析,发现数据库服务器网络负载在
200多M(浏览器压测情况下没有启用缓存,页面图片量比较大),开始认为是网络带宽问题,但实际上,把页面的代码都注释掉(基本空页面),带宽很低,但CPU并没有降低,最后通过添加MySql查询缓存解决该问题!

某次压测发现数据库服务器A的CPU占比很低,但就是TPS很低(正常情况下,数据库没有压力,适当的迸发环境下TPS一般应比较高),用工具连接数据库服务器,执行show processlist 发现state基本为空,很正常,查询相关配置参数,也没做更改。之后想起来还有另外一台数据库服务器B,会不会是B服务器导致的了?在B服务器上top一看,CPU占比90%,show full processlsit数据库一看,state很多sending data,info列重复很多一个查询语句,explain该语句,发现该语句缺少相应的索引!添加相关索引即TPS恢复正常
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值