【死磕Netty】-----Netty的核心组件

原文出处http://cmsblogs.com/ 『chenssy』 转载请注明原创出处,谢谢!

在第一篇博客中(【死磕Netty】-----NIO基础详解),那一大坨的服务端、客户端代码各位应该看着都会害怕。博主在 15 年写过 NIO,那滋味的酸爽现在都还记忆犹新,而且运行后,中途还会出现异常,所以开发一个具有较好的稳定性和可靠性的 NIO 程序还是挺有难度的。于是 Netty 出现,把我们从水深火热当中解救出来。

什么是 Netty?

Netty 是一款提供异步的、事件驱动的网络应用程序框架和工具,用以快速开发高性能、高可靠性的网络服务器和客户端程序 也就是说,Netty 是一个基于 NIO 的客户、服务器端编程框架,使用 Netty 可以确保你快速和简单地开发出一个网络应用,例如实现了某种协议的客户,服务端应用。Netty 相当简化和流线化了网络应用的编程开发过程,例如,TCP 和 UDP 的 socket 服务开发。(以上摘自百度百科)。

Netty具有如下特性(摘自《Netty in Action》)

分类

Netty的特性

设计

统一的API,支持多种传输类型,阻塞和非阻塞的 简单而强大的线程模型真正的无连接数据报套接字支持链接逻辑组件以支持复用

易于使用

详实的 Javadoc 和大量的示例集不需要超过JdK 1.6+的依赖

性能

拥有比 Java 的核心 API 更高的吞吐量以及更低的延迟得益于池化和复用,拥有更低的资源消耗最少的内存复制

健壮性

不会因为慢速、快速或者超载的连接而导致 OutOfMemoryError 消除在高速网络中 NIO 应用程序常见的不公平读/写比率

安全性

完整的 SSL/TLS 以及 StartTLs 支持可用于受限环境下,如 Applet 和 OSGI

社区驱动

发布快速而且频繁

Netty核心组件

为了后期更好地理解和进一步深入 Netty,有必要总体认识一下 Netty 所用到的核心组件以及他们在整个 Netty 架构中是如何协调工作的。Nettty 有如下几个核心组件:

  • Channel
  • ChannelFuture
  • EventLoop
  • ChannelHandler
  • ChannelPipeline

Channel

Channel 是 Netty 网络操作抽象类,它除了包括基本的 I/O 操作,如 bind、connect、read、write 之外,还包括了 Netty 框架相关的一些功能,如获取该 Channe l的 EventLoop。

在传统的网络编程中,作为核心类的 Socket ,它对程序员来说并不是那么友好,直接使用其成本还是稍微高了点。而Netty 的 Channel 则提供的一系列的 API ,它大大降低了直接与 Socket 进行操作的复杂性。而相对于原生 NIO 的 Channel,Netty 的 Channel 具有如下优势(摘自《Netty权威指南(第二版)》):

  • 在 Channel 接口层,采用 Facade 模式进行统一封装,将网络 I/O 操作、网络 I/O 相关联的其他操作封装起来,统一对外提供。
  • Channel 接口的定义尽量大而全,为 SocketChannel 和 ServerSocketChannel 提供统一的视图,由不同子类实现不同的功能,公共功能在抽象父类中实现,最大程度地实现功能和接口的重用。
  • 具体实现采用聚合而非包含的方式,将相关的功能类聚合在 Channel 中,有 Channel 统一负责和调度,功能实现更加灵活。

EventLoop

Netty 基于事件驱动模型,使用不同的事件来通知我们状态的改变或者操作状态的改变。它定义了在整个连接的生命周期里当有事件发生的时候处理的核心抽象。

Channel 为Netty 网络操作抽象类,EventLoop 主要是为Channel 处理 I/O 操作,两者配合参与 I/O 操作。

下图是Channel、EventLoop、Thread、EventLoopGroup之间的关系(摘自《Netty In Action》):

  • 一个 EventLoopGroup 包含一个或多个 EventLoop。
  • 一个 EventLoop 在它的生命周期内只能与一个Thread绑定。
  • 所有有 EnventLoop 处理的 I/O 事件都将在它专有的 Thread 上被处理。
  • 一个 Channel 在它的生命周期内只能注册与一个 EventLoop。
  • 一个 EventLoop 可被分配至一个或多个 Channel 。

当一个连接到达时,Netty 就会注册一个 Channel,然后从 EventLoopGroup 中分配一个 EventLoop 绑定到这个Channel上,在该Channel的整个生命周期中都是有这个绑定的 EventLoop 来服务的。

ChannelFuture

Netty 为异步非阻塞,即所有的 I/O 操作都为异步的,因此,我们不能立刻得知消息是否已经被处理了。Netty 提供了 ChannelFuture 接口,通过该接口的 addListener() 方法注册一个 ChannelFutureListener,当操作执行成功或者失败时,监听就会自动触发返回结果。

