为什么你的websocket只能建立256个连接?

简介: WebSocket想必大家都不陌生,当我们的程序需要实时高效的获取后端的返回结果时,除了早期大家用到的前端轮循的机制之外,当前比较简单好用的莫过于WebSocket了。

WebSocket想必大家都不陌生,当我们的程序需要实时高效的获取后端的返回结果时,除了早期大家用到的前端轮循的机制之外,当前比较简单好用的莫过于WebSocket了。


当然,这篇文章不是WebSocket的科普文,按照惯例:强哥出品,必属精品的原则(哈哈,自吹一波)。我们就不在这里介绍WebSocket是什么以及如何在Springboot上使用了,大家有兴趣的可以自行百度。


当我们在后端项目中加入WebSocket之后,如何测试是否配置成功呢?无疑编写一个前端html5的demo页面,试着建立WebSocket连接并由后端主动推送消息查看前端是否收到是最简单的验证方式了。


截取部分后端代码:


@OnOpenpublic void onOpen(Session session,@PathParam("winNum") String fromWinNum) throws IOException {    this.session = session;    if(StringUtils.isEmpty(fromWinNum)){        log.error("请输入窗口号!!!!!!!!!!!!!!!!");        return;    }else{        try {            if(websocketList.get(fromWinNum) == null){                this.winNum = fromWinNum;                websocketList.put(fromWinNum,this);                addOnlineCount();           //在线数加1                log.info("有新窗口开始监听:{},当前窗口数为{}",fromWinNum,getOnlineCount());                sendMessage("一条来自后端的消息");            }else{                session.getBasicRemote().sendText("已有相同窗口,请重新输入不同窗口号");                CloseReason closeReason = new CloseReason(CloseReason.CloseCodes.NORMAL_CLOSURE,"相同窗口");                session.close(closeReason);            }        }catch (IOException e){            e.printStackTrace();        }    }    if(session.isOpen()){        log.info("connect success");    }}


下面是一个简单的前端脚本:


<!DOCTYPE HTML><html>   <head>   <meta charset="utf-8">      <script type="text/javascript">         var success = 0;         function WebSocketTest(i){           if ("WebSocket" in window){                  var x = 100;//上限            var y = 0; //下限             // 打开一个 web socket            var ws = new WebSocket("ws://localhost:8080/websocket/" + i);            ws.onopen = function(){              // Web Socket 已连接上,使用 send() 方法发送数据              ws.send("客户端来了");              success++;              console.log("成功连接个数:"+success);             };             ws.onmessage = function (evt) {                var received_msg = evt.data;             };            }else{               // 浏览器不支持 WebSocket               alert("您的浏览器不支持 WebSocket!");            }         }         WebSocketTest(1);</script>     </head>   <body>   </body></html>


可以看到,我们在js代码中,调用WebSocketTest()方法创建了前端Html5的WebSocket客户端并连接到服务器端。我们打开Chrome浏览器的开发者工具查看:


0.jpg


确实成功创建了WebSocket连接,同时收到了来自后端推送的消息。由此可见,我们的项目中引入WebSocket其实还是相对比较简单的,同时因为其能够在前端主动收到来自后端推送的消息,实时性上也更优于前端轮询的机制。


当我们完成了上面的内容,想必许多人就急急忙忙的开始在WebSocket服务中加入自己的业务逻辑了。强哥当初也是这样,可是代码敲着敲着心里就暗暗发虚。


不知道大家有没有思考过一个问题:WebSocket是长连接,当用户量上来后,对我们服务端的压力不是就会比传统的Http无状态连接的压力大吗?要是因为引入了WebSocket后,用户量一上来就导致系统无法访问那可不行,那不是还不如原来的轮询了吗?


没错,如果能够在项目中引入新功能时,我们能够多想想,我相信你已经是一个较负责的开发人员了。尽量让问题发生在开发甚至预研阶段,而不是在项目真正的部署上线后往往是比较的,上线后遇到问题,只会让我们焦头烂额并且备受打击。


既然担心引入WebSocket会对性能造成影响,那最直接方式无疑就是进行压测看看实际效果了。那么要怎么压测呢?哈哈,我们不是已经有了前端连接WebSocket的代码了吗,我们进行改造一下:


<!DOCTYPE HTML><html>   <head>   <meta charset="utf-8">      <script type="text/javascript">         var success = 0;         function WebSocketTest(i){            if ("WebSocket" in window)            {              var x = 100;//上限              var y = 0; //下限               // 打开一个 web socket               var ws = new WebSocket("ws://localhost:8080/websocket/" + i);               ws.onopen = function(){                  // Web Socket 已连接上,使用 send() 方法发送数据                  ws.send("客户端来了");                  success++;                  console.log("成功连接个数:"+success);               };               ws.onmessage = function (evt) {                   var received_msg = evt.data;               };                        }            else            {               // 浏览器不支持 WebSocket               alert("您的浏览器不支持 WebSocket!");            }         }         for(let i=0; i<50; i++){          WebSocketTest(i)         }</script>   </head>   <body>   </body></html>


没错,我们将WebSocketTest()方法加入到一个for循环里面,先循环50次练练手。前后端输出如下:


1.jpg


可见没有问题,加大压力150再试试:


2.jpg


同样没有问题,那就翻个倍300,嘿嘿,真是越来越自信:


3.jpg


纳尼!!!怎么只有255个,有45个失败了:


4.jpg


这尼玛,不到300个就翻车了,那还搞什么,难不成引入WebSocket后,我的项目只能不到300人访问,那还不如轮训呢。不!我不信,再来几次:280次、310次、400次。结果居然都和上面一样,成功建立256个连接之后,其他的就都失败了。


256这么诡异的数字,里面一定隐含着惊天的秘密,第一个想法就是:难不成是后端限制了websocket的连接个数?


结果一番搜索,在配置文件中找到了如下配置:

server.tomcat.max-connections=10000


最大连接数为10000???我压测的结果是256。10000???256???这差的也太多了吧!!


难道是没有生效,把10000改成10试试,前端还是一下请求300次看看:


5.jpg


确实连上10个之后,其他的就都失败了,由此可见,这个配置还是生效的。那到底是因为什么?


连接到了256个就失败了,后端配置最大连接数又是生效的且远大于256,那么这个诡异的256究竟是为什么呢?后端配置是对的……啊!前端是不是有什么问题?难道浏览器限制了WebSocket的连接数?赶紧百度一下:


6.jpg


确认过眼神,就是这个答案了,Chrome浏览器限制WebSocket的最大连接数就是256。可能在试验中存在一点点偏差,可是是这个答案无疑了。既然是因为浏览器的限制,那我们在搞个别的浏览器(这里用360浏览器)一起试试,后端连接改回10000,前端代码还是300,当然因为后端代码有限制map的key不能重复,所以换浏览器时,for循环代码需要改成从300开始,结果如下:


7.jpg


成功了!!后端接收了255+256=511个请求,可见后端还是能够顶得住压力的。由此,我们便弄清了为什么在测试的时候,WebSocket最多只能连接256个连接的问题:原来各个浏览器有对WebSocket的连接数进行了限制。


看到这里你可能会觉得真是一顿操作猛如虎,结果竟然是因为浏览器的问题。这不是很简单吗?可是,当你真正的遇到问题的时候,其实,解决问题的过程才是比较关键的。


既然解决了这个问题,可是接下来是不是就一帆风顺了呢?强哥又想再多问几个问题:


  • 后端既然可以接受10000个连接,可是,是不是每一个请求过来,都需要一个线程来处理呢?
  • 我们的后端代码中,session作为成员变量,难道是每个请求都有独自的类处理吗,Springboot不是默认单例吗?
  • 前后端WebSoket有没有可能出现断连的问题,要如何解决呢?


这些问题,强哥在之后的推文中将会继续展开讲解,好了,今天的篇幅有点太长了,就到这里吧。


对了,今天的源码稍后也会发布出来,公众号后台留言:websocket可以获取到相应源码

相关文章
|
6月前
|
网络协议 数据安全/隐私保护
百度搜索:蓝易云【WebSocket:从建立连接到关闭的完整流程】
这是WebSocket的基本流程,它提供了一种实时、双向的通信方式,适用于需要实时数据传输的应用场景,如聊天应用、实时游戏等。
200 2
|
应用服务中间件 网络安全 nginx
Nginx配置WebSocket 【支持wss与ws连接】
Nginx配置WebSocket 【支持wss与ws连接】
4877 0
|
1月前
uni-app 62websocket连接权限验证和强制下线
uni-app 62websocket连接权限验证和强制下线
18 3
|
3月前
ModelScope-FunASR的WebSocket连接中断后,服务端不会自动关闭连接
ModelScope-FunASR的WebSocket连接中断后,服务端不会自动关闭连接【1月更文挑战第11天】【1月更文挑战第55篇】
56 2
|
7月前
|
应用服务中间件 nginx
通过nginx访问连接websocket 错误 failed: Error during WebSocket handshake: Unexpected response code: 400
通过nginx访问连接websocket 错误 failed: Error during WebSocket handshake: Unexpected response code: 400
197 0
|
9月前
|
移动开发 缓存 安全
连接世界的纽带:掌握Linux网络设计中的WebSocket服务器
本文探索了在Linux环境下实现WebSocket服务器的网络设计,将WebSocket服务器作为连接世界的纽带,为读者介绍了如何掌握Linux网络设计中的关键技术。文章从实现WebSocket协议到优化服务器性能和稳定性等方面进行了深入讲解。通过学习本文,读者将能够全面了解WebSocket服务器的原理和工作机制,并获得构建高效、可靠的Linux WebSocket服务器的实用技巧和最佳实践。无论是初学者还是有经验的开发人员,都能从本文中获得宝贵的知识和启发,进一步提升在Linux网络设计中的能力。让我们一同打造连接世界的纽带,掌握Linux网络设计中WebSocket服务器的精髓。
122 0
连接世界的纽带:掌握Linux网络设计中的WebSocket服务器
|
9月前
|
IDE 物联网 开发工具
ESP32连接云服务器【WebSocket】
ESP32 芯片基于 ARM Cortex-M 内核,具有 32 位地址空间,支持 Wi-Fi、蓝牙和其他无线连接,以及多种外设接口,如 GPIO、定时器、PWM、串口等。🚂到这里,你可以到文件夹中的bin目录中,可以找到已经存在了activate文件。🎈接着,在宝塔面板的软件商店中导入➡️➡️Python项目管理器⬅️⬅️。🎈首先是本次需要挂在服务器上的脚本代码➡️Server.py⬇️。👨‍💻因此,有关云服务器和宝塔面板的初始配置,这里将直接跳过👋。🗽其中项目路径等内容,可以参照下图填写⬇️。
ESP32连接云服务器【WebSocket】
|
12月前
|
Web App开发 移动开发 前端开发
WebSocket 是什么原理?为什么可以实现持久连接?
额。。最高票答案没答到点子上,最后怎么跑到Nodejs上去了。。Websocket只是协议而已。。 我一个个来回答吧
91 0
|
自然语言处理 Java
WebSocket在建立连接时通过@PathParam获取页面传值
WebSocket在建立连接时通过@PathParam获取页面传值
471 0
|
网络协议 前端开发 安全
websocket和http的瓜葛以及websocket协议实现
websocket和http的瓜葛以及websocket协议实现
websocket和http的瓜葛以及websocket协议实现