websocket多线程问题
开发框架
- springMVC
- tomcat8
问题描述
后端建立websocket 前端连接上来,后台会主动推送agent脚本执行信息,由于采用netty框架,保证并发性,执行的结果是多线程处理的,通过websocket返回前端居然报错了,很是费解。症状见下图。


排查解决过程
从图中可以看出,远端处于【TEXT_PARTIAL_WRITING】状态,就这这个关键字google(不得不说就英文搜索而言,google强太多),
最后发现,tomcat的websocket没有相关的多线程处理,有人在apache上提bug,可以看一下开发者给的回复:
tomcat8 websocker bug
I have some sympathy with this view. Given that the Javadoc for RemoteEndpoint.Basic explicitly states that
concurrent attempts to send messages are not allowed and the Javadoc for RemoteEndpoint.Async doesn't, you'd be
forgiven for thinking that meant that RemoteEndpoint.Async permitted concurrent attempts to send messages.
Unfortunately, the (not very well documented) intention of the WebSocket EG was not to allow concurrent attempts to send messages. [1]
I did take a quick look at adding an option to relax (i.e. ignoring) this but the change required to do this with the current Tomcat code would be far from trivial.
I'm marking this as INVALID since the intention of the EG was to not allow this but WONTFIX is almost as appropriate if this is viewed as an enhancement request.
As an aside, one reason not to implement this particular enhancement is that apps that depended on it would not be portable between containers.
提bug的人提出了一个很常见的需求:
一个简单的聊天应用程序与3个用户聊天将导致并发调用Async.sendText()当A和B都发送一个必须传递到C的消息,所以用例是很常见的。
应用程序担心同步或排队并发调用Async.sendText()会对执行并发写入的应用程序造成巨大的负担,我相信这不是JSR 356的意图(尽管规范并没有说明并发保证) 。
tomcat 开发者大致认为
javaDoc,RemoteEndpoint.Basic明确指出不允许并发发送消息,但是RemoteEndpoint.Async没有,并且websocket eg 的意图是不允许并发,最终结论将此bug定位为无效bug
解决方法
看下面的评论也是很有意思,哈哈,大部分人认为容器应该为应用程序开发者提供便利,提供容器内部的缓冲,,而不是程序开发者自己管理websocket Session缓冲区。有一个方法是利用同步来降低这种问题的出现频率,与此同时,Tyrus 1.5是安全的,貌似只有tomcat存在这个问题。
随之而来的新的问题
采用同步操作之后,由于agent会有很多中间结果,当第一条消息到来把锁抢占之后,后面的结果已经到来,当锁释放之后,其他线程抢占锁,尼玛,原先有时间顺序的结果变得混乱无序. 难道真的要自己实现一套缓冲队列吗。左思右想,最终决定还是有公平锁好了
公平锁是个好东西,自己内部实现了一套等待队列,虽然效率有点低,但是对业务来说可以满足需求
private static ReentrantLock lock = new ReentrantLock(true);

