性能优化建议
大约 3 分钟
优化原则
性能优化应按“压测建立基线、监控定位瓶颈、逐项调参、回归验证”的流程推进。不要只凭经验调整参数,尤其是 JVM、数据库连接池、Redis 内存策略和 MQTT 连接数,应结合实际设备规模和接口峰值验证。
性能关键点
| 层级 | 重点指标 | 优化方向 |
|---|---|---|
| Nginx | 连接数、状态码、响应时间、502/504 | worker、超时、Gzip、上游健康 |
| Java | CPU、堆内存、GC、线程池、接口耗时 | JVM 参数、线程池隔离、异步化 |
| Redis | 命中率、内存、慢命令、连接数 | TTL、预热、淘汰策略、批量操作 |
| 数据库 | 慢 SQL、锁等待、连接数、TPS | 索引、分页、连接池、事务范围 |
| MQTT | 在线连接数、消息速率、认证耗时 | Broker 集群、ACL、回调性能 |
| 时序库 | 写入速率、查询耗时、磁盘空间 | 批量写入、分区、保留周期 |
| 视频服务 | 拉流成功率、带宽、端口占用 | 码率、转码、录制目录、网络策略 |
Nginx 优化
- 根据 CPU 核数调整 worker 数量,结合并发量调整连接数。
- 静态资源开启合理缓存,接口和 WebSocket 配置独立超时。
- 长连接场景要关注
proxy_read_timeout、上游健康和连接释放。 - HTTPS 场景需要关注证书、TLS 版本、会话复用和加密套件。
Java 与线程池
- 容器环境中明确设置堆大小、元空间、直接内存和 GC 策略。
- Web 请求、设备接入、规则执行、通知发送、定时任务建议分离线程池。
- 队列必须有上限,并定义拒绝策略,避免瞬时流量导致内存膨胀。
- 对耗时操作使用异步处理,并保留可追踪日志和失败重试机制。
缓存与数据库
- 热点数据优先缓存,缓存键要有统一命名和过期策略。
- 防止缓存穿透、击穿和雪崩,必要时加入空值缓存、分布式锁和 TTL 分散。
- SQL 查询优先优化索引、条件过滤和分页,不建议一次性返回大结果集。
- 设备历史数据写入量较大时,优先进入时序库,并设置数据保留周期。
压测与容量规划
- 明确目标:在线设备数、消息频率、接口 QPS、P95/P99 延迟、错误率。
- 分层压测:先测 Nginx/API,再测 MQTT 接入、规则处理、数据库写入和视频链路。
- 记录基线:保存硬件规格、容器配置、JVM 参数、数据库参数和压测脚本。
- 单项调整:一次只调整一个主要变量,避免无法判断优化来源。
- 回归验证:确认功能、错误率、资源占用和数据一致性没有退化。
监控指标
| 对象 | 建议采集 |
|---|---|
| 系统 | CPU、内存、磁盘、网络、文件句柄 |
| Nginx | QPS、状态码、响应时间、上游错误 |
| Java | GC、堆内存、线程、接口耗时、异常数 |
| Redis | 内存、命中率、慢命令、连接数 |
| MySQL | 慢 SQL、锁等待、连接池、TPS、复制延迟 |
| EMQX/MQTT | 在线连接数、消息速率、认证失败、订阅数 |
| 时序库 | 写入吞吐、查询耗时、磁盘使用率 |
常见问题
- 页面慢:先看静态资源体积、Nginx 缓存、接口耗时和浏览器网络瀑布。
- 接口超时:检查线程池、数据库慢 SQL、Redis 慢命令和外部服务回调。
- 设备消息积压:检查 Broker 吞吐、规则执行耗时、数据库写入和消费者并发。
- JVM 频繁 GC:检查堆大小、对象分配、缓存对象和大结果集查询。
- 数据库压力高:检查索引、分页、事务范围、热点表和归档策略。
