websocket服务器测试

[TOC]

代码地址:github.com/buexplain/netsvr

  • netsvr网关进程,是websocket服务器,运行在Linux虚拟机内,启动后的初始内存:19KiB
  • business业务进程,是模拟业务逻辑的服务器端的,运行在宿主机上
  • stress压测进程,是模拟客户端的,运行在宿主机上

宿主机配置
宿主机配置
Linux虚拟机配置
Linux虚拟机配置

场景1:一万个只有心跳的连接

压测代码逻辑:

  1. 分三个阶段,每个阶段发起一部分连接,每个阶段连接建立完毕后,暂停60秒后,再进行下一个阶段,最后一个阶段不做暂停操作。
  2. 每个连接,每隔30秒,发起一次心跳,服务端会响应心跳。
  3. 所有阶段的连接建立完毕后,持续3分钟后,输出统计结果,关闭连接。

netsvr监控,该图是所有连接建立完毕,持续1分钟后的截图
websocket服务器测试
该图是压测代码的运行日志与统计结果
websocket服务器测试

场景2:一万个单播的连接

压测代码逻辑:

  1. 分三个阶段,每个阶段发起一部分连接,每个阶段连接建立完毕后,暂停60秒后,再进行下一个阶段,最后一个阶段不做暂停操作。
  2. 每个连接,每隔30秒,发起一次心跳,服务端会响应心跳。
  3. 每个连接间,每隔5秒向服务器发起一次单播(自己发给自己),消息长度是128字节,注意这个长度不是数据打包后的长度。
  4. 所有阶段的连接建立完毕后,持续3分钟后,输出统计结果,关闭连接。

netsvr监控,该图是所有连接建立完毕,持续1分钟后的截图
websocket服务器测试
该图是压测代码的运行日志与统计结果
websocket服务器测试

场景3:一万个批量单播的连接

压测代码逻辑:

  1. 分三个阶段,每个阶段发起一部分连接,每个阶段连接建立完毕后,暂停60秒后,再进行下一个阶段,最后一个阶段不做暂停操作。
  2. 每个连接,每隔30秒,发起一次心跳,服务端会响应心跳。
  3. 每个连接间,每隔5秒向服务器发起一次批量单播(自己发给自己),消息长度是128字节,注意这个长度不是数据打包后的长度。
  4. 所有阶段的连接建立完毕后,持续3分钟后,输出统计结果,关闭连接。

netsvr监控,该图是所有连接建立完毕,持续1分钟后的截图
websocket服务器测试
该图是压测代码的运行日志与统计结果
websocket服务器测试

场景4:一万个组播的连接

压测代码逻辑:

  1. 分三个阶段,每个阶段发起一部分连接,每个阶段连接建立完毕后,暂停60秒后,再进行下一个阶段,最后一个阶段不做暂停操作。
  2. 每个连接,每隔30秒,发起一次心跳,服务端会响应心跳。
  3. 每个连接间,每隔5秒向服务器发起一次组播(一次性给多个人发消息),目标连接数是15个,消息长度是128字节,注意这个长度不是数据打包后的长度。
  4. 所有阶段的连接建立完毕后,持续3分钟后,输出统计结果,关闭连接。

netsvr监控,该图是所有连接建立完毕,持续1分钟后的截图
websocket服务器测试
该图是压测代码的运行日志与统计结果
websocket服务器测试

场景5:一千个订阅主题、取消订阅主题、按主题发布数据的连接

压测代码逻辑:

  1. 分三个阶段,每个阶段发起一部分连接,每个阶段连接建立完毕后,暂停60秒后,再进行下一个阶段,最后一个阶段不做暂停操作。
  2. 每个连接,每隔30秒,发起一次心跳,服务端会响应心跳。
  3. 每个连接,每隔5秒向服务器发起一次订阅100个主题、取消订阅50个主题、基于1个主题发布128字节的数据。
  4. 所有阶段的连接建立完毕后,持续3分钟后,输出统计结果,关闭连接。

netsvr监控,该图是所有连接建立完毕,持续1分钟后的截图
websocket服务器测试
该图是压测代码的运行日志与统计结果
websocket服务器测试
当所有连接建立完毕后,netsvr中的主题数量是1225个主题,平均每个主题被303个连接订阅。

场景6:一个连接广播给一万个连接

