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进行处理,然后在浏览 ...
随机推荐
- IOS安装CocoaPods详情过程
一.简介 什么是CocoaPods CocoaPods是OS X和iOS下的一个第三类库管理工具,通过CocoaPods工具我们可以为项目添加被称为“Pods”的依赖库(这些类库必须是CocoaPod ...
- vim - manual -个人笔记
##vim配置 ###normal > 输入命令:w 写入保存 > > 粘贴 :p(向下粘贴) P(大写向上粘贴) > > 复制 :yy 复制一行 > > 删 ...
- 使用SpringBoot快速构建应用程序
1.Spring MVC和Spring Boot自带的web构建方式有所区别.Spring提供了spring-boot-starter-web自动配置模块. 2. 添加如下依赖 <depende ...
- VS2013各版本激活密钥
Visual Studio Ultimate 2013 KEY(密钥):BWG7X-J98B3-W34RT-33B3R-JVYW9 Visual Studio Premium 2013 KEY(密钥) ...
- 浏览器兼容性--new Date
ie浏览器下new Date("2013/04")与new Date("2016-04")会报错: //将201601格式的字符串转为Date对象,月份从0开始 ...
- EntityFramework6.X之DataAnnotations
DataAnnotations 在web开发中不仅在客户端需要执行验证逻辑,会对会对用户向表单中输入的数据给出一个即时反馈:且在服务器端也需验证逻辑,因为来自网络的信息都是不能信任的.在MVC中通常是 ...
- 开涛spring3(9.1) - Spring的事务 之 9.1 数据库事务概述
9.1 数据库事务概述 事务首先是一系列操作组成的工作单元,该工作单元内的操作是不可分割的,即要么所有操作都做,要么所有操作都不做,这就是事务. 事务必需满足ACID(原子性.一致性.隔离性和持久性 ...
- OpenStack云平台的网络模式及其工作机制
网络,是OpenStack的部署中最容易出问题的,也是其结构中难以理清的部分.经常收到关于OneStack部署网络方面问题和OpenStack网络结构问题的邮件.下面根据自己的理解,谈一谈OpenSt ...
- 深入理解CSS3 Flexbox
一.前言 Flexbox 是一个 CSS3 的盒子模型 ( box model ),顾名思义它就是一个灵活的盒子 ( Flexible Box ),为什麽最近这个属性才红起来呢?最主要也是因为 CSS ...
- laravel中的多对多关系详解
数据表之间是纵横交叉.相互关联的,laravel的一对一,一对多比较好理解,官网介绍滴很详细了,在此我就不赘述啦,重点我记下多对多的关系 一种常见的关联关系是多对多,即表A的某条记录通过中间表C与表B ...