Netty学习:EventLoop事件机制
EventLoop是什么
如果你去百度EventLoop,肯定会百度到很多关于JavaScript,NodeJS的文章,是的,这两种语言的事件机制就依赖于EventLoop,但是EventLoop到底是什么,可以先思考2个问题:
- 一般情况下,当我们要实现令一个线程不断处理任务,都是选择使用while(true){……}这样的结构,但是往往为了防止无限循环空跑占用CPU时间,会在死循环中使用sleep()来空出时间。有更好的方法吗?
- Redis的性能毋庸置疑,但是Redis是单线程的,单线程的Redis是如何达到不逊色于多线程的性能的呢?(当然也是EventLoop)。
EventLoop事实上是一种线程编程模型,简而言之,将需要执行的任务封装成原子化的Event,都交到一个线程去执行,而这个线程唯一的任务就是不断的从自己的Event事件池中取出来Event去执行。那么为什么叫Loop呢?因为这种模型适用于非阻塞的操作,在非阻塞Event发生后,将该Event以及回调函数封装成一个CheckEvent,继续扔到Event池中,在不断执行Event的过程中,当执行到CheckEvent时,会去检查非阻塞操作是否成功,成功则执行回调,未成功则继续扔进去等待下一次,所以这种模型叫做EventLoop=事件轮询。
EventLoop适用的场景
或许你会说,EventLoop性能这么高,这么帅,那大家都用不就好了?事实上,EventLoop也有他局限的场景,如上所说,这种编程场景多用于该系统大多数事件可以封装成异步事件时,EventLoop会有更好的吞吐和执行效率,比如JavaScript要在js执行完后交由浏览器进行绘制这种图形客户端场景,或者redis这种使用密集IO型,或者Netty这种天生NIO框架。简而言之:异步非阻塞操作多,回调机制多。当你需要Check的事件不多,都是实际需要执行的任务时,EventLoop比起线程池,优势就微乎其微了,并且EventLoop的实现还更为复杂。所以不是什么场景都适合使用的。
Netty中的EventLoop
Netty中使用的当然也是EventLoop,这是它的一个优点或者说提升它性能的原因。
EventLoopGroup group = new NioEventLoopGroup();
Bootstrap b = new Bootstrap();
b.group(group)
Netty代码肯定少不了这几句,其中NioEventLoopGroup就是Netty的EventLoop实现,一个Group中包含多个EventLoop,类似线程池和线程的关系。支持构造函数传进去里面的线程数,如果不传的话默认是CPU数*2。
Netty中的大量inEventLoop判断
看过Netty源码的很多人肯定会看到Netty的源码中有大量的如下判断:
if (!inEventLoop && !executor.inEventLoop(currentThread)) {
executor.execute(new Runnable() {
});
}
这个判断是为什么呢?我一开始也很疑惑,后面随着对Netty的理解,才知道,对Netty来说,Netty许多函数的调用方,它并不知道调用方是谁,是在自己的内部EventLoop内,还是在用户线程里,所以它在一些用户很可能在用户线程里调用的方法,增加了这类判断,将这些方法的执行转移到EventLoop中。
Netty是如何建立连接并监听端口的-NIOSocketChannel
初看Netty源码,Netty是怎么建立端口监听以及连接的,都找了我许久。先上一段标准代码,这是netty源码例子中的代码。
EventLoopGroup bossGroup = new NioEventLoopGroup(1);
EventLoopGroup workerGroup = new NioEventLoopGroup();
final EchoServerHandler serverHandler = new EchoServerHandler();
try {
ServerBootstrap b = new ServerBootstrap();
b.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.option(ChannelOption.SO_BACKLOG, 100)
.handler(new LoggingHandler(LogLevel.INFO))
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline p = ch.pipeline();
if (sslCtx != null) {
p.addLast(sslCtx.newHandler(ch.alloc()));
}
//p.addLast(new LoggingHandler(LogLevel.INFO));
p.addLast(serverHandler);
}
});
// Start the server.
ChannelFuture f = b.bind(PORT).sync();
// Wait until the server socket is closed.
f.channel().closeFuture().sync();
} finally {
// Shut down all event loops to terminate all threads.
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
可以看到其中主要就是配置了EventLoopGroup,channel,handler,这三个东西,这三个东西就是netty三大件,总领了Netty。建立连接的就是其中的NioServerSocketChannel,这个NioSocketChannel这种是Netty包装了Java原生的SocketChannel,在启动时(server)或者进行请求时(client)通过反射进行创建并运行。
Netty,bossGroup与workerGroup
Netty默认构造函数,支持设置2个EventLoopGroup,其中分为Boss和Worker,其中Boss只负责处理连接请求的建立,以及key的select,类似主线程,Worker负责具体的读写,handler处理等其他任务,官方建议这两个的线程数比是1:5,实际使用中可以看情况设置。
Netty学习:EventLoop事件机制的更多相关文章
- Netty学习篇④-心跳机制及断线重连
心跳检测 前言 客户端和服务端的连接属于socket连接,也属于长连接,往往会存在客户端在连接了服务端之后就没有任何操作了,但还是占用了一个连接:当越来越多类似的客户端出现就会浪费很多连接,netty ...
- Netty学习摘记 —— 心跳机制 / 基于分隔符和长度的协议
本文参考 本篇文章是对<Netty In Action>一书第十一章"预置的ChannelHandler和编解码器"的学习摘记,主要内容为通过 SSL/TLS 保护 N ...
- 系统学习DOM事件机制
本文将从以下几个方面介绍DOM事件: 基本概念:DOM事件的级别 DOM事件模型,事件流 描述DOM事件捕获的具体流程 Event对象的常见应用 自定义事件 DOM事件的级别 //DOM0 eleme ...
- 【iScroll源码学习03】iScroll事件机制与滚动条的实现
前言 想不到又到周末了,周末的时间要抓紧学习才行,前几天我们学习了iScroll几点基础知识: 1. [iScroll源码学习02]分解iScroll三个核心事件点 2. [iScroll源码学习01 ...
- Netty 源码学习——EventLoop
Netty 源码学习--EventLoop 在前面 Netty 源码学习--客户端流程分析中我们已经知道了一个 EventLoop 大概的流程,这一章我们来详细的看一看. NioEventLoopGr ...
- Netty学习摘记 —— 再谈EventLoop 和线程模型
本文参考 本篇文章是对<Netty In Action>一书第七章"EventLoop和线程模型"的学习摘记,主要内容为线程模型的概述.事件循环的概念和实现.任务调度和 ...
- Ext JS学习第十七天 事件机制event(二)
此文仅有继续学习笔记: 昨天说了三种邦定事件的方法,今天说一下自定义事件 假设现在又这样的情景一个自定义的事件 没有用到事件处理的场景 母亲问孩子和不饿-> ...
- Netty学习(八)-Netty的心跳机制
版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/a953713428/article/details/69378412我们知道在TCP长连接或者Web ...
- Ext JS学习第十六天 事件机制event(一) DotNet进阶系列(持续更新) 第一节:.Net版基于WebSocket的聊天室样例 第十五节:深入理解async和await的作用及各种适用场景和用法 第十五节:深入理解async和await的作用及各种适用场景和用法 前端自动化准备和详细配置(NVM、NPM/CNPM、NodeJs、NRM、WebPack、Gulp/Grunt、G
code&monkey Ext JS学习第十六天 事件机制event(一) 此文用来记录学习笔记: 休息了好几天,从今天开始继续保持更新,鞭策自己学习 今天我们来说一说什么是事件,对于事件 ...
随机推荐
- ubuntu20.04 系统初始化与美化
ubuntu20.04 系统初始化与美化 参考博客:https://mp.weixin.qq.com/s/JowjHrs9GMVlolaoaSGiEg 参考博客:https://www.linuxmi ...
- xss未看完的文章
https://blog.csdn.net/fen0707/article/details/8596888 XSS介绍与攻击 http://xss.fbisb.com/w ...
- SSRF CTF 例题
一道ctf题目,有两个文件:ssrf3.php和flag.php 题目意思是flag只能127.0.0.1访问,还进行了post验证,这就需要gopher提交post数据来绕过 curl设置了302跳 ...
- HCIP --- BGP 总结
AS:自治系统 --逻辑管理域(例如移动.电信.联通),AS号范围:0-65535,其中,1-64511:公有AS,64512-65535:私有AS IGP:内部网关协议,在一个AS之内传递的路由协 ...
- C# 多态virtual标记重写 以及EF6 查询性能AsNoTracking
首先你如果不用baivirtual重写的话,系统默认会为du你加new关键字,他zhi的作用是覆盖,而virtual的关键作用在dao于实现多态 virtual 代表在继承了这个类的子类里面可以使用o ...
- 用git上传项目到GitHub或者码云全过程
用git上传项目到GitHub或者码云全过程 1. 会生成一个隐藏文件夹".git".这是一个不可删文件,因为暂存区和历史区还有一些其他的信息都在这里,删掉就不是一个完整的仓库了 ...
- 关于git中的merge和rebase
变基-git官网说明 变基 改变提交的基于分支 和merge不同 合并显示合并记录 变基合并更新后一起提交 不显示合并记录 变基 合并的结果是一致的
- Ext CheckBoxGroup使用
一.效果图展示 我这里主要是为了实现选择周期时间.如周一.周二.周三等 二.界面界面代码 下面就是我实现的代码,包含了界面.数据处理.回填数据等.可能架构的方式,您的代码和我的代码有差异,但是大体就是 ...
- maven项目修改名称后,打包名称和现在名称不一致
将pom.xm文件中 <artifactId>health</artifactId> 修改成现在项目名称,然后 maven clean ->maven install 如 ...
- [leetcode]304Range Sum Query 2D - Immutable动态规划计算二维数组中子数组的sum
303一维数组的升级版,方法就是用二维数组res存下从(0,0)到当前位置的sum,存的方法是动态规划,看着二维数组画圈比较好搞清楚其中的加减法 算子数组的sum的时候也是和存差不多的逻辑,就是某一部 ...