压测目的
本次压测意在寻找性能拐点,评估最大处理能力,并不断摸索操作系统与应用的调优参数
压测方案
压测场景
模拟单灯控制器,建立TCP链接,发送登录报文。登录成功后,不间断的发送属性上报消息。
创建虚拟设备
编写简易的JUnit脚本,以便于批量创建删除设备
录入10万个设备,设备ID为: 000000000001~000000100000
编写设备模拟器
由于单灯控制器通过TCP私有协议与平台进行通信,且上报消息的内容不固定,所以很难使用JMeter等常规压测工具进行测试。
需要自行编写单灯控制器模拟器,做为压测客户端,使用VertX异步框架开发以提高并发性能。
服务器指标监控
部署Prometheus
+Grafana
,进行图形化监控,方便查询历史指标并找出瓶颈点
消息样例
- 登录(42字节):
68230068000000002000002226130007500100020802034C4F43373930302D4331454C36313000A35116
- 属性上报(58字节):
68330068010000001300000e0000002001011003112700010fce590000003b400000dd242a426400000000000000000000000014000000f01216
压测环境搭建
服务端配置
- 1台普通台式机,配置为i7-7700 4核8线程/16G/256G/千兆LAN
- 最小化部署,应用及中间件混合部署在同一台服务器
服务端组件清单
类别 | 名称 | 版本号 |
---|---|---|
应用 | bifrost-ui | 1.0.0 |
应用 | bifrost-app | 1.0.0 |
中间件 | redis | 5.0.4 |
中间件 | elasticsearch | 6.8.11 |
中间件 | kibana | 6.8.11 |
中间件 | postgres | 11-alpine |
JDK | openjdk | 1.8.0_382 |
监控 | grafana | 10.3.3 |
监控 | prometheus | 2.50.1 |
监控 | nodeExporter | 1.7.0 |
服务端地址信息
类别 | 地址 | 帐密 |
---|---|---|
单灯TCP端口 | 10.90.22.200:1886 | |
UI | http://10.90.22.200:9000 | admin/1qaz@WSX |
Redis | 10.90.22.200:6379 | 仅密码:bifrost!23 |
ES6 | http://10.90.22.200:9200 | |
Kibana | http://10.90.22.200:5601 | |
Postgres | postgres://10.90.22.200:5432/bifrost | postgres/bifrost!23 |
Grafana | http://10.90.22.200:3000 | admin/1qaz@WSX |
压测客户端
- 4台Ubuntu虚拟机,配置为:8C/16G/500G/千兆LAN(实际只用到2台)
- Ulimit与内核参数的优化,与服务端保持一致
- 部署自行编写的单灯控制器模拟器
启动参数(以1万并发,120秒为例):
1 | java -jar catonelight-simulator-1.0.0-SNAPSHOT.jar --host=10.90.22.200 --port=1886 --start=1 --parallels=10000 --duration=120 |
压测详细记录
请参考11~12轮的结果即可,点击跳转至语雀在线表格:
https://tc-aiot.yuque.com/org-wiki-tc-aiot-ms6e4o/tabv3n/zug68i5yymut8vlg#CyG5
结果分析
- 8核16G的单机配置下,极限吞吐量为95502 TPS,极限并发数约为80000个设备
- 随着并发数的不断提升,TPS保待不变,响应时间成比例的增加。系统并未出现明显拐点。
- 内存占用量平稳,6-8G,基本无变化,上下文切换保持在60K左右
- 系统负载稳定保持在15左右(处理器为8核心),以上都是Reactor带来的收益
- 日志IO对性能的影响比预想中大很多,需要最先调优,同时需要兼顾实用性,不能完全关闭。优化后的性能提升约15倍。
- Docker方式和原生JDK方式,在参数相同的情况下,TPS会有较大差异,各有胜负,原因不明
- 关闭TCP粘拆包处理,可获得约30%的性能提升
- 关闭Reactor的DebugAgent后,可获得约40%的性能提升
参数调优
操作系统Ulimit
1 | # Ulimit设置 |
操作系统内核参数(修改前)
1 | cat <<EOF >> /etc/sysctl.conf |
操作系统内核参数(修改后)
1 | net.ipv4.tcp_max_tw_buckets=50000 |
TCP粘拆包脚本
1 | parser.fixed(4) |
默认情况下,可以不启用粘拆包,以获得30%以上的性能提升
日志优化
- 开启Console日志+文件日志+设备ES日志
- 并逐行调整日志级别,大部分置为INFO级,兼顾实用
- 关闭Logback的ES日志(怀疑这部分程序有问题会产生阻塞,关闭后TPS提升20倍)
应用优化
- 关闭Reactor调试模式 spring.reactor.debug-agent.enabled=false,可获得约40%的性能提升
- 关闭平台链路跟踪 trace.enabled=false
- 后续如有必要时,将单个TCP连接的接收队列长度由默认256调高到65535,以应对单一设备连续上报的场景。需要修改VertX代码。
JVM优化
1 | java -Duser.language=zh -XX:+UseG1GC -server \ |