一、为什么调优?
1、随着时间积累问题凸显。机器定时宕机,重启后恢复正常,以此循环
2、搞活动并发量导致。不知道性能的极限,并发量导致性能瓶颈
3、定时炸弹。上线后一直半死不活,无人问津。
4、(最直接的目的)提高系统性能,缩减服务器数量,节省公司资源
二、什么时候调优?
1、开发初期
无需刻意优化,影响开发进度,带来新问题
保证有效编码。如,减少磁盘IO、降低锁竞争、高效算法、设计模式应对复杂场景(折扣、红包活动)
2、编码完成
压测,通过工具分析系统性能指标,是否符合预期范围
3、上线后
根据实际情况,根据工具(日志监控、性能统计日志),观察系统性能问题并及时修复
三、如何调优/调优的指标?
1、哪些计算机资源,会成为系统的性能瓶颈?
cpu,有些应用需要大量计算,一直霸占cpu,导致其他资源无法争夺cpu而响应缓慢。
如,
代码循环递归
正则表达式的回溯问题
jvm频繁 full gc
多线程造成的大量线程切换
内存
java程序通过jvm对内存进行管理。jvm中的堆用于存放java创建的对象
堆内存读写速度快,不存在读写性能瓶颈,但是内存存储空间有限,当内存空间被占满,对象无法回收,会遇到内存溢出、内存泄漏问题。
磁盘IO,存储空间大,读写慢,可以通过SSD固态硬盘来优化。读写速度 内存 > SSD固态硬盘 > 磁盘
网络,若传输数据大、并发量大,需要增加网络带宽。
异常,java应用抛出异常 需要构造异常栈,对于异常的捕获和处理 非常消耗系统性能,尤其是并发环境。
数据库,大量数据库读写,会导致磁盘IO瓶颈。
锁竞争
为避免多线程操作共享资源,需要加锁保证原子性。同时,锁的使用 带来上下文切换,导致性能开销
jdk1.6后,java为降低锁竞争带来的上下文切换,对jvm内部锁做优化:偏向锁、自选锁、轻量级锁、锁粗化、锁消除。
合理的使用锁资源,需要了解更多的操作系统知识、java多线程编程基础
2、系统性能的衡量指标
响应时间(毫秒级),越小越好
自下而上 分类:数据库响应t(最耗时)、服务器t(nginx分发t、服务端t)、网络传输(网络硬件 解析传输请求 耗时)、客户端(一般忽略不计,除非有大量逻辑)
吞吐量(TPS 每秒事务量,体现接口性能,越大越好)
自下而上 分类:
磁盘吞吐量,2个关键指标
IOPS(input/output per second)每秒的输入输出量/读写次数。(次数)
指单位时间系统处理的IO请求数量(通常为读写请求),关注的是随机读写的性能。
适用于随机读写频繁的应用,如小文件存储(图片)、oltp数据库、邮件服务器
数据吞吐量(大小,关键指标)
指单位时间成功传输的数据量
对于大量顺序读写频繁的应用,传输大量连续数据。如:电视台的视频编辑、视频点播VOD
网络吞吐量,设备能够接受的最大数据速率
与带宽、cpu处理能力、网卡、防火墙、外部接口、IO有关
主要取决于,网卡处理能力、内部程序算法、带宽大小
计算机资源分配使用率
木桶效应:cpu占用率、内存使用率、磁盘IO、网络IO
负载承受能力
通过压测的不断加量,观察系统响应时间上升曲线是否平缓,分析系统极限。
迭代之前的版本的系统性能指标 作为参考标准,通过自动化测试,校验迭代发版后的系统性能是否异常
如:响应时间、吞吐量、负载能力、资源使用率(cpu、内存、磁盘IO、网络IO)
-------------------------------------------------------------
总结
why?不定期宕机、并发、没人用、提高性能 减少机器 节约钱
when?编码后上线前,压测系统极限;上线后,实时监控及时修复
how?
影响因素:
cpu,代码死循环、正则回溯、full gc、线程切换
内存,小而快,jvm堆存储java对象 --> 内存溢出
磁盘,大而慢,读写速度 :内存 > ssd > 磁盘
网络,数据包大/并发高--> 增加带宽
异常,异常栈 耗性能
数据库,读写并发 导致 磁盘IO
锁竞争,上下文切换 耗性能 --> 减少锁竞争,锁粒度细化
衡量指标
响应时间:db --> server端 --> nginx --> 网络 --> client
吞吐量
磁盘***:IOPS(频率)+数据吞吐量(大小)
网络***:网卡设置能接受的最大速率
资源占用率:cpu、内存、磁盘IO、网络IO等
系统极限:通过压测,观察系统响应时间是否平缓增涨,至极限
还没有评论,来说两句吧...