websocket多线程问题的更多相关文章
- spring boot集成Websocket
websocket实现后台像前端主动推送消息的模式,可以减去前端的请求获取数据的模式.而后台主动推送消息一般都是要求消息回馈比较及时,同时减少前端ajax轮询请求,减少资源开销. spring boo ...
- H5一二事
先回顾一下WEB技术的几个阶段 Web 1.0 内容为主,主要流行HTML和CSS Web 2.0 动态网页,流行AJAX/JavaScript/DOM H5 时代,WEB开发回归富客户端 那么H5肯 ...
- 文档通信(跨域-不跨域)、时时通信(websocket)、离线存储(applicationCache)、开启多线程(web worker)
一.文档间的通信 postMessage对象 //不跨域 1.iframe:obj.contentWindow [iframe中的window对象] iframe拿到父级页面的window: pare ...
- Web Worker javascript多线程编程(一)
什么是Web Worker? web worker 是运行在后台的 JavaScript,不占用浏览器自身线程,独立于其他脚本,可以提高应用的总体性能,并且提升用户体验. 一般来说Javascript ...
- Netty 实现 WebSocket 聊天功能
上一次我们用Netty快速实现了一个 Java 聊天程序(见http://www.waylau.com/netty-chat/).现在,我们要做下修改,加入 WebSocket 的支持,使它可以在浏览 ...
- Java用webSocket实现tomcat的日志实时输出到web页面
原文:http://blog.csdn.net/smile326/article/details/52218264 1.场景需求 后台攻城狮和前端攻城狮一起开发时,经常受到前端攻城狮的骚扰,动不动就来 ...
- 转:鏖战双十一-阿里直播平台面临的技术挑战(webSocket, 敏感词过滤等很不错)
转自:http://www.infoq.com/cn/articles/alibaba-broadcast-platform-technology-challenges 鏖战双十一-阿里直播平台面临的 ...
- html5---webworker多线程
javascript本身就是一个单线程的语言,一开始它的出现是为了简单的网页设计,设计者并没有考虑到多线程的问题,要知道,线程的开销是非常昂贵的.但是随着web开发的潮流化,javascript不是仅 ...
- 根据Unix哲学来编写你的HTML5 Websocket服务器来实现全双工通信
websocketd代表WebSocket的守护进程 websocketd处理的是浏览器和服务器之间的WebSocket连接,它会启动你所指定的服务器端应用来对WebSockets进行处理,然后在浏览 ...
随机推荐
- python 小程序—三级菜单—循环和字典练习
程序中利用多级字典来存储三级菜单, 通过一系列while循环和for循环,实现了三级菜单的查询,选择,退回上级菜单,退出程序几个功能. 缺点:程序语句过于重复,效率低. #-*-coding:utf- ...
- Linux使用Jexus托管Asp.Net Core应用程序
第一步 安装.Net Core环境 安装 dotnet 环境参见官方网站 https://www.microsoft.com/net/core. 选择对应的系统版本进行安装.安装完成过后 输入命令查看 ...
- 最新的chart 聊天功能( webpack2 + react + router + redux + scss + nodejs + express + mysql + es6/7)
请表明转载链接: 我是一个喜欢捣腾的人,没事总喜欢学点新东西,可能现在用不到,但是不保证下一刻用不到. 我一直从事的是依赖angular.js 的web开发,但是我怎么能一直用它呢?看看最近火的一塌糊 ...
- 关于Dubbo一个接口多个实现的解决方案
如题,其实这个问题在官方文档中已经说明了.我直接贴图就好了 更多学习请参考:minglisoft.cn/technology
- 瀑布流原生ajax,demo
最近听朋友们说起瀑布流挺多的,自己就去研究下了,一个简单的原生demo,分享给大家... 简单分为三个文档,有详细的注释 img:ajax.php:demo.php 其中img中放入图片 1.jpg: ...
- html5,js插件实现手机端实现头像剪切上传
思路:先打开相册,选取图片,在剪切图片,转化为base64格式,然后上传到七牛存储,返回url,再传给后端,整个流程就是这样.用的是angular框架,图像插件用到imagecropper.js,废话 ...
- Python标准库--Scope
作者:zhbzz2007 出处:http://www.cnblogs.com/zhbzz2007 欢迎转载,也请保留这段声明.谢谢! 1 模块简介 你一定在很多计算机科学课程上听说过作用域.它很重要, ...
- MindNode for mac 思维导图
绘制思维导图 下载地址 链接: https://pan.baidu.com/s/1o7NBzmU 密码: mu3f
- 关于vue生命周期中的同步异步的理解
在vue官网中介绍生命周期的图如下: 主要测试代码如下: 主要是测试前四个生命周期beforeCreate,created,beforeMount,mounted,里面同步和异步的执行顺序,其它的类似 ...
- PHP科普
1.PHP是什么意思? 超文本预处理器(Hypertext Preprocessor) 2.PHP是干什么用的? PHP是一种通用开源脚本语言.语法吸收了C语言.Java和Perl(实际抽取与汇报语言 ...