百万并发websocket 压测操作手册

本文分享了使用Netty和Spring实现WebSocket服务,并挑战百万级并发连接的实际经验。从初试Node.js遇到瓶颈,转战Linux环境,再到利用虚拟IP与高配服务器提升并发数,最终采用Java+Netty方案,结合多核处理能力,在8c16g服务器上实现了6万WebSocket链接的快速搭建。深入探讨了如何指定Netty连接TCP时使用的源地址,及不同技术栈在高并发场景下的表现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

使用netty+spring 写好websocket服务之后,想要看看实际的运行效果,和并发数。网上确实websocket百万并发性能测试,但是没有给出具体的websocket-client 链接方式。这个就很尴尬了,起初我们使用nodejs ws 包,做连接发现在windows上面单台电脑发起的总计链接数量死活超不过2 w。在1.6w左右。这个和系统使用的端口的数有关系。通过netstat查看发现45000后的端口全部被占用了,之前的有没有使用的也不会使用。然后我们把nodejs的脚本放到了linux的测试环境上面。然而~并发数到2.6w之后就无法开启了。如果要到百万并发的话,就得有40台。我的天这么多,怎么可能呢?好在性能测试的文章里面给了一台思路。直接使用虚拟ip。我们在腾讯云上买了10台1c1g的肉鸡用来发起websocket请求。如果你也有这样的想法,还是算了吧。直接上8c16g 两台。1c1g开websocket2w的在半路就被系统直接kill了。加一起也没有两台8c16g不加虚拟ip开到12w多。腾讯云上在内网环境下,选择弹性网卡,点进去详情可以新增内网辅助IP,给每台电脑添加10个辅助IP。加上倒是挺简单的,加好之后怎么用呢?这又是个问题。然后各种百度虚拟IP,IP别名,辅助IP。linux上一个物理网卡是允许多个IP的。对于不同的IP网段,会像有一个链接一样一个一个的连接起来,文章找到了后面我在补上吧。然后每个网段会有一个primary IP,每个primary IP下还会链表一样连着该网段的其他secondly IP。在发起网络请求时,如果不指定源IP系统会默认使用primary IP作为源IP使用。所以我们需要在发起请求的时候指定源IP地址。
由于nodejs性能太低了,或者我们的编写的代码性能太低了,每次链接的耗时很长,所以改用了JAVA+netty的方式做客户端链接加上parallelStream 多核能力的加持在8c16g的肉鸡上启动6w的websocket链接只需要10秒左右。具体如何指定netty链接TCP的时候使用的源地址呢?

 DefaultAsyncHttpClientConfig.Builder builder = new DefaultAsyncHttpClientConfig.Builder();
        DefaultAsyncHttpClientConfig build = builder.addChannelOption(ChannelOption.SO_REUSEADDR, true).setWsAdditionalChannelInitializer(ws -> {
            try {
                InetAddress byName = InetAddress.getByName(args[3]);
                InetSocketAddress inetSocketAddress = new InetSocketAddress(byName, pro.incrementAndGet());
                ws.bind(inetSocketAddress);
            } catch (UnknownHostException e) {
                e.printStackTrace();
            }
        }).build();

SO_REUSEADDR提供如下四个功能:

  1. 允许启动一个监听服务器并捆绑其众所周知端口,即使以前建立的将此端口用做他们的本地端口的连接仍存在。这通常是重启监听服务器时出现,若不设置此选项,则bind时将出错
  2. 允许在同一端口上启动同一服务器的多个实例,只要每个实例捆绑一个不同的本地IP地址即可。对于TCP,我们根本不可能启动捆绑相同IP地址和相同端口号的多个服务器。
  3. 允许单个进程捆绑同一端口到多个套接口上,只要每个捆绑指定不同的本地IP地址即可。这一般不用于TCP服务器。
  4. SO_REUSEADDR允许完全重复的捆绑:
    当一个IP地址和端口绑定到某个套接口上时,还允许此IP地址和端口捆绑到另一个套接口上。一般来说,这个特性仅在支持多播的系统上才有,而且只对UDP套接口而言(TCP不支持多播)。

通过添加 setWsAdditionalChannelInitializer 来控制ws的初始化操作,使用 ws.bind(inetSocketAddress)来绑定到具体的虚拟IP以及端口上,由于这个时候不是系统自动分配,所以直接让端口从3000开始列加 也就是pro.incrementAndGet() 该方法多线程的情况下可以保证执行成功。也就是端口不一致。接着我们就收集了同时的几个websocket服务demo项目在16c32g上运行测试。2个netty 1个go 语言。go语言在表现上为内存使用过大,还没有到百万链接,内存先撑爆了。netty的表现为1.5G 6w链接同时使用list吃用websocketsession。go 为2G 6w链接 使用list持有websocketsession。
在这里插入图片描述
以上的图片来源与netty websocket 百万websocket链接保持的截图。

### 如何对 WebSocket 进行试 #### 使用 JMeter 对 WebSocket 进行试 对于 WebSocket试,JMeter 是一种广泛使用的工具。通过特定插件的支持,JMeter 可以有效地模拟个客户端连接到 WebSocket 服务器并执行各种操作。 为了准备这样的试,在配置阶段需安装适用于 JMeter 的 WebSocket 插件[^3]。一旦完成设置,创建一个新的试计划来定义负载场景变得简单起来。这通常涉及指定目标 WebSocket URL 和预期的行为模式——比如发送的消息内容以及接收响应后的处理逻辑。 在实际实施过程中,可以从浏览器开发者工具中找到 WebSocket IP 地址和其他必要参数,这对于构建准确的试脚本至关重要[^2]。具体来说,Google 浏览器提供了便捷的方式让用户查看这些细节;只需右键点击网页并选择“检查”,就能进入网络活动监控界面获取所需信息。 当一切就绪后,利用 JMeter 提供的强大功能定制化地调整并发用户数、循环次数等变量,从而评估不同条件下的系统表现情况。此外,还可以记录下每次运行的结果用于后续分析比较,帮助识别潜在瓶颈所在之处。 ```bash # 安装 JMeter WebSocket 插件命令示例 (假设使用 Linux 系统) wget https://github.com/ptrd/jmeter-websocket-samplers/releases/download/v1.0/JMeterWebSocketSamplers-v1.0.zip unzip JMeterWebSocketSamplers-v1.0.zip -d /path/to/apache-jmeter/lib/ext/ ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值