Netty事件监听和处理(上)

陪产假结束了,今天又开始正常上班了,正好赶上米粉节活动,又要忙上一阵了,米粉节活动时间为4.03 - 4.10,有不少优惠,感兴趣的可以关注mi.com或小米商城app。

今天给大家送了福利:小爱音箱F码,据说卖的比较好,不太好抢到,借着这次公司福利,分享给大家,以表大家的支持和鼓励。

掘金的运营真的很贴心,主动找到我说:我的福利文章不是技术型文章,不能推送到信息流,只能在个人主页看到,为了让更多的人参与这次抽取,建议写一篇技术文章,末尾加上送福利的内容。再次感谢掘金运营小哥「刺客」的贴心和建议。

RabbitMQ实战的后续章节还没来得及看,这篇就总结下之前在项目组分享过的技术点:Netty事件监听和处理。

通过介绍,你会了解到:

  • 事件监听、NIO、线程模型等相关概念;
  • Netty总体结构;
  • 事件监听和处理;
  • 项目实践总结;

本篇先介绍下前两节,下一篇介绍后两节。

本篇最后会说明下福利的抽取规则,大家积极参与 >_<

相关概念

Netty是一个NIO框架,它将IO通道的建立、可读、可写等状态变化,抽象成事件,以责任链的方式进行传递,可以在处理链上插入自定义的Handler,对感兴趣的事件进行监听和处理。

所以,先介绍下事件监听、责任链模型、socket接口和IO模型、线程模型等基本概念,对后面理解Netty的事件监听和处理有很大帮助。

事件监听

JDK监听器模式主要包含以下元素:

  • EventObject 事件对象
  • EventListener 事件监听接口
  • 自定义事件源
  • 事件触发

模式很简单,用户可以自定义事件源,保存触发对象的相关数据,事件被触发后,传递给注册事件的处理者。事件监听接口是为了统一处理者方法。

举个比较好理解的按钮单击事件,其中ActionListener是事件监听器,ActionEvent是事件对象,包含了事件源:

实现一套事件监听的具体过程:

  • 确定事件源;
  • 明确可能产生的事件,定义成不同的事件对象或事件方法;
  • 提供一个存储结构,用于保存监听事件的对象,当事件发生时,会通知监听者;
  • 执行回调方法,进行业务处理;
责任链模式

主要是说事件处理者的组织方式,通过责任链模式,可以在任何处理节点,添加自定义处理器,很方便。

关于责任链概念,这里再简单说下:使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系,将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理他为止。

socket

一般说NIO,主要是针对网络IO,从网卡中读取数据,向网卡中写入数据,这就是监听器模式的数据源。

网络编程主要通过操作系统提供的socket接口进行,通过了解socket接口可以总结出有哪些事件。

socket是用户进程和内核网络协议之间的统一接口。 socket也是一种特殊的文件,网络通信可以看作是对文件的读取,使得对网络的控制和对文件的控制一样方便。

NIO和IO模型

NIO是指非阻塞IO,我们一般说的IO都是阻塞IO,想全面了解这些概念,又会说的很多,这里就简单概括下。

一个进程所占的内存包括用户态和内核态,为了安全,用户代码是不能直接操作内核态内存的,通过系统调用进行交互,比如读取网络数据,交互过程如下:

用户线程发起read请求后,需要等待数据到达才能返回,在这期间,用户线程不能做任何事情,如果是网络编程,可能有很多Socket对象进行监听,会创建大量线程被阻塞,造成资源浪费,性能下降。

针对这种情况,出现了IO模型的概念,有几种方式:

  • 同步非阻塞IO;
  • IO多路复用;
  • 异步IO;

具体介绍,网上有很多资料,就不详细说了,这里只提下IO多路复用,说说我的理解,我们项目中就是使用这种方式。

所谓多路复用,主要是操作系统提供给我们这种开发模式:可以把感兴趣的IO事件(建立、可读、可写等)提前注册,而且多个socket对象可以注册到一个selector选择器上,这样就可以多个socket对象使用一个用户线程进行监听,当事件发生时,会查找对应的socket进行读、写等操作。

之前做过NIO开发的朋友,可以看下面的示例回顾下整个过程:

线程模型

上面说了我对多路复用的理解,提到了一个线程监听多个socket,但如果socket很多,一个线程是处理不过来的。另外,事件的接收和判断 与 数据的读取、处理、写入,可以在不同线程进行。

这就引出了线程模型的概念,比如Reactor和Proactor模型,具体细节就不介绍了,网上有很多资料,最终目的都是为了提高IO事件处理的性能。

Netty总体结构

这部分主要是了解下Netty,对其实现原理先不做深究。

概述

