一文让你全面认识WebSocket压测!

一、 WebSocket简介 

01 WebSocket是什么?

「WebSocket」是一种在单个TCP连接上进行全双工通信的协议。

「WebSocket」使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在「WebSocket API」中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。

TCP连接是一种可靠的、面向连接的网络通信协议。它通过三次握手建立连接,然后通过数据包的传输和确认来保证数据的可靠性和顺序性。

在建立TCP连接时,客户端首先向服务器发送一个SYN(同步)包,服务器收到后回复一个SYN+ACK(同步+确认)包,客户端再回复一个ACK(确认)包,完成了三次握手,建立了连接。在连接建立后,双方可以通过发送和接收数据包进行通信。

发送方将数据分割成小的数据包,并为每个数据包添加序列号。接收方接收到数据包后进行确认,并按照序列号将数据包重新组装成完整的数据。

解析:

Http: 类似微信发文字消息

Websocket: 类似微信视频通话

02 WebSocket压测的目的和意义

「WebSocket」压测的目的和意义是评估「WebSocket」服务的性能和稳定性。通过模拟大量并发连接和发送大量数据包,可以测试服务器在高负载情况下的响应速度、吞吐量和并发连接数等指标。

这有助于发现服务器在实际使用中可能出现的性能瓶颈和问题并进行优化和调整,以确保服务器能够处理大规模的实时通信需求。

此外,「WebSocket」压测还可以验证服务器在长时间运行下是否会出现内存泄漏或其他稳定性问题,以提高系统的可靠性。

03 常用的WebSocket压测工具和方法

首先在进行WebSocket压测时,一般需要注意以下5个方面:

  • 1. 并发连接数:模拟真实场景下可能出现的并发连接数,并观察服务器在高负载情况下是否能够正常处理请求。

  • 2. 数据包大小:根据实际需求设置合适大小的数据包,并观察服务器在处理不同大小数据包时的性能表现。

  • 3. 响应时间:记录每个请求的响应时间,并分析是否存在延迟或超时问题。

  • 4. 吞吐量:观察服务器在单位时间内处理请求数量,评估其处理能力。

  • 5. 稳定性:长时间运行测试以验证服务器是否会出现内存泄漏或其他稳定性问题。

工具对比:

图片

综合上面工具的特性,使用Jmeter测试建立长连接发送心跳的QPS,使用自己写的工具模拟建立长连接数量。

Jmeter 使用

1插件下载:

https://bitbucket.org/pjtr/jmeter-websocket-samplers/downloads/,建议下载最新版本。

2 详细使用可以参考:https://help.aliyun.com/document_detail/93627.html?spm=5176.pts_console.help.dexternal.4b6267e45z6Q4x

3 如何建立连接后一直发送心跳

  • 3.1 添加线程组

  • 3.2 线程组下添加 HTTP请求头管理器

图片

  • 3.3 线程组下添加WebSocket Open Connection

图片

  • 3.4 线程组下添加循环控制器

循环控制器:60

图片

WebSocket Ping/Pong:pong(just send pong)

图片

固定定时器:5000 ms

图片

  • 3.5 线程组下添加WebSocket Close

图片

  • 3.6 如果需要参数,增加CSV 数据文件设置

图片

再加上聚合报告和查看结果数,这样一个完整的建立「websocket」连接后,5秒发送一次心跳,持续300秒的脚本就配置好了。执行上面配置好的脚本,就可以压测出建立连接后发送心跳的QPS和响应时间了。

netty客户端(只能模拟连接数)

代码地址:https://github.com/GreatAsia/websocket-netty-tools.git下载代码后,使用编译器打开,进入对应的项目目录,mvn package就可以打包了。

1 使用netty客户端文件(带header)

命令: nohup java -jar ultrasnake-client-header.jar --host 10.10.10.1--port 8080 --file 6wc.cvs --ws ws &

--host: ip/域名

--port: 8080/443/80

--file: 文件

--ws: ws/wss

2 使用netty客户端文件(不带header)

命令:java -jar ultrasnake-client.jar --host 10.10.10.10 --port 8000 --size 60000