压测代码逻辑:

  1. 分三个阶段,每个阶段发起一部分连接,每个阶段连接建立完毕后,暂停60秒后,再进行下一个阶段,最后一个阶段不做暂停操作。
  2. 每个连接,每隔30秒,发起一次心跳,服务端会响应心跳。
  3. 1个连接,每隔5秒向服务器发起一次广播,消息长度是128字节,注意这个长度不是数据打包后的长度。
  4. 所有阶段的连接建立完毕后,持续3分钟后,输出统计结果,关闭连接。

netsvr监控,该图是所有连接建立完毕,持续1分钟后的截图
websocket服务器测试
该图是压测代码的运行日志与统计结果
websocket服务器测试

场景7:一万个登录、登出操作的连接

压测代码逻辑:

  1. 分三个阶段,每个阶段发起一部分连接,每个阶段连接建立完毕后,暂停60秒后,再进行下一个阶段,最后一个阶段不做暂停操作。
  2. 每个连接,每隔30秒,发起一次心跳,服务端会响应心跳。
  3. 每个连接,每隔5秒向服务器发起一次登录、登出操作,登录操作是:往网关存储新的uniqId、1kb的session数据、订阅10个主题,登出操作是:移除连接在网关中的uniqId、session、主题。
  4. 所有阶段的连接建立完毕后,持续3分钟后,输出统计结果,关闭连接。

netsvr监控,该图是所有连接建立完毕,持续1分钟后的截图
websocket服务器测试
该图是压测代码的运行日志与统计结果
websocket服务器测试
当所有连接建立完毕后,netsvr中的主题数量是1226个主题,平均每个主题被38个连接订阅。

场景8:综合以上场景做一个全套测试

压测逻辑太冗长了,不再描述,只给压测配置:

# 日志级别 debug、info、warn、error
LogLevel = "debug"
# customer服务的websocket连接地址
CustomerWsAddress = "ws://192.168.241.2:6060/netsvr"
# worker服务的监听地址
WorkerListenAddress = "192.168.241.2:6061"
# 该值与netsvr.toml的配置保持一致
ConnOpenCustomUniqIdKey = ""
# 表示消息被哪个workerId的业务进程处理
WorkerId = 1
# 每个连接间隔多少秒进行心跳
Heartbeat = 30
# 是否并发初始化每个压测模块
Concurrent = true
# 当所有连接建立完毕后的持续时间,单位秒
Suspend = 180
# 沉默的连接
[Silent]
Enable = true
Step = [
    #每个阶段初始化的连接数、每秒初始化的连接数、本阶段初始化完毕后的暂停秒数
    { ConnNum = 600, ConnectNum = 100, Suspend = 60 },
    { ConnNum = 600, ConnectNum = 100, Suspend = 60 },
    { ConnNum = 800, ConnectNum = 100, Suspend = 60 },
]

# 疯狂登录登出的连接
[Sign]
Enable = true
# 每个连接间隔多少秒进行一次登录、登出操作
MessageInterval = 5
Step = [
    { ConnNum = 50, ConnectNum = 100, Suspend = 60 },
    { ConnNum = 100, ConnectNum = 100, Suspend = 60 },
    { ConnNum = 200, ConnectNum = 100, Suspend = 60 },
]

# 疯狂单播的连接
[SingleCast]
Enable = true
# 单播时发送的消息大小
MessageLen = 128
# 每个连接间隔多少秒进行一次单播操作
MessageInterval = 5
Step = [
    { ConnNum = 50, ConnectNum = 100, Suspend = 60 },
    { ConnNum = 100, ConnectNum = 100, Suspend = 60 },
    { ConnNum = 200, ConnectNum = 100, Suspend = 60 },
]

# 疯狂批量单播的连接
[SingleCastBulk]
Enable = true
MessageLen = 256
# 一组包含的uniqId数量
UniqIdNum = 15
# 每个连接间隔多少秒进行一次批量单播操作
MessageInterval = 5
Step = [
    { ConnNum = 50, ConnectNum = 100, Suspend = 60 },
    { ConnNum = 100, ConnectNum = 100, Suspend = 60 },
    { ConnNum = 200, ConnectNum = 100, Suspend = 60 },
]