ChannelHandler

ChannelHandler 为 Netty 中最核心的组件,它充当了所有处理入站和出站数据的应用程序逻辑的容器。ChannelHandler 主要用来处理各种事件,这里的事件很广泛,比如可以是连接、数据接收、异常、数据转换等。

ChannelHandler 有两个核心子类 ChannelInboundHandler 和 ChannelOutboundHandler,其中 ChannelInboundHandler 用于接收、处理入站数据和事件,而 ChannelOutboundHandler 则相反。

ChannelPipeline

ChannelPipeline 为 ChannelHandler 链提供了一个容器并定义了用于沿着链传播入站和出站事件流的 API。一个数据或者事件可能会被多个 Handler 处理,在这个过程中,数据或者事件经流 ChannelPipeline,由 ChannelHandler 处理。在这个处理过程中,一个 ChannelHandler 接收数据后处理完成后交给下一个 ChannelHandler,或者什么都不做直接交给下一个 ChannelHandler。

当一个数据流进入 ChannlePipeline 时,它会从 ChannelPipeline 头部开始传给第一个 ChannelInboundHandler ,当第一个处理完后再传给下一个,一直传递到管道的尾部。与之相对应的是,当数据被写出时,它会从管道的尾部开始,先经过管道尾部的 “最后” 一个ChannelOutboundHandler,当它处理完成后会传递给前一个 ChannelOutboundHandler 。

当 ChannelHandler 被添加到 ChannelPipeline 时,它将会被分配一个 ChannelHandlerContext,它代表了 ChannelHandler 和 ChannelPipeline 之间的绑定。其中 ChannelHandler 添加到 ChannelPipeline 过程如下:

  1. 一个 ChannelInitializer 的实现被注册到了 ServerBootStrap中
  2. 当 ChannelInitializer.initChannel() 方法被调用时,ChannelInitializer 将在 ChannelPipeline 中安装一组自定义的 ChannelHandler
  3. ChannelInitializer 将它自己从 ChannelPipeline 中移除

谢谢阅读,祝好!!!

参考资料

  • 《Netty In Action》

原文发布于微信公众号 - chenssy(chenssy89)

原文发表时间:2017-12-04

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

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏SpringBoot

Ckplayer试看功能

最近在做一个付费看视频项目,找了很多视频插件,一直得不到自己想要的效果,直到看到CK。

8094
来自专栏刘望舒

为什么现在要用Gradle?

又要开启一个新系列了,这个系列我们来学习Gradle,它是一个基于JVM的新一代构建工具,关于Gradle完全可以写一本书,这个系列会针对Android开发来对...

1051
来自专栏Java后端技术栈

Spring Cloud微服务全家桶主要组件及简要介绍

微服务是最近的一两年的时间里是很火的一个概念。感觉不学习一下都快跟不上时代的步伐了,下边做一下简单的总结和介绍。

3153
来自专栏JAVA高级架构

作为一个Java架构师程序员 你应该会什么

一,JAVA架构师 1、语法:Java 程序员必须比较熟悉语法,在写代码的时候IDE 的编辑器对 某一行报错应该能够根据报错信息 知道是什么样的语法错误并且知道...

4115
来自专栏Java职业技术分享

一个老程序员是如何手写Spring MVC的?「附代码」

人见人爱的Spring已然不仅仅只是一个框架了。如今,Spring已然成为了一个生态。但深入了解Spring的却寥寥无几。这里,我带大家一起来看看,我是如何手写...

1150
来自专栏程序你好

流行的9个Java框架介绍: 优点、缺点等等

在2018年,Java仍然是世界上最流行的编程语言。它拥有一个巨大的生态系统,在全世界有超过900万Java开发人员。虽然Java不是最直接的语言,但是您不需要...

2022
来自专栏闻道于事

Spring技术内幕:设计理念和整体架构概述

2603
来自专栏互扯程序

SpringBoot 如何在一分钟内整合SSM?

写在前面 前几天看到“互扯程序”技术群(想要入群进行技术讨论请在下方留言)里有人问,什么是SSM?相信99%的人应该知道是什么,那么我给剩下的1%的人再解释一...

5655
来自专栏北京马哥教育

Apache、tomcat、Jboss、weblogic、WebSphere区别和容器的作用

总结:Apache/Tomcat/JBOSS/Nginx区别 . 1、Apache是Web服务器,Tomcat是应用(Java)服务器。Tomcat在中小型系...

8356
来自专栏一个会写诗的程序员的博客

Gatling : 次时代性能测试利器

Gatling作为一款开源免费的性能测试工具越来越受到广大程序员的欢迎。免费当然是好的,最缺钱的就是程序员了;开源更好啊,缺啥功能、想做定制化的可以自己动手,丰...

1172

扫码关注云+社区

领取腾讯云代金券