--host: ip/域名

--port: 8080/80

--size: 连接数

一台施压机器只能建立6w连接,如果模拟20万连接,需要4台机器。

二、影响WebSocket连接数的因素

01服务器硬件配置对连接数的影响

1.处理器性能:服务器的处理器性能决定了其在单位时间内可以处理的连接数。较高性能的处理器可以更快地处理连接请求和数据传输,从而支持更多的连接数。 

2. 内存容量:服务器的内存容量决定了其可以同时维护的连接数。每个连接都需要占用一定的内存资源,包括缓冲区、会话状态等。较大的内存容量可以支持更多的连接。

3.硬盘速度:服务器硬盘的读写速度对于处理连接请求和数据传输也有影响。较高速度的硬盘可以更快地读取和写入数据,提高服务器响应速度,从而支持更多的连接。

4.网络带宽和延迟:服务器所在网络环境的带宽限制了其可以同时处理的连接数。较高带宽可以支持更多数据传输,从而提供更多连接服务。 

延迟是指数据从发送端到接收端所需的时间。较低的延迟可以提高连接响应速度,使得服务器能够更快地处理连接请求和数据传输。

如果延迟较高,则可能会导致连接响应变慢或超时,限制了服务器能够同时处理的连接数。

5.WebSocket协议本身对连接数的限制:在计算机网络中,TCP连接是通过IP地址和端口号来唯一标识的。

而四元组则是指一个完整的TCP连接所需要的四个要素,包括源IP地址、源端口号、目标IP地址和目标端口号。 

当两台主机建立TCP连接时,它们会互相交换各自的IP地址和端口号信息,以建立一个唯一的TCP连接。

这些信息被称为四元组,用于区分不同的TCP连接。

为什么端口号只能使用65535个?

一个四元组包含源IP地址、源端口号、目的IP地址和目的端口号。其中,源端口号和目的端口号都是16位的无符号整数,范围是0到65535。

因此,一个四元组最大只能支持65535个连接。这是因为TCP/IP协议中使用16位的端口号来标识不同的应用程序或服务。每个连接都需要使用不同的端口号来区分不同的应用程序或服务。

由于端口号是16位的,所以最多可以有2^16=65536个不同的端口号可供使用。其中,0被保留为保留端口,因此实际可用的端口范围是1到65535。

三、 单台服务器支撑多少连接

01 如何优化服务器配置以提高连接数

压测机和服务端都需要调整文件句柄参数/etc/security/limits.conf

# End of file

root soft nofile 655350

root hard nofile 655350

* soft nofile 655350

* hard nofile 655350

这些参数是用于设置系统中打开文件的限制。- root soft nofile 655350:表示对于root用户,软限制(soft limit)为655350,即允许root用户最多打开655350个文件。 

- root hard nofile 655350:表示对于root用户,硬限制(hard limit)为655350,即root用户无法超过655350个文件的打开数。

 - * soft nofile 655350:表示对于所有其他用户,软限制为655350。- * hard nofile 655350:表示对于所有其他用户,硬限制为655350。 

软限制是指在不需要重新启动系统的情况下可以修改的值,而硬限制是指系统所能支持的最大值。

linux系统文件句柄数和tcp连接数的关系?

Linux系统文件句柄数和TCP连接数之间存在一定的关系。在Linux系统中,每个打开的文件(包括网络连接)都会被分配一个唯一的文件句柄。

因此,系统文件句柄数限制了同时打开的文件和网络连接的数量。TCP连接是通过套接字(socket)实现的,而套接字本质上也是一种文件。因此,TCP连接数也受到系统文件句柄数的限制。 

如果系统文件句柄数较小,则同时打开的文件和TCP连接数量也会受到限制。

当达到系统文件句柄数上限时,无法再创建新的文件或建立新的TCP连接。 

为了提高系统并发性能,可以通过增加系统文件句柄数来增加同时打开的文件和TCP连接数量。可以通过修改操作系统内核参数或者调整应用程序配置来实现。

 需要注意的是,增加系统文件句柄数可能会占用更多的内存资源,并且过高的并发连接可能导致服务器负载过大。因此,在调整系统文件句柄数时需要综合考虑服务器硬件资源和应用程序需求。

