在实际项目中,Java 应用的性能瓶颈通常出现在哪些方面,又该如何有效地进行优化?
这个问题关于性能和并发数,先说如何确定性能或并发需求。
1 根据以往历史经验,比如某电商以前的促销活动,会有一秒并发3000个请求。
2 或者客户方有需求,要求接口或请求在1秒内返回。
这就是性能测试或压力测试的目标。你说了这个,就说明你在项目里真正做过性能调优方面的工作,性能调优的目标不是拍脑袋想的。
一般来说,大多数的中小公司项目,是没有并发量需求的,即每秒的并发量不会超过50,但可能对接口性能有需求,比如接口要在500毫秒内返回。
再说下如何确定你的系统是否满足这个性能要求,一般是通过压力测试,一般做法如下。
1 搭建个线上一样的系统,比如线上有几台主机,测试环境这样搭建,或者在不忙的时候,直接用线上环境做压力测试。
2 用jmeter或其它工具,模拟并发需求,比如一秒发3000个请求,看这些请求的处理时间是否满足需求,比如是否在一秒内处理好。
3 压力测试过程中,数据库和服务器,一般会连接zabbix或newrelic或skywalking等,确认在压力测试过程中,cpu,内存的用量不会太高,比如不会超过80%,同时确保每个sql语句都会在2秒内返回,即不会出现慢慢查询。
最后再说下,如何根据压力测试结果制定性能调优的策略,或者是排查解决性能问题。
1 扩容,这个是最直接的。
比如业务jar包部署在一台电脑上,当下能应对100并发量,但需求是一秒200并发量,或者是,客户要求接口在1秒内返回,但现在普遍在1.5秒,那就把jar包部署到2台电脑上。用nacos做服务治理,用nginx或gateway做网关,用负载均衡的方式提升性能。
2 看日志,或者看监控组件,如果大量出现慢查询,或者是某个带数据库请求的动作,执行很久再返回,那或者用索引和执行计划逐一排查,或者引入redis缓存。
不过,在大多数情况下,比如500并发量以内,用单机版redis真就够了,未必要用到redis集群,也未必要用到redis持久化这套。
3 比如某个业务动作要远端很久再返回,比如发个风控请求,风控服务器要2秒返回,那可以把此类请求改成是异步的,就发请求到风控端,然后本次请求直接关掉,等风控端来结果后,再发到消息队列,这样能提升性能。
4 然后就逐一排查了,比如发现cpu或内存问题,或者看dump文件,或者用linux命令排查。
以上属于面试技巧,而说并发,只是其中的一方面,关于Java面试,本人还完稿过一本书,其中有面试素材,包括亮点说辞和解决过问题,也包含并发方面的说辞。但由于书号的原因,没法出版了。
这里包含了本人的面试官经验,也包含了本人辅导其它朋友求职的点点滴滴,所以本人相信,把这些资料给到大家的同时,适当收些费用,也是说得出口的。电子版,现在收费是69,之后大概率会涨价。