1,性能瓶颈诊断
可以使用阿里的arthas工具来进行性能监控和诊断,使用比较简单,直接下载jar包运行在需要监控的机器上即可。
可以抓取java进程的火焰图来观察比较耗时的方法:
wget https://github.com/jvm-profiling-tools/async-profiler/releases/download/v1.8.5/async-profiler-1.8.5-linux-aarch64.tar.gz
tar -zxf async-profiler-1.8.5-linux-aarch64.tar.gz
cd async-profiler-1.8.5-linux-aarch64
./profiler.sh -d 30 -f flagmegraph.svg <pid> #-d表示采样时间
可以抓取cpu火焰图来观察cpu的性能瓶颈:
git clone https://github.com/brendangregg/FlameGraph.git
perf record -F 99 -p <pid> -g --sleep 30
perf script | FlameGraph/stackcollapse-perf.pl | FlameGraph/flamegraph.pl > process.svg #-F表示每秒99次,--sleep为持续时间
2,压测工具
建议使用jmeter5.3,修改好后缀为.jmx的配置文件后,可以通过gui的方式启动,也可以通过命令行方式启动,在命令行查看输出信息。
命令行方式:jmeter -n -t xx.jmx
gui方式:jmeter -t xx.jmx
jmeter还支持分布式测试。
如果出现java.net.NoRuteToHostException,是因为客户端的端口被占用完了,执行以下命令可以解决:
echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout
echo 1 > /proc/sys/net/ipv4/tcp_tw_reuse #开启端口可重用
3,JVM参数优化
调优原则:每次minor GC尽可能多地收集垃圾对象;尽量减少full GC的次数;GC能处理的堆空间越大越好;在三个性能属性(吞吐量、延迟、内存占用)中优先选择两个进行调优;避免创建生命周期短的大对象
调优方法:通常设置-Xms和-Xmx相同,避免堆膨胀带来的性能变化;JDK8以后默认为G1GC,G1GC更适合大堆,超大堆还可以使用ZGC,JDK8以下优先选用CMS+ParNew,如果吞吐量有限就选择Parallel Scavenge+Parallel Old。
4,服务器优化
线程绑核:对于多核服务器而言,可以通过将不同的线程绑定到不同的CPU核上来更合理的分配CPU资源提高性能。在以往的项目案例中,通过将tomcat的accept线程,poller线程和worker线程绑定在不同数量的cpu核上(给accept线程分配了一个单独的cpu资源),获得了不错的性能提升。使用命令taskset -pc 1-7 <pid>可将进程绑定到1-7cpu核上运行。
对于numa架构的服务器,通常将应用绑定在同一个numa上的cpu核。
os参数优化:os即操作系统,可以通过调整net.core.rps_sock_flow_entries、kernel.halt_poll_threshold、kernel.sched_wakeup_granularity_ns、kernel.sched_min_granularity_ns等参数来提升性能,调整参数的命令格式为sysctl -w sched_min_granularity_ns=3000000,这些内核参数的含义可以自行查询。
选择合适的JDK:不同版本和不同平台的JDK可能表现出来的性能也有所差异,尽量选择合适的JDK。
5,top命令使用
t可以通过top -H -p <pid>来查看java线程的cpu使用情况。
top命令面板中,按i可以过滤掉空闲进程;按c可以显示进程的详细启动命令(可以通过这个查看java进程的位置和启动参数);还可以按o进行条件过滤;
如果需要观察线程运行在那些cpu核上,按f,将光标移动到p,按空格选中,然后按esc返回。
如果需要排序,按f,将光标移动到需要排序的列,然后按esc返回。
还有ps -T -p <pid> 也可以查看线程信息
定位cpu占用高的线程:
top -H -p <pid>
printf "%x\n" <sid>
jstack <pid> |grep <转换sid的结果> -A 30
6,反编译工具
有时候线上诊断问题可能需要查看源代码,但是一时拿不到源码或者源码丢失,就需要用到反编译工具。
可以使用jd-gui-1.6.6.jar和luyten-0.5.4.jar,两个反编译工具各有优缺,比较推荐jd-gui,两个都可以在github上下载。