内核参数调整

/etc/sysctl.conf:

net.ipv4.ip_local_port_range = 1024 65535

net.core.somaxconn=65535

net.ipv4.tcp_max_syn_backlog = 2621440

这些参数是用于配置Linux系统的网络相关设置。

 - net.ipv4.ip_local_port_range = 1024 65535:表示本地端口范围,即指定可用于本地应用程序的端口范围。在这个例子中,可用的本地端口范围是从1024到65535。

 - net.core.somaxconn=65535:表示系统中每个监听套接字(socket)的最大连接数。在这个例子中,最大连接数被设置为65535。 

- net.ipv4.tcp_max_syn_backlog = 2621440:表示TCP协议的SYN队列的最大长度。SYN队列用于存储尚未完成三次握手的连接请求。在这个例子中,SYN队列的最大长度被设置为2621440。 

这些参数可以通过修改/etc/sysctl.conf文件来进行配置,并且需要重新加载sysctl配置才能生效(使用命令sysctl -p)

经过实测一台8c16g的阿里云服务器结果如下:

  • 1 使用demo可以连接:24w

  • 2 使用业务代码可以连接:18w(根据实际业务逻辑变动)

  • 3 阿里云服务器限制:25w

图片

一条ESTABLISH状态的连接大约消耗4K内存(空连接,不涉及任何数据发送和处理),实际测试服务端24万连接预计消耗9G内存。

图片

四、 如何设计支撑20万并发连接数架构

01 分布式架构设计思路

图片

上面这张图只支持12W连接, 瓶颈在nginx,在nginx中建立一个连接需要消耗两个连接数,每台机器最大连接数是24w,所以只能支持24/2=12w个连接。

图片

上面这张图只支持12W连接, 瓶颈在业务服务,一个nginx对应一个服务只能建立6w个连接,所以是12w连接。

图片

上面这张图支持24W连接, 一个nginx连接2个服务,每个服务能建立6w个连接,所以是12w + 12w=24w连接。

图片

上面这张图支持24W连接, 一个server 6w个连接,所以是4x6w=24w连接。

五、 推测100万连接所需配置分析

先看一下连接数限制条件:

  • 1 四元组:6w;

  • 2 nginx: 一条连接占用两个连接数;

  • 3 一台服务器8c16g最高25W连接;

  • 4 一个服务最大18W连接;

100w所需配置:

  • 1 slb支持100W

  • 2 带宽占用:入口325Mbps 出口225Mbps

图片

上面的服务器配置可以满足100w连接数,实际使用时必须留有余量,所以需要多配置几台服务器进行备份。

六、 总结与建议

01 WebSocket压测结果分析与总结

1. 服务很容易出现OOM和服务假死

OOM:内存溢出,需要长时间的压测,观察内存是否释放,比如:每秒%0.1的内存占用累加,最后OOM

服务假死:大量发送同步消息,CPU占满,导致假死,现象有:

  • 1 客户端全部断开

  • 2 服务占用CPU100%,一直不释放

  • 3 服务停止打印日志

  • 4 CLOSE_WAIT关闭很慢

2 压测过程中一定要及时记录服务器性能和服务日志和报错相关信息,避免出现漏侧。通过记录的数据可以分析出问题所在,可以对症进行优化。

3 分析压测结果,分析服务所存在的瓶颈,为后面服务扩容做好准备。做好预案,比如服务假死后,怎么重启服务来满足连接服务。还有结合客户端发送心跳时需要随机发送,避免服务重启造成同时间造成大量建立连接,出现问题。

行动吧,在路上总比一直观望的要好,未来的你肯定会感谢现在拼搏的自己!如果想学习提升找不到资料,没人答疑解惑时,请及时加入群:1150305204,里面有各种测试开发资料和技术可以一起交流哦。

最后: 下方这份完整的软件测试视频教程已经整理上传完成,需要的朋友们可以自行领取【保证100%免费】

在这里插入图片描述


软件测试面试文档
我们学习必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有字节大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值