开发框架

  • 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多线程问题的更多相关文章

  1. spring boot集成Websocket

    websocket实现后台像前端主动推送消息的模式,可以减去前端的请求获取数据的模式.而后台主动推送消息一般都是要求消息回馈比较及时,同时减少前端ajax轮询请求,减少资源开销. spring boo ...

  2. H5一二事

    先回顾一下WEB技术的几个阶段 Web 1.0 内容为主,主要流行HTML和CSS Web 2.0 动态网页,流行AJAX/JavaScript/DOM H5 时代,WEB开发回归富客户端 那么H5肯 ...

  3. 文档通信(跨域-不跨域)、时时通信(websocket)、离线存储(applicationCache)、开启多线程(web worker)

    一.文档间的通信 postMessage对象 //不跨域 1.iframe:obj.contentWindow [iframe中的window对象] iframe拿到父级页面的window: pare ...

  4. Web Worker javascript多线程编程(一)

    什么是Web Worker? web worker 是运行在后台的 JavaScript,不占用浏览器自身线程,独立于其他脚本,可以提高应用的总体性能,并且提升用户体验. 一般来说Javascript ...

  5. Netty 实现 WebSocket 聊天功能

    上一次我们用Netty快速实现了一个 Java 聊天程序(见http://www.waylau.com/netty-chat/).现在,我们要做下修改,加入 WebSocket 的支持,使它可以在浏览 ...

  6. Java用webSocket实现tomcat的日志实时输出到web页面

    原文:http://blog.csdn.net/smile326/article/details/52218264 1.场景需求 后台攻城狮和前端攻城狮一起开发时,经常受到前端攻城狮的骚扰,动不动就来 ...

  7. 转:鏖战双十一-阿里直播平台面临的技术挑战(webSocket, 敏感词过滤等很不错)

    转自:http://www.infoq.com/cn/articles/alibaba-broadcast-platform-technology-challenges 鏖战双十一-阿里直播平台面临的 ...

  8. html5---webworker多线程

    javascript本身就是一个单线程的语言,一开始它的出现是为了简单的网页设计,设计者并没有考虑到多线程的问题,要知道,线程的开销是非常昂贵的.但是随着web开发的潮流化,javascript不是仅 ...

  9. 根据Unix哲学来编写你的HTML5 Websocket服务器来实现全双工通信

    websocketd代表WebSocket的守护进程 websocketd处理的是浏览器和服务器之间的WebSocket连接,它会启动你所指定的服务器端应用来对WebSockets进行处理,然后在浏览 ...

随机推荐

  1. 用 Entity Framework结合Oracle数据库来开发项目

    项目需要,要使用Oracle 11g数据库.作为不想写SQL的程序员,所以...... 原先想当然的是使用EF+MSSQL的方式来进行配置.吃了哑巴亏.然后谷歌出了一篇好文,沿着这篇文章进行了搭建,I ...

  2. [笔记]ACM笔记 - 组合数

    一.高中数学公式复习 , (好吧这个没学过但是既然看到了就一并抄过来了) 二.快速求组合数取模C(n, m)%p 当n和p大小不同时方法有不同. 1. n很小,p随意,p不需要为素数 1) 原理 使用 ...

  3. Linux_shell 学习

    shell中test的运用 test 命令是用于检查某个条件是否成立,他可以进行数值.符号.文件三个方面的测试 1.数值中的运用 -eq 等于 -ne 不等于 -gt 大于 -ge 大于等于 -lt ...

  4. 关于List<T> 的排序

    /** * @author hjn * @entity Student * @date 2017年5月23日15:22:18 */ public class Student { private Str ...

  5. SmartCoder每日站立会议09

    站立会议内容 今天约了在一起编程,详细确定各个页面以及消息的添加.发送等一些小的细节. 1.站立会议照片:      2.任务展板 2.燃尽图

  6. Libsvm使用资料

    原理: 1. pluskid(张弛原)的支持向量机教程(人家现在都是大牛了) http://blog.pluskid.org/?page_id=683 2. JerryLead机器学习教程 http: ...

  7. 多线程编程-- part 5.3 LockSupport

    一.LockSupport的介绍 LockSupport是用来创建锁和其他同步类的基本线程阻塞原语.  LockSupport中的park() 和 unpark() 的作用分别是阻塞线程和解除阻塞线程 ...

  8. 同步中的四种锁synchronized、ReentrantLock、ReadWriteLock、StampedLock

    目录 1.synchronized同步锁 2.ReentrantLock重入锁 3.ReadWriteLock读写锁 4.StampedLock戳锁(目前没找到合适的名字,先这么叫吧...) 5.总结 ...

  9. .net开源权限管理系统

    有业务请加QQ 245747009 源码地址:http://git.oschina.net/sunzewei/EIP 一.更新记录1.更新日期:2017-02-24 00:00:002.更新内容: 版 ...

  10. Javascript及Jquery获取元素节点以及添加和删除操作

    用了javascript和jquery很久,把所有元素节点的操作总结了下,放在博客上作为记录. Javascript获取元素的主要方式有三种 1.document.getElementById('ma ...