netty中的一个小bug

WebSocket快速上手 文章目录WebSocket快速上手1. WebSocket是什么?1.1. WebSocket连接过程1.2. WebSocket与HTTP对比1.3. WebSocket协议2. 快速上手2.1 服务端2.2 客户端2.2.1 浏览器客户端2.2.2 Java客户端 WebSocket快速上手 1. WebSocket是什么? WebSocket建立在TCP协议之上,并且与HTTP协议有着良好的... 阅读详情
在读netty的websocket处理的handler部分的代码的时候,发现了一个小bug,不过这个bug不会造成太大的影响,我们来看看WebSocketServerProtocolHandler的decode部分的代码:
    @Override
    protected void decode(ChannelHandlerContext ctx, WebSocketFrame frame, List<Object> out) throws Exception {
        if (frame instanceof CloseWebSocketFrame) {  //如果是用于关闭
            WebSocketServerHandshaker handshaker = getHandshaker(ctx);
            frame.retain();
            handshaker.close(ctx.channel(), (CloseWebSocketFrame) frame); //发送用于关闭的websocket帧
            return;
        }
        super.decode(ctx, frame, out);  
    }
这里


这里当收到的客户端的帧是用于关闭连接的话,按照websocket协议,需要向客户端返回这个帧,然后关闭底层的socket连接,这里是获取以前用到的用于websocket建立连接的握手对象来处理这个帧的,问题就处在这里,因为其实最后获取这个handshaker对象将会是null的,我们来看看获取这个方法的定义:

    static WebSocketServerHandshaker getHandshaker(ChannelHandlerContext ctx) {
        return ctx.attr(HANDSHAKER_ATTR_KEY).get();
       
    }

那么我们再来看看是什么时候set的吧,他是在WebSocketServerProtocolHandshakeHandler里面设置的,前面已经提到,不同版本的websocket需要对应的握手对象来处理,直接来看看代码吧:

    @Override
    public void channelRead(final ChannelHandlerContext ctx, Object msg) throws Exception {
        FullHttpRequest req = (FullHttpRequest) msg;
        if (req.getMethod() != GET) {  //如果不是get请求,那么就出错了
            sendHttpResponse(ctx, req, new DefaultFullHttpResponse(HTTP_1_1, FORBIDDEN));
            return;
        }
        //创建爱你websocket进行连接握手的工厂类,因为不同版本的连接握手不太一样
        final WebSocketServerHandshakerFactory wsFactory = new WebSocketServerHandshakerFactory(
                getWebSocketLocation(ctx.pipeline(), req, websocketPath), subprotocols, allowExtensions);
        final WebSocketServerHandshaker handshaker = wsFactory.newHandshaker(req);  //这里会根据不同的websocket版本来安排不同的握手handler
        if (handshaker == null) {
            WebSocketServerHandshakerFactory.sendUnsupportedWebSocketVersionResponse(ctx.channel());
        } else {
        	//其实这里在将用于建立连接的http报文发送回去之后,会将前面添加的http部分的handler都移除,然后加上用于decode和encode针对websocket帧的handler
            final ChannelFuture handshakeFuture = handshaker.handshake(ctx.channel(), req);   //这里说白了就是进行握手,向客户端返回用于建立连接的报文
            handshakeFuture.addListener(new ChannelFutureListener() {
                @Override
                public void operationComplete(ChannelFuture future) throws Exception {
                    if (!future.isSuccess()) {
                        ctx.fireExceptionCaught(future.cause());
                    } else {
                        ctx.fireUserEventTriggered(  //用于激活握手已经完成的事件,可以让用户的代码收到通知
                                WebSocketServerProtocolHandler.ServerHandshakeStateEvent.HANDSHAKE_COMPLETE);
                    }
                }
            });
            WebSocketServerProtocolHandler.setHandshaker(ctx, handshaker);   //记录用到的用于握手的对象
            ctx.pipeline().replace(this, "WS403Responder",
                    WebSocketServerProtocolHandler.forbiddenHttpRequestResponder());  //将当前这个handler替换,因为只有刚开始使用http协议进行通信,接下来就没有了
        }
    }

