Netty学习笔记之Netty介绍及常用组件(一)

一、Netty介绍

1、Netty简介

Netty是由JBOSS提供的一个java开源框架,现为 Github上的独立项目。Netty提供异步的、事件驱动的网络应用程序框架和工具,用以快速开发高性能、高可靠性的网络服务器和客户端程序。

也就是说,Netty 是一个基于NIO的客户、服务器端的编程框架,使用Netty 可以确保你快速和简单的开发出一个网络应用,例如实现了某种协议的客户、服务端应用。Netty相当于简化和流线化了网络应用的编程开发过程,例如:基于TCP和UDP的socket服务开发。

“快速”和“简单”并不用产生维护性或性能上的问题。Netty 是一个吸收了多种协议(包括FTP、SMTP、HTTP等各种二进制文本协议)的实现经验,并经过相当精心设计的项目。最终,Netty 成功的找到了一种方式,在保证易于开发的同时还保证了其应用的性能,稳定性和伸缩性。 

2、Netty优势

1、API使用简单,开发门槛低;

2、功能强大,预置了多种编解码功能,支持多种主流协议;

3、定制能力强,可以通过ChannelHandler对通信框架进行灵活地扩展;

4、性能高,通过与其他业界主流的NIO框架对比,Netty的综合性能最优;

5、成熟、稳定,Netty修复了已经发现的所有JDK NIO BUG,业务开发人员不需要再为NIO的BUG而烦恼;

6、社区活跃,版本迭代周期短,发现的BUG可以被及时修复,同时,更多的新功能会加入;

7、经历了大规模的商业应用考验,质量得到验证。

3、为什么Netty使用NIO而不是AIO?

Netty不看重Windows上的使用,在Linux系统上,AIO的底层实现仍使用EPOLL,没有很好实现AIO,因此在性能上没有明显的优势,而且被JDK封装了一层不容易深度优化。

AIO还有个缺点是接收数据需要预先分配缓存, 而不是NIO那种需要接收时才需要分配缓存, 所以对连接数量非常大但流量小的情况, 内存浪费很多。

而且Linux上AIO不够成熟,处理回调结果速度跟不上处理需求。

二、Netty程序组成

1、Bootstrap、EventLoop(Group)、Channel

        Bootstrap是Netty框架的启动类和主入口类,分为客户端类Bootstrap和服务器类ServerBootstrap两种。

        Channel是java NIO 的一个基本构造。它代表一个到实体(如一个硬件设备、一个文件、一个网络套接字或者一个能够执行一个或者多个不同的I/O操作的程序组件)的开放连接,如读操作和写操作。可以把Channel看作是传入(入站)或者传出(出站)数据的载体。因此,他可以被打开或者被关闭,连接或者断开连接。

        EventLoop暂时可以看成一个线程、EventLoopGroup自然可以看成线程组。

2、事件和ChannelHandler、ChannelPipeline

        Netty使用不同的事件来通知我们状态的改变或者是操作的状态。这使得我们能够基于已经发生的事件来触发适当的动作。

        Netty事件是按照它们的入站或出站数据流的相关性分类的。

        可能由入站数据或者相关的状态更改而触发的事件包括:连接已被激活或者连接失活;数据读取;用户事件;错误事件;

        出站事件是未来将会触发的某个动作的操作结果,动作包括:打开或者关闭远程节点的连接;将数据写到或者冲刷到套接字。

 

        每个事件都可以被分发给ChannelHandler类中的某个用户实现的方法,既然事件分为入站和出站,用来处理事件的ChannelHandler也被分为可以处理入站事件的Handler和出站事件的Handler,当然有些Handler既可以处理入站也可以处理出站。

        Netty提供了大量预定义的可以开箱即用的ChannelHandler实现,包括用于各种协会(如HTTP和SSL/TLS)的CHannelHandler。

        基于Netty的网络应用程序中根据业务需求会使用Netty已经提供的ChannelHandler或自行开发的ChannelHandler,这些ChannelHandler都放在ChannelPipeline中统一管理,事件就会在ChannelPipeline中流动,并被其中一个或者多个ChannelHandler处理。

3、ChannelFuture

Netty中所有的I/O操作都是异步的,我们知道“异步的意思就是不需要主动等待结果的返回,而是通过其他手段,比如:状态通知、回调函数等”,那就是说至少我们需要一种获得异步执行结果的方式。

JDK预置了interface java.util.concurrent.Future,Future 提供了一种在操作完成通知应用程序的方式。这个对象可以看做是一个异步操作的结果占位符,他将在未来的某个时刻完成,或者一直阻塞直到它完成,并提供对结果的访问,但是只允许手动检查对应的操作是否已经完成,或者一直阻塞直到他完成。这非常繁琐,所以Netty提供了他自己的实现ChannelFuture,用于执行异步操作的时候使用。

一般来说,每个Netty的出站I/O操作都将返回一个ChannelFuture。

三、Netty组件详解

EventLoop和EventLoopGroup

在一个while循环中select出事件,然后依次处理每种事件。我们可以把它称为事件循环,这就是EventLoop。interface io.netty.channel. EventLoop 定义了Netty 的核心抽象,用于处理网络连接的生命周期中所发生的事件。

io.netty.util.concurrent 包构建在JDK 的java.util.concurrent 包上。而io.netty.channel 包中的类,为了与Channel 的事件进行交互,扩展了这些接口/类。一个EventLoop 将由一个永远都不会改变的Thread 驱动,同时任务(Runnable 或者Callable)可以直接提交给EventLoop 实现,以立即执行或者调度执行。

 线程的分配

        服务于Channel的I/O和事件的EventLoop包含在ExentLoopGroup中。

        异步传输实现只使用了少量的EventLoop(以及和它们相关联的Thread),而且在当前的线程模型中,它们可能会被多个Channel 所共享。这使得可以通过尽可能少量的Thread 来支撑大量的Channel,而不是每个Channel 分配一个Thread。EventLoopGroup 负责为每个新创建的Channel 分配一个EventLoop。在当前实现中,使用顺序循环(round-robin)的方式进行分配以获取一个均衡的分布,并且相同的EventLoop可能会被分配给多个Channel。

一旦一个Channel 被分配给一个EventLoop,它将在它的整个生命周期中都使用这个EventLoop(以及相关联的Thread)。

 

需要注意,EventLoop 的分配方式对ThreadLocal 的使用的影响。因为一个EventLoop 通常会被用于支撑多个Channel,所以对于所有相关联的Channel 来说,ThreadLocal 都将是一样的。这使得它对于实现状态追踪等功能来说是个糟糕的选择。然而,在一些无状态的上下文中,它仍然可以被用于在多个Channel 之间共享一些重度的或者代价昂贵的对象,甚至是事件。

线程管理

在内部,当提交任务到如果(当前)调用线程正是支撑EventLoop 的线程,那么所提交的代码块将会被(直接)执行。否则,EventLoop 将调度该任务以便稍后执行,并将它放入到内部队列中。当EventLoop下次处理它的事件时,它会执行队列中的那些任务/事件。

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

30岁老阿姨

支持一下哦!!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值