性能调优
调优说明
以下为核心调优参数说明,可通过调优参数最大可能压榨服务器性能,但仅建议根据实际情况调整参数,若盲目配置容易起到反作用哦。
Linux 操作系统参数
系统全局允许分配的最大文件句柄数:
# 2 millions system-wide
sysctl -w fs.file-max=2097152
sysctl -w fs.nr_open=2097152
echo 2097152 > /proc/sys/fs/nr_open
允许当前会话/进程打开文件句柄数:
ulimit -n 1048576
/etc/sysctl.conf
持久化 fs.file-max
设置到 /etc/sysctl.conf 文件:
fs.file-max = 1048576
/etc/systemd/system.conf 设置服务最大文件句柄数:
DefaultLimitNOFILE=1048576
/etc/security/limits.conf
/etc/security/limits.conf
持久化设置允许用户/进程打开文件句柄数:
* soft nofile 1048576
* hard nofile 1048576
TCP 协议栈网络参数
并发连接 backlog 设置:
sysctl -w net.core.somaxconn=32768
sysctl -w net.ipv4.tcp_max_syn_backlog=16384
sysctl -w net.core.netdev_max_backlog=16384
可用知名端口范围:
sysctl -w net.ipv4.ip_local_port_range='1000 65535'
TCP Socket 读写 Buffer 设置:
sysctl -w net.core.rmem_default=262144
sysctl -w net.core.wmem_default=262144
sysctl -w net.core.rmem_max=16777216
sysctl -w net.core.wmem_max=16777216
sysctl -w net.core.optmem_max=16777216
#sysctl -w net.ipv4.tcp_mem='16777216 16777216 16777216'
sysctl -w net.ipv4.tcp_rmem='1024 4096 16777216'
sysctl -w net.ipv4.tcp_wmem='1024 4096 16777216'
TCP 连接追踪设置:
sysctl -w net.nf_conntrack_max=1000000
sysctl -w net.netfilter.nf_conntrack_max=1000000
sysctl -w net.netfilter.nf_conntrack_tcp_timeout_time_wait=30
TIME-WAIT Socket 最大数量、回收与重用设置:
sysctl -w net.ipv4.tcp_max_tw_buckets=1048576
# 注意: 不建议开启該设置,NAT模式下可能引起连接RST
# sysctl -w net.ipv4.tcp_tw_recycle=1
# sysctl -w net.ipv4.tcp_tw_reuse=1
FIN-WAIT-2 Socket 超时设置:
sysctl -w net.ipv4.tcp_fin_timeout=15
blade-broker 服务配置调优
日志级别调整
优化日志打印,提高日志级别,将一些不必要和重复的日志打印去掉。特别是一些报文的打印,正式环境一定要去掉。
org.tio: ERROR
org.tio.server: ERROR
net.dreamlu: ERROR
时序库配置调整
如果你的服务有大量的写入,可以调大时序库的连接池数和批量的批次大小 batchSize
,调小一个批次任务的写入时间 flushDuration
(不建议过小,建议配置 300ms ~ 1s 之间)。
blade-broker 工作线程调优
blade-broker 服务端默认的业务线程数是 CPU 核心 2 倍(最小默认为 8),如果服务端也遇到上述业务处理耗时大、消息量大,导致的处理不赢,建议将消息转发到 kafka、rocketmq,然后将耗时的业务添加多个服务去消费 mq,后续版本会直接支持。当然你还可以尝试使用 java21 虚拟线程,能得到几倍的性能提升,当然 CPU 和内存消耗会多一些。
虚拟线程配置
import net.dreamlu.iot.mqtt.core.server.MqttServerCreator;
import net.dreamlu.iot.mqtt.spring.server.MqttServerCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.concurrent.Executors;
@Configuration(proxyBeanMethods = false)
public class MqttServerCustomizerConfiguration {
@Bean
public MqttServerCustomizer mqttServerCustomizer() {
return new MqttServerCustomizer() {
@Override
public void customize(MqttServerCreator creator) {
// 设置业务线程,使用 java21 虚拟线程
creator.mqttExecutor(Executors.newVirtualThreadPerTaskExecutor());
}
};
}
}
问题定位
为了提高Java应用的性能监控和故障排查效率,建议在启动Java虚拟机时配置自动内存溢出转储选项:
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=heapdump.hprof
这样,在应用运行过程中一旦遭遇内存溢出或CPU使用率异常高的情况,就可以利用以下步骤进行分析:
检查日志异常:首先查看应用日志,确认是否存在大量异常输出。如果发现异常,根据日志内容进行问题分析和定位。
进程和线程分析:
- 使用
jps
命令获取Java进程的pid
。 - 执行
jstack -l [pid]
命令,检查是否有线程状态为BLOCKED
或存在调用栈过深的情况。 - 根据调用栈信息,分析并定位到具体的代码问题。
- 性能分析工具应用:
- 利用
jprofiler
(jprofiler 快速分析内存泄露实战)或Arthas工具收集火焰图,深入分析调用栈的耗时情况。 - 在本地开发环境中,可以利用IDE(如IntelliJ IDEA)内置的 Profiler 进行实时性能监控。
- 网络性能调优:
- 如果发现网络连接问题,如连接数少或释放时间长,可以参考上文的TCP协议栈网络参数章节进行针对性的调优。
通过上述步骤,可以更有效地诊断和解决Java应用中的性能问题。