在这里,将从factory中获取的shaker对象保存起来,我们知道么一个handlercontext其实也是一个attributemap对象,那么也就是将这个shaker对象放到了当前的ctx中,

而上面获取shaker的时候,却是在WebSocketServerProtocolHandler的context中获取,那么必然将会获取null,这个异常将会被WebSocketServerProtocolHandler的exceptionCaught方法来处理,而这里正好就是将channel关闭了,因此正好,这个bug也不会出现什么问题。。。



netty-Netty线程模型&epoll-bug问题 Proactor&Reactor Proactor和Reactor是两种经典的多路复用IO模型,主要用于在高并发,高吞吐量的环境下进行IO处理。 IO多路复用机制都依赖于事件分发器,事件分发器将客户事件分发到不同的事件处理器中. Select&poll&epoll 在操作系统级别上,select,poll,epoll是三个常用的IO多路复用机制。 三者的具体区别与实现请读... 阅读详情

相关推荐

Netty是如何解决JDK空轮询Bug的?

Selector每一次轮询都计数selectCnt++,开始轮询会将系统时间戳赋值给timeoutMillis,轮询完成后再将系统时间戳赋值给time,这两个时间会有一个时间差,而这个时间差就是每次轮询所消耗的时间。这是与操作系统机制有关系的,JDK虽然仅仅是一个兼容各个操作系统平台的软件,但遗憾的是在JDK 5和JDK 6最初的版本中,这个问题并没有得到解决,而将这个“帽子”抛给了操作系统方,这就是这个Bug一直到2013年才最终修复的原因。就这样,Netty完美解决了JDK的空轮询Bug。

程序员野蛮成长 1031

Netty源码分析-Websocket之WebSocketServerHandshakerFactory