Netty 是一个异步的事件驱动的网络应用程序框架,支持快速地开发可维护的高性能的面向协议的服务器和客户端; 它驾驭了 Java 高级 API 的能力,并将其隐藏在一个易于使用的 API 之后;

  • Core(核心部分),是底层的网络通讯的一些通用抽象,这部分内容是关键。
  • Transport Services(传输服务),具体的网络传输能力的定义以及一些实现。
  • Protocol Support(协议支持),netty 对于一些通用协议的编码解码实现。
零拷贝

广义的零拷贝是指计算机操作的过程中,CPU不需要为数据在内存之间的拷贝消耗资源。Linux中的sendfile()以及 Java NIO 中的FileChannel.transferTo()方法都实现了零拷贝的功能,而在 Netty 中也通过在FileRegion中包装了 NIO 的FileChannel.transferTo()方法实现了零拷贝。

Netty中所指零拷贝,完全在用户态,更偏向于优化数据操作。Netty允许我们将多段数据合并为一整段虚拟数据供用户使用,而不需要对数据进行拷贝操作。

统一的通讯模型

传统的JAVA IO API 在应对不同的传输协议时,需要使用不同的类型和方法,例如:java.net.Socket和java.net.DatagramSocket,它们并不具有相同的超类型;Java新的IO API与原有的阻塞式IO API也不兼容;

Netty提供了统一的API编程接口,抽象了所有点对点通信操作,仅调整几行代码,便可切换不同的传输实现:

  • 基于NIO的TCP/IP传输
  • 基于OIO的TCP/IP传输
  • 基于OIO的UDP/IP传输
  • 本地传输
事件模型

也就是要说的事件监听和处理,提供了很好的方式去处理各种事件。

大致处理过程如上图,具体将在下一篇介绍。

欢迎扫描下方二维码,关注我的个人微信公众号,查看更多文章 ~

公众号:情情说

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

编辑于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏美团技术团队

Java NIO浅析

NIO(Non-blocking I/O,在Java领域,也称为New I/O),是一种同步非阻塞的I/O模型,也是I/O多路复用的基础,已经被越来越多地应用到...

4179
来自专栏MelonTeam专栏

[译]Android Instant Apps简介

导语 : Google最近发布了Instant Apps,可以帮助开发者进一步的增强Android的原生App体验。Instant Apps旨在通过在需要时只下...

4037
来自专栏aoho求索

认证鉴权与API权限控制在微服务架构中的设计与实现(一)

引言: 本文系《认证鉴权与API权限控制在微服务架构中的设计与实现》系列的第一篇,本系列预计四篇文章讲解微服务下的认证鉴权与API权限控制的实现。 1. 背景 ...

6666
来自专栏友弟技术工作室

PHP相关概念及配置

php MIME,http,html MIME:MIME(Multipurpose Internet Mail Extensions)多用途互联网邮件扩展类型 ...

44713
来自专栏后端云

实时操作系统

一般的linux都是GPOS(通用)内核。GPOS是不保证实时的,但是对于大多数应用程序来说是没有问题的。GPOS可以充分利用物理资源。但在实时性要求性比较高的...

2927
来自专栏云端架构

【云端架构】网站运维之CDN链接鉴权示例入门(PHP)

链接时间戳格式和有效时间与鉴权KEY 要求跟腾讯云CDN链接鉴权 配置保持同步,服务器以CDN节点配置为基准。以上模板可以根据需要调整,但请不要过度依赖模板,努...

94212
来自专栏程序猿DD

Spring Cloud构建微服务架构:服务容错保护(Hystrix依赖隔离)【Dalston版】

前言在上一篇《Spring Cloud构建微服务架构:服务容错保护(Hystrix服务降级)》中,我们已经体验了如何使用@HystrixCommand来为一个依...

2039
来自专栏三好码农的三亩自留地

快捷安装Flutter姿势,了解一下?

到 Flutter官网 直接下载SDK压缩包,找准你需要的平台下载并解压。为什么不用git 命令到 Flutter Github clone下来?因为你基本不可...

1101
来自专栏全华班

不错的Spring-代码生成器

Spring-generator是基于javafx8开发的图形界面Spring代码生成器,使用 Apache FreeMarker 作为代码文件的模板,用户可以...

2613
来自专栏Java帮帮-微信公众号-技术文章全总结

zookeeper启动错误zkEnv.sh:Syntax error:&quot;(&quot;unexpected(expecting&quot;fi&quot;)

昨天我把Ubuntu Server64位上的 zookeeper换成了最新版本的,结果启动的时候出错;之前zookeeper-3.3.6是没有任何问题的,换成了...

1443

扫码关注云+社区

领取腾讯云代金券