项目中的性能瓶颈
反应在三个方面:
1、机器不够了:每个机器的cpu利用率都达到了50%以上,需要新增机器。
2、接口性能慢:使用多线程方式去做事情,保证接口响应
1、一次调用第三方模块比较多的情况下出现耗时,把串行方式改为多线程去调用阻塞同步,对一次性查询过多的数据情况,把数据分片查询在组合。
2、对不要求立即返回的操作,做异步处理,比如下载一个Excel文件,可以在子线程中写好通知用户下载,在一些批量操作的情况下,之前是异步的处理,处理好了之后通知用户,后来改成mq的形式,在mq机器上操作完成后通知用户。
3、数据库慢查询:优化sql 使用缓存 使用ES做检索。
系统遇到的坑
1、之前由于某个时段,db集群问题,主从延迟高,所以就使用redis来做一个分布式锁来解决短时间内插入问题,具体问题是我插入记录后,需要进行查询,如果验证没有就需要新增,验证过程走从库,但是从库没有,就又新插入一条数据,所以就有2份数据了,所以就使用了这个方式来阻止插入2个记录,其实也可以在数据库加入一个多个字段联合的唯一索引来实现,但感觉用数据库的索引来约束成本有点高,就使用redis来实现。
2、之前出现过一次cpu利用率过高情况,排查的思路就是:
1、可能猜测的三个原因就是接口调用量增加了发现也没有,如果是就加机器看看。
2、如果不是,先用top找出cpu高的进程,一般都是java进程,然后在top (-Hp pid)出对应的使用率高的线程,然后线程 id 转化16进制,使用了jstack命令(jstack 419 | grep -A 30 58a)去实际定位某一个线程堆栈的具体代码快,发现是某一行代码的问题:进入了死循环导致cpu过高(使用了阻塞队列,把poll改为take poll会返回null导致一直训练 take会阻塞等待)后来才知道公司有一个JVM性能诊断优化平台,选择主机,去诊断5分钟左右,他会自己生成jvm参数、调用堆栈树生成近一段时间各个方法占用CPU的情况,热点分析树(统计出CPU上调用最频繁的方法)。
3、公司内部听过别人分享过一些频繁gc问题:
主要是yongGC fullGC:
1、因为Metaspace不足引发频繁 Full GC排查:好像原因都是因为使用了一些第三方框架(比如AviatorEvaluator、),第三方框架使用了反射手段,反射生产了大量类的class对象,class对象就是类的元信息保存在Metaspace,XX:SoftRefLRUPolicyMSPerMB参数设置不对,因为反射生产出的类的class对象是软引用,如果设置为0就导致这些软引用对象会被频繁yong GC,GC了对象之后后面的反射又回新增class对象,导致Metaspace记录越来越多的类元信息,最后导致Metaspace full GC。
解决方式有:
1、把框架用反射生产的类的class对象缓存起来,有就使用缓存不会新生产一个类的class对象,就不会往Metaspace区写
2、设置调大一些-XX:SoftRefLRUPolicyMSPerMB=0 参数,这样就不会一直yong GC类的class对象。
2、老年代触发FULL GC,查看gc日志发现gc频繁,出现大量Allocation Failure问题,日志里面记录发现多数情况都是因为在年轻代中没有足够的空间能够存储新的数据问题。并且是一些新生代的大对象导致。就直接分配到老年代,触发FULL GC,应避免在局部构建大对象。
工具方法:
1、使用jmap -heap分析堆使用情况 :
2、方法一般都是使用 jmap -dump:format=b,file=/tmp/dump PID 把线上进程的快照dump下来一份分析。但是如果堆比较大,可能暂停太久了不行 和 jmap -histo:live 或手动触发full gc。
- 还遇到那些线上问题,怎么去解决的
我再学习学习
待学习点:
三、关于BIO,NIO,AIO,Netty及Redis线程模型
1、BIO,NIO,AIO的区别?
2、什么是阻塞IO以及非阻塞IO?
3、Reactor和Proactor IO设计模式是什么?
4、NIO底层select、poll和epoll实现的区别 ?
5、Java NIO的几个核心组成部分是什么?作用分别是什么?
6、Redis、Netty、Tomcat的线程模型与NIO的联系是什么?
Future、FutureTask、CompletableFuture的比较
mysql事务隔离级别
1、读未提交 可避免丢失更新,不可避免脏读、不可重复的和幻读
2、读已提交 避免脏读,不可避免不可重复的和幻读
3、可重复读(默认隔离级别)