public class WebSocketServerHandshakerFactory { //WebSocket地址 private final String webSocketURL; //子协议 private final String subprotocols; //是否允许扩展协议 private final boolea...

大新博客 6184

Netty : netty 3如何解决空轮询bug

1.美图 2.概述 空轮询bug参考:Netty : 臭名昭出的JDK的NIO bug(空轮询bug) 3. netty 3 如何解决 netty3采用的是第三种方案,检测重点是select函数是否返回了0。代码在AbstractNioSelector类中 if (timeBlocked < minSelectTimeout) { boolean notConnected = fa...

九师兄 1287

HTTP与WebSocket协议的区别以及基于Netty搭建WebSocket

WebSocket 是一种网络传输协议,可在单个 TCP 连接上进行全双工通信,位于 OSI 模型的应用层。WebSocket 协议在 2011 年由 IETF 标准化为RFC 6455,后由RFC 7936补充规范。WebSocket 使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在 WebSocket API 中,浏览器和服务器只需要完成一次握手,两者之间就可以创建持久性的连接,并进行双向数据传输。

m0_74229735的博客 2250

Netty : netty 4如何解决空轮询bug

1.美图 2.概述 空轮询bug参考:Netty : 臭名昭出的JDK的NIO bug(空轮询bug) 4.netty4 解决 4.1 构建阈值 int selectorAutoRebuildThreshold = SystemPropertyUtil.getInt("io.netty.selectorAutoRebuildThreshold", 512); if (selectorAutoRe...

九师兄 2255

Netty : 臭名昭著的JDK的NIO bug(空轮询bug)

1.美图 2.概述 在搞这个问题的时候 Netty:Netty不断打开文件的BUG 一直找不到原因,然后偶然想了一下是不是netty的空轮询bug,后来查了一下真的是,第一感觉居然是,我草,我草,好兴奋,太他妈刺激了,我居然遇到了传说中的bug,哈哈哈哈,容我笑一会。 在 李林峰的<Netty权威指南>,第2.6.1章写到不使用JDK原生NIO框架的原因是JDK存在epoll bu...

九师兄 5030

Netty网络编程(六):搭建websocket服务器

websocket是一个优秀的协议,它是建立在TCP基础之上的,兼容HTTP的网络协议。通过Websocket我们可以实现客户端和服务器端的即时通讯,免除了客户端多次轮循带来的性能损耗。既然websocket这么优秀,那么怎么在netty中使用websocket呢?

Java+GO+JS全栈工程师-鹤冲天的博客:编程辅导~商务合作~技术交流 1万+

电竞护航系统成品搭建俱乐部点单小程序开发三角洲小程序搭建

电竞护航系统成品搭建俱乐部点单小程序开发三角洲小程序搭建

dapengglove的博客 1682

WebSocket初体验

前言 今天在慕课网上看到了Java的新教程(Netty入门之WebSocket初体验):https://www.imooc.com/learn/941 WebSocket我是听得很多,没有真正使用过的技术。我之前也去了解过了WebSocket究竟是什么东西,不过一直没有去实践过。 我在写监听器博文的时候,在线人数功能用监听器的是来做,在评论有说使用WebSocket的方式会更加好。 那么,我们就来...

u013272476的博客 481

STM32F407与AD7766实战:如何用SPI+DMA实现高速ADC数据采集(附完整代码)

本文详细介绍了如何利用STM32F407的SPI接口与DMA控制器,高效稳定地驱动24位高精度ADC芯片AD7766,实现高速连续数据采集。通过对比传统中断方式的瓶颈,阐述了SPI+DMA方案如何大幅降低CPU负载,并提供了从硬件设计、CubeMX配置到核心驱动代码的完整实战指南,帮助工程师解决高速ADC数据采集中的性能难题。

weixin_29281941的博客 186

Windows下快速搭建MSYS2开发环境(含GCC与MinGW配置)

本文详细介绍了在Windows系统下快速搭建MSYS2开发环境的完整流程。通过使用pacman包管理器,可以便捷地安装GCC编译器与MinGW-w64工具链,并配置系统环境变量。文章还涵盖了从基础安装、系统更新到编译开源项目的实战指南,帮助开发者高效构建原生Windows程序,显著提升C/C++开发效率。

weixin_29213827的博客 538

Netty 的空轮询bug是什么?

是早期版本中因 JDK NIO 的。:重建后事件循环恢复正常阻塞状态。,引发事件循环线程陷入死循环。

大户影视的博客 2036

Auto.js凉了之后,我们该用啥?AutoX.js保姆级环境搭建与第一个脚本实战(2024最新)

本文详细介绍了AutoX.js作为Auto.js替代方案的环境搭建与脚本开发实战指南。从技术生态现状分析到2024最新环境配置,再到编写第一个实用脚本和进阶调试技巧,帮助开发者无缝迁移至AutoX.js平台。特别适合需要手机自动化的JavaScript开发者,涵盖从基础到企业级应用的全套解决方案。

weixin_28737073的博客 388

我给 Netty 提交了一个 bug

本系列Netty源码解析文章基于 4.1.56.Final版本写在前面.....本文是笔者肉眼盯 Bug 系列的第三弹,前两弹分别是:抓到Netty一个Bug,顺带来透彻地聊一下Netty是如何高效接收网络连接的 ,在这篇文章中盯出了一个在 Netty 接收网络连接时,影响吞吐量的一个 Bug。抓到Netty一个隐藏很深的内存泄露Bug | 详解Recycler对象池的精...

weixin_41385912的博客 617

SAP Parallel Accounting(平行分类账业务)配置及操作手册【适用于多国家会计准则】

在SAP系统中,分类账(Ledger)是用于会计核算的核心概念,它允许企业根据不同的会计原则和货币进行财务记录。定义分类账是配置平行账(Parallel Accounting)的第一步。分类账的创建:通过事务代码OX18可以创建新的分类账。通常,一个SAP系统会有一个主分类账(如0L),它代表法定会计和实时传输至管理会计(CO)的账本。分类账属性:在创建分类账时,需要定义其属性,如会计年度变式、货币、会计原则等。这些属性将决定分类账的核算规则和适用性。

数字化2025 4615

Windows 11 安装 MySQL 8.4:安装包方式、下载、安装、使用

本文详细介绍了在 Windows 11 系统下通过 MSI 安装包方式安装 MySQL 8.4 LTS 社区版的完整流程,包括版本选择、下载、自定义安装路径、服务配置、日志设置、示例数据库创建及后续使用方法。同时提供了命令行客户端与图形化工具 DBeaver 的连接与操作演示,适合初学者和开发者快速搭建本地 MySQL 开发环境。

寒水馨 · 轻量级技术文档 · hanshuixin.org 2257

NIO的空轮询bug是什么?netty是如何解决NIO空轮询bug的?

文章目录1. NIO的空轮询bug2. netty如何解决NIO空轮询bug的? 1. NIO的空轮询bug         JDK1.5开始引入了epoll基于事件响应机制来优化NIO。相较于select和poll机制来说,epoll机制将事件处理交给了操作系统内核(操作系统硬中断)来处理,优化了elect和poll模型的无效遍历问题。        &n

qq_1149513559的博客 5165

【碳排放数据集】全球近实时网格化二氧化碳排放数据集GRACED

【碳排放数据集】全球近实时网格化二氧化碳排放数据集GRACED

WW、forever的博客 146

【Netty基础】Netty的高性能及NIO的epoll空轮询bug

Selector BUG出现的原因若Selector的轮询结果为空,也没有wakeup或新消息处理,则发生空轮询,CPU使用率100%,Netty的解决办法 对Selector的select操作周期进行统计,每完成一次空的select操作进行一次计数, 若在某个周期内连续发生N次空轮询,则触发了epoll死循环bug。 重建Selector,判断是否是其他线程发起的重建请求,若不是则将原Socket

白夜行 2万+

华为OD机试双机位C卷:打印机队列 (C++/Py/C/Java/Js/Go)

华为OD机试双机位C卷 打印机队列,提供C语言、Java、C++、Python、Go、JavaScript源码实现,并提供完整思路讲解。华为OD机试 - 打印机队列。

qq_45776114的博客 1793

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

Netty源码解析-Netty解决Nio epoll bug

前言: Netty作为一个优秀的NIO框架,不仅仅是对JDK NIO的使用进行封装,使其更易用,而且对其一些原生BUG也进行了修复。其中epoll cpu 100%的一个bug的修复更是经典。 1.bug产生的场景 常规使用NIO ServerSocket来接收连接的方式如下: Selector selector = Selector.open(); while (true) { int count = selector.select(); Set<SelectionKe

恐龙弟旺仔的博客 1888

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

抓到Netty一个Bug,顺带来透彻地聊一下Netty是如何高效接收网络连接的

抓到Netty一个Bug!!于是把发现修复Bug的过程总结成文,介绍一下Bug产生的原因,造成的影响,以及最终的修复方案。同时详细介绍一下Netty是如何高效的接收网络连接的!

bin的技术小屋 1754

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

Netty 如何解决 JDK Selector 空轮询 BUG?

Netty 的空轮询解决方案默认启用,无需手动配置,但实际开发中可根据需求调整参数,并通过日志监控重建情况。不依赖底层修复,主动掌控主动权面对第三方依赖(如 JDK、操作系统内核)的缺陷,不要被动等待上游修复——尤其是底层组件,修复周期长、兼容性覆盖难。Netty 从应用层设计解决方案,既规避了旧环境的缺陷,又不依赖新版本,这对生产级系统至关重要(很多企业仍在使用 JDK 8,无法通过升级 JDK 解决问题)。检测+容错的闭环设计,拒绝“裸奔”

埃泽漫笔 1109

Netty对Channel事件的处理以及空轮询Bug的解决

主要刨析Netty处理连接事件并注册的全过程,有助于理解Netty线程模型

m0_73700925的博客 747

5. 抓到Netty一个Bug,顺带来透彻地聊一下Netty是如何高效接收网络连接的

java

blueheartstone的博客 297

Netty——NIO 空轮询 bug

本文讲解了 NIO 的空轮询 bug,并介绍了一种简单的解决方案和 Netty 的解决方案。

qq_61350148的博客 1250
上一篇: netty的websocket服务端开发
下一篇: HttpServlet分析
fjs_cloud
博客等级 码龄15年 248粉丝 192原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值