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(一) 此文用来记录学习笔记: 休息了好几天,从今天开始继续保持更新,鞭策自己学习 今天我们来说一说什么是事件,对于事件 ...
随机推荐
- elasticsearch6.5.x-centos6
elasticsearch6.5.x-centos6 elasticsearch 和 关系型数据库中的类比 es ====== RDBMS index ----- database type ---- ...
- DirectX12的初始化
DirectX12的初始化主要分为以下若干步骤: 创建device和gifactory 创建与GPU通信同步相关的objects,command和fence 创建swap chain 为render ...
- 利用302绕过http协议限制
360某处ssrf漏洞可探测内网信息(附内网6379探测脚本) http://xss.one/bug_detail.php?wybug_id=wooyun-2016-0229611
- 流程控制之☞ while 和 for 的故事
学习三连鞭... 什么是循环? 为什么要有循环? 如何用循环? 循环的基本语法:while 和 for 先来看while循环: while条件:首先得是个循环体. 1.如果条件为真,那么循 ...
- Nebula Graph 在微众银行数据治理业务的实践
本文为微众银行大数据平台:周可在 nMeetup 深圳场的演讲这里文字稿,演讲视频参见:B站 自我介绍下,我是微众银行大数据平台的工程师:周可,今天给大家分享一下 Nebula Graph 在微众银行 ...
- ubuntu20部署php-swoole开发环境
第1步:安装依赖 add-apt-repository ppa:ondrej/php apt install php-dev 第2步:编译安卓swoole wget https://codeload. ...
- 【命令】htop命令
一.Htop的使用简介 大家可能对top监控软件比较熟悉,今天我为大家介绍另外一个监控软件Htop,姑且称之为top的增强版,相比top其有着很多自身的优势.如下: 两者相比起来,top比较繁琐 默认 ...
- asp.net url参数中有中文request.querystring 乱码
说明: 从这点我们发现:所有的参数输入,都调用了一次:HttpUtility.UrlDecode(str2, encoding); 结论出来了: 当客户端js对中文以utf-8编码提交到服务端时,用R ...
- sql优化的几种方式
一.为什么要对SQL进行优化 我们开发项目上线初期,由于业务数据量相对较少,一些SQL的执行效率对程序运行效率的影响不太明显,而开发和运维人员也无法判断SQL对程序的运行效率有多大,故很少针对SQL进 ...
- [leetcode]304Range Sum Query 2D - Immutable动态规划计算二维数组中子数组的sum
303一维数组的升级版,方法就是用二维数组res存下从(0,0)到当前位置的sum,存的方法是动态规划,看着二维数组画圈比较好搞清楚其中的加减法 算子数组的sum的时候也是和存差不多的逻辑,就是某一部 ...