# 疯狂组播的连接
[Multicast]
Enable = true
MessageLen = 256
# 一组包含的uniqId数量
UniqIdNum = 15
# 每个连接间隔多少秒进行一次组播操作
MessageInterval = 5
Step = [
    { ConnNum = 50, ConnectNum = 100, Suspend = 60 },
    { ConnNum = 100, ConnectNum = 100, Suspend = 60 },
    { ConnNum = 200, ConnectNum = 100, Suspend = 60 },
]

# 疯狂订阅、取消订阅、发布,下面这套配置下,主题总数是1225个主题,平均每个主题被80个连接订阅,当然因为机器性能、网络等原因,实际订阅数可能不一样
[Topic]
Enable = true
# 每个连接的备选主题数量,该值是随机产生的,该值越大,则一个主题会被多个连接订阅的概率越小
AlternateTopicNum = 600
# 主题字符串的长度,41413720种排列 342840种排列,21260种排列,该值越大,则一个主题会被多个连接订阅的概率越小
AlternateTopicLen = 2
# 连接建立的步骤
Step = [
    { ConnNum = 50, ConnectNum = 100, Suspend = 60 },
    { ConnNum = 100, ConnectNum = 100, Suspend = 60 },
    { ConnNum = 200, ConnectNum = 100, Suspend = 60 },
]
[Topic.Subscribe]
# 运行模式 0 延长多少秒执行,1 间隔多少秒执行一次
Mode = 1
# 延长或间隔的秒数
ModeSecond = 5
# 每次订阅的主题数量,该值是轮询AlternateTopicNum得到的,第零个主题一定会被订阅
TopicNum = 100
[Topic.Unsubscribe]
# 运行模式 0 延长多少秒执行,1 间隔多少秒执行一次
Mode = 1
# 延长或间隔的秒数
ModeSecond = 5
# 每次取消订阅的主题数量,该值是轮询AlternateTopicNum得到的,但是不会取消连接订阅的第零个主题
TopicNum = 50
[Topic.Publish]
# 发布数据的大小
MessageLen = 512
# 运行模式 0 延长多少秒执行,1 间隔多少秒执行一次
Mode = 1
# 延长或间隔的秒数
ModeSecond = 5
# 每次发布消息的主题数量,该值是轮询AlternateTopicNum得到的,但是连接订阅的第零个主题是一定会被用于消息发布的
TopicNum = 1

# 疯狂广播的连接
[Broadcast]
Enable = true
MessageLen = 1024
# 每个连接间隔多少秒进行一次广播操作
MessageInterval = 5
Step = [
    { ConnNum = 2, ConnectNum = 10, Suspend = 60 },
    { ConnNum = 4, ConnectNum = 10, Suspend = 60 },
    { ConnNum = 6, ConnectNum = 10, Suspend = 60 },
]

netsvr监控,该图是所有连接建立完毕,持续1分钟后的截图
websocket服务器测试
该图是压测代码的运行日志与统计结果
websocket服务器测试

总结

在以上场景下,github.com/buexplain/netsvr 的代码运行稳定。

本作品采用《CC 协议》,转载必须注明作者和本文链接
梦想星辰大海
讨论数量: 20

websocket 怎么压测

10个月前 评论
梦想星辰大海 (楼主) 10个月前

可以在生产环境使用该项目吗?

8个月前 评论
梦想星辰大海 (楼主) 8个月前
kureCC (作者) 8个月前
梦想星辰大海 (楼主) 8个月前
kureCC (作者) 8个月前
梦想星辰大海 (楼主) 8个月前

我比较好奇,怎么快速给一万客户端发消息

8个月前 评论
梦想星辰大海 (楼主) 8个月前
kureCC 8个月前
梦想星辰大海 (楼主) 8个月前
kureCC 8个月前
梦想星辰大海 (楼主) 8个月前
kureCC 8个月前
lxzan 7个月前

我们生产有个场景,客户会导入excel我们作为任务来处理,但是处理的时间会有一点长,目前是通过轮询来查看任务,请问可以用你的项目吗?我的想法是完成任务以后发个消息后续通过websocket来告诉前端。

8个月前 评论
梦想星辰大海 (楼主) 8个月前

大佬 请教下有什么比较简单的方式吗 是可以引入现成的包吗

8个月前 评论
梦想星辰大海 (楼主) 8个月前

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!