Netty入门三:Netty概要讲解,全面了解Netty,做到胸有成竹

【Netty】模型篇三:Netty核心组件讲解 本文针对上一篇文章 【Netty】模型篇二:通过案例分析Netty线程模型以及Netty的核心组件 中涉及到的Netty核心组件进行分析讲解。 注意:这里强烈建议大家先学习一下 Java NIO,再来看本文。 阅读详情

http://www.tuicool.com/articles/mEJvYb


   读完这一章,我们基本上可以了解到Netty所有重要的组件,对Netty有一个全面的认识,这对下一步深入学习Netty是十分重要的,而学完这一章,我们其实已经可以用Netty解决一些常规的问题了。


一、先纵览一下Netty,看看Netty都有哪些组件?

     为了更好的理解和进一步深入Netty,我们先总体认识一下Netty用到的组件及它们在整个Netty架构中是怎么协调工作的。Netty应用中必不可少的组件:
  • Bootstrap or ServerBootstrap
  • EventLoop
  • EventLoopGroup
  • ChannelPipeline
  • Channel
  • Future or ChannelFuture
  • ChannelInitializer
  • ChannelHandler

     Bootstrap,一个Netty应用通常由一个Bootstrap开始,它主要作用是配置整个Netty程序,串联起各个组件。

     Handler,为了支持各种协议和处理数据的方式,便诞生了Handler组件。Handler主要用来处理各种事件,这里的事件很广泛,比如可以是连接、数据接收、异常、数据转换等。

     ChannelInboundHandler,一个最常用的Handler。这个Handler的作用就是处理接收到数据时的事件,也就是说,我们的业务逻辑一般就是写在这个Handler里面的,ChannelInboundHandler就是用来处理我们的核心业务逻辑。

     ChannelInitializer,当一个链接建立时,我们需要知道怎么来接收或者发送数据,当然,我们有各种各样的Handler实现来处理它,那么ChannelInitializer便是用来配置这些Handler,它会提供一个ChannelPipeline,并把Handler加入到ChannelPipeline。

     ChannelPipeline,一个Netty应用基于ChannelPipeline机制,这种机制需要依赖于EventLoop和EventLoopGroup,因为它们三个都和事件或者事件处理相关。

     EventLoops的目的是为Channel处理IO操作,一个EventLoop可以为多个Channel服务。

     EventLoopGroup会包含多个EventLoop。

     Channel代表了一个Socket链接,或者其它和IO操作相关的组件,它和EventLoop一起用来参与IO处理。

     Future,在Netty中所有的IO操作都是异步的,因此,你不能立刻得知消息是否被正确处理,但是我们可以过一会等它执行完成或者直接注册一个监听,具体的实现就是通过Future和ChannelFutures,他们可以注册一个监听,当操作执行成功或失败时监听会自动触发。总之,所有的操作都会返回一个ChannelFuture。


二、Netty是如何处理连接请求和业务逻辑的呢?-- Channels、Events 和 IO

     Netty是一个非阻塞的、事件驱动的、网络编程框架。当然,我们很容易理解Netty会用线程来处理IO事件,对于熟悉多线程编程的人来说,你或许会想到如何同步你的代码,但是Netty不需要我们考虑这些,具体是这样:

      一个Channel会对应一个EventLoop,而一个EventLoop会对应着一个线程,也就是说,仅有一个线程在负责一个Channel的IO操作。

     关于这些名词之间的关系,可以见下图:

     
      

     如图所示:当一个连接到达,Netty会注册一个channel,然后EventLoopGroup会分配一个EventLoop绑定到这个channel,在这个channel的整个生命周期过程中,都会由绑定的这个EventLoop来为它服务,而这个EventLoop就是一个线程。

     说到这里,那么EventLoops和EventLoopGroups关系是如何的呢?我们前面说过一个EventLoopGroup包含多个Eventloop,但是我们看一下下面这幅图,这幅图是一个继承树,从这幅图中我们可以看出,EventLoop其实继承自EventloopGroup,也就是说,在某些情况下,我们可以把一个EventLoopGroup当做一个EventLoop来用。



三、我们来看看如何配置一个Netty应用?-- BootsStrapping

     我们利用BootsStrapping来配置netty 应用,它有两种类型,一种用于Client端:BootsStrap,另一种用于Server端:ServerBootstrap,要想区别如何使用它们,你仅需要记住一个用在Client端,一个用在Server端。下面我们来详细介绍一下这两种类型的区别:

     1.第一个最明显的区别是,ServerBootstrap用于Server端,通过调用bind()方法来绑定到一个端口监听连接;Bootstrap用于Client端,需要调用connect()方法来连接服务器端,但我们也可以通过调用bind()方法返回的ChannelFuture中获取Channel去connect服务器端。

     2.客户端的Bootstrap一般用一个EventLoopGroup,而服务器端的ServerBootstrap会用到两个(这两个也可以是同一个实例)。为何服务器端要用到两个EventLoopGroup呢?这么设计有明显的好处,如果一个ServerBootstrap有两个EventLoopGroup,那么就可以把第一个EventLoopGroup用来专门负责绑定到端口监听连接事件,而把第二个EventLoopGroup用来处理每个接收到的连接,下面我们用一幅图来展现一下这种模式:

        

     PS: 如果仅由一个EventLoopGroup处理所有请求和连接的话,在并发量很大的情况下,这个EventLoopGroup有可能会忙于处理已经接收到的连接而不能及时处理新的连接请求,用两个的话,会有专门的线程来处理连接请求,不会导致请求超时的情况,大大提高了并发处理能力。

      我们知道一个Channel需要由一个EventLoop来绑定,而且两者一旦绑定就不会再改变。一般情况下一个EventLoopGroup中的EventLoop数量会少于Channel数量,那么就很有可能出现一个多个Channel公用一个EventLoop的情况,这就意味着如果一个Channel中的EventLoop很忙的话,会影响到这个Eventloop对其它Channel的处理,这也就是为什么我们不能阻塞EventLoop的原因。

     当然,我们的Server也可以只用一个EventLoopGroup,由一个实例来处理连接请求和IO事件,请看下面这幅图:


      

 

四、我们看看Netty是如何处理数据的?-- Netty核心ChannelHandler

     下面我们来看一下netty中是怎样处理数据的,回想一下我们前面讲到的Handler,对了,就是它。说到Handler我们就不得不提ChannelPipeline,ChannelPipeline负责安排Handler的顺序及其执行,下面我们就来详细介绍一下他们:

 ChannelPipeline and handlers

     我们的应用程序中用到的最多的应该就是ChannelHandler,我们可以这么想象,数据在一个ChannelPipeline中流动,而ChannelHandler便是其中的一个个的小阀门,这些数据都会经过每一个ChannelHandler并且被它处理。这里有一个公共接口ChannelHandler:


     

     从上图中我们可以看到,ChannelHandler有两个子类ChannelInboundHandler和ChannelOutboundHandler,这两个类对应了两个数据流向,如果数据是从外部流入我们的应用程序,我们就看做是inbound,相反便是outbound。其实ChannelHandler和Servlet有些类似,一个ChannelHandler处理完接收到的数据会传给下一个Handler,或者什么不处理,直接传递给下一个。下面我们看一下ChannelPipeline是如何安排ChannelHandler的:


     

     从上图中我们可以看到,一个ChannelPipeline可以把两种Handler(ChannelInboundHandler和ChannelOutboundHandler)混合在一起,当一个数据流进入ChannelPipeline时,它会从ChannelPipeline头部开始传给第一个ChannelInboundHandler,当第一个处理完后再传给下一个,一直传递到管道的尾部。与之相对应的是,当数据被写出时,它会从管道的尾部开始,先经过管道尾部的“最后”一个ChannelOutboundHandler,当它处理完成后会传递给前一个ChannelOutboundHandler。

数据在各个Handler之间传递,这需要调用方法中传递的ChanneHandlerContext来操作, 在netty的API中提供了两个基类分ChannelOutboundHandlerAdapter和ChannelOutboundHandlerAdapter,他们仅仅实现了调用ChanneHandlerContext来把消息传递给下一个Handler,因为我们只关心处理数据,因此我们的程序中可以继承这两个基类来帮助我们做这些,而我们仅需实现处理数据的部分即可。

     我们知道InboundHandler和OutboundHandler在ChannelPipeline中是混合在一起的,那么它们如何区分彼此呢?其实很容易,因为它们各自实现的是不同的接口,对于inbound event,Netty会自动跳过OutboundHandler,相反若是outbound event,ChannelInboundHandler会被忽略掉。

     当一个ChannelHandler被加入到ChannelPipeline中时,它便会获得一个ChannelHandlerContext的引用,而ChannelHandlerContext可以用来读写Netty中的数据流。因此,现在可以有两种方式来发送数据,一种是把数据直接写入Channel,一种是把数据写入ChannelHandlerContext,它们的区别是写入Channel的话,数据流会从Channel的头开始传递,而如果写入ChannelHandlerContext的话,数据流会流入管道中的下一个Handler。   

五、我们最关心的部分,如何处理我们的业务逻辑? -- Encoders, Decoders and Domain Logic

     Netty中会有很多Handler,具体是哪种Handler还要看它们继承的是InboundAdapter还是OutboundAdapter。当然,Netty中还提供了一些列的Adapter来帮助我们简化开发,我们知道在Channelpipeline中每一个Handler都负责把Event传递给下一个Handler,如果有了这些辅助Adapter,这些额外的工作都可自动完成,我们只需覆盖实现我们真正关心的部分即可。此外,还有一些Adapter会提供一些额外的功能,比如编码和解码。那么下面我们就来看一下其中的三种常用的ChannelHandler:

Encoders和Decoders

     因为我们在网络传输时只能传输字节流,因此,才发送数据之前,我们必须把我们的message型转换为bytes,与之对应,我们在接收数据后,必须把接收到的bytes再转换成message。我们把bytes to message这个过程称作Decode(解码成我们可以理解的),把message to bytes这个过程成为Encode。

     Netty中提供了很多现成的编码/解码器,我们一般从他们的名字中便可知道他们的用途,如ByteToMessageDecoder、MessageToByteEncoder,如专门用来处理Google Protobuf协议的ProtobufEncoder、 ProtobufDecoder。

     我们前面说过,具体是哪种Handler就要看它们继承的是InboundAdapter还是OutboundAdapter,对于Decoders,很容易便可以知道它是继承自ChannelInboundHandlerAdapter或 ChannelInboundHandler,因为解码的意思是把ChannelPipeline传入的bytes解码成我们可以理解的message(即Java Object),而ChannelInboundHandler正是处理Inbound Event,而Inbound Event中传入的正是字节流。Decoder会覆盖其中的“ChannelRead()”方法,在这个方法中来调用具体的decode方法解码传递过来的字节流,然后通过调用ChannelHandlerContext.fireChannelRead(decodedMessage)方法把编码好的Message传递给下一个Handler。与之类似,Encoder就不必多少了。

Domain Logic

     其实我们最最关心的事情就是如何处理接收到的解码后的数据,我们真正的业务逻辑便是处理接收到的数据。Netty提供了一个最常用的基类SimpleChannelInboundHandler<T>,其中T就是这个Handler处理的数据的类型(上一个Handler已经替我们解码好了),消息到达这个Handler时,Netty会自动调用这个Handler中的channelRead0(ChannelHandlerContext,T)方法,T是传递过来的数据对象,在这个方法中我们便可以任意写我们的业务逻辑了。


Netty实战(六)ChannelHandler和ChannelPipeline 可以看到上面两段代码的事件流是一样的,需要注意的是虽然被调用的 Channel 或 ChannelPipeline 上的 write()方法一直传播事件通过整个 ChannelPipeline,但是在 ChannelHandler 的级别上,事件从一个ChannelHandler到下一个 ChannelHandler 的移动是由 ChannelHandlerContext 上的调用完成的。要想处理这种类型的入站异常,你需要在你的 ChannelInboundHandler 实现中重写下面的方法。 阅读详情

相关推荐

深入了解Netty之ChannelHandler与Pipeline(一)

2021SC@SDUSC 目录前言一、ChannelHandler1.ChannelInboundHandler入站处理器2.ChannelOutboundHandler出站处理器二、Pipeline三、ChannelHandlerContext 前言 本篇博客主要介绍ChannelHandler、Pipeline、ChannelHandlerContext及三者之间的关系。 Reactor模式的两个重要的组件,一个是Reactor反应器,在Netty中的对应的实现是EventLoop,另一个重要的组.

weixin_46449172的博客 358

Netty4详解三:Netty架构设计

读完这一章,我们基本上可以了解到Netty所有重要的组件,对Netty有一个全面的认识,这对下一步深入学习Netty是十分重要的,而学完这一章,我们其实已经可以用Netty解决一些常规的问题了。 一、先纵览一下Netty,看看Netty都有哪些组件?      为了更好的理解和进一步深入Netty,我们先总体认识一下Netty用到的组件及它们在整个Netty架构中是怎么协调工作

Heaven Wang 的专栏 3万+

超详细Netty入门,看这篇就够了!

思维导图 前言 本文主要讲述Netty框架的一些特性以及重要组件,希望看完之后能对Netty框架有一个比较直观的感受,希望能帮助读者快速入门Netty,减少一些弯路。 一、Netty概述 官方的介绍: Netty isan asynchronous event-driven network application framework for rapid development of maintainable high performance protocol servers & ..

阿里云云栖号 2万+

Netty4关于ChannelInboundHandler的使用说明

前言: Netty中处理输入输出字节的最重要的类就是ChannelInboundHandler(处理输入字节)、ChannelOutboundHandler(处理输出字节) 下面我们从最简单的使用到复杂使用来回顾一下关于这些Handler的处理 Netty版本说明:笔者使用的是netty-4.1.10版本,以下代码均基于此编写 1.服务端 服务...

恐龙弟旺仔的博客 1万+

Netty入门教程——深入浅出Netty

什么是Netty? Netty 是一个利用 Java 的高级网络的能力,隐藏其背后的复杂性而提供一个易于使用的 API 的客户端/服务器框架。 Netty 是一个广泛使用的 Java 网络编程框架(Netty 在 2011 年获得了Duke's Choice Award,见https://www.java.net/dukeschoice/2011)。它活跃和成长于用户社区,像大型公司 Facebook 和 Instagram 以及流行 开源项目如 Infinispan, HornetQ, Vert.x,

Vermont_的博客 3万+

【Netty入门教程】Netty基础篇之入门详情介绍

本文主要讲述Netty框架的一些特性以及重要组件,希望看完之后能对Netty框架有一个比较直观的感受,希望能帮助读者快速入门Netty,减少一些弯路。 Netty是 一个异步事件驱动的网络应用程序框架,用于**快速开发可维护的高性能协议服务器和客户端。 Netty是一个NIO客户端-服务器框架,可以快速轻松地开发协议服务器和客户端等网络应用程序。它大大简化和简化了TCP和UDP套接字服务器等网络编程。

No8g攻城狮的博客 1648

Netty的基础知识

1、简介 1、Netty是一个提供了易于使用的API的客户端/服务器框架 2、高并发-NIO 3、传输快 4、线程访问资源,该资源是否准备就绪的一种处理方式 5、同步和异步是指访问数据的一种机制 6、BIO: 同步阻塞IO 7、NIO 同步非阻塞IO 8、AIO 异步非阻塞IO 9、单线程模型: 10、多线程模型:由一组NIO线程处理IO操作 11、主从线程模型:一组线程池接收请求,一组...

夏季版 232

框架篇(Netty) ---Netty入门讲解

目录 前言 Netty的由来 Netty的特性 Netty的核心组件 简单DEMO 重要的ByteBuf ChannelHandler 和 ChannelPipeline Netty线程模型 编解码器 网络应用开发流程 总结 相关资源 前言 Netty是一个高性能、异步事件驱动的NIO框架,它提供了对TCP、UDP和文件传输的支持,作为一个异步NIO框架,Net...

Coder_Light的博客 1007

Netty入门(快速了解以及使用netty)

Netty 是一个异步的、基于事件驱动的网络应用框架,用于快速开发可维护、高性能的网络服务器和客户端。Netty 在 Java 网络应用框架中的地位就好比:Spring 框架在 JavaEE 开发中的地位 以下的框架都使用了 Netty,因为它们有网络通信需求! Cassandra - nosql 数据库 Spark - 大数据分布式计算框架 Hadoop - 大数据分布式存储框架 RocketMQ - ali 开源的消息队列 ElasticSearch - 搜索引擎 gRPC

lonelykkk的博客 8627

LoRa模块选型指南:正点原子ATK-LORA-01与SX1278芯片深度评测(含实测距离/功耗数据)

本文深度评测了正点原子ATK-LORA-01与SX1278芯片的性能表现,通过实测数据展示其在复杂环境中的通信距离与功耗表现。特别适合智慧农业、工业监测等物联网应用场景,提供详细的配置指南和优化技巧,帮助开发者实现高效、低功耗的LoRa通信解决方案。

weixin_29191081的博客 290

Allegro Design Entry CIS 与 OrCAD Capture CIS:PCB设计工具链中的双雄对决

本文深入对比了Cadence旗下两大原理图设计工具Allegro Design Entry CIS与OrCAD Capture CIS。Allegro Design Entry CIS源自Concept HDL,定位高端,强调自顶向下的层次化设计和与Allegro PCB Editor的无缝约束管理,适合大型复杂系统及团队协作。OrCAD Capture CIS则以其出色的易用性、广泛的兼容性和强大的CIS数据库功能著称,是中小型项目及跨工具链协作的通用选择。文章从历史渊源、核心功能、适用场景等多维度剖析,

bush的博客 486

Netty4详解三:Netty概要讲解,全面了解Netty,做到胸有成竹

读完这一章,我们基本上可以了解到Netty所有重要的组件,对Netty有一个全面的认识,这对下一步深入学习Netty是十分重要的,而学完这一章,我们其实已经可以用Netty解决一些常规的问题了。一、先纵览一下Netty,看看Netty都有哪些组件? 为了更好的理解和进一步深入Netty,我们先总体认识一下Netty用到的组件及它们在整个Netty架构中是怎么协调工作的。Netty应用中必不可少的组

野生码农 7418

步进电机 cia402协议 报文自己的理解 (笔记)

步进电机 cia402协议 报文自己的理解 (笔记)

she666666的博客 3802

Netty快速入门

Netty快速入门

Zhangsama1的博客 8988

Android蓝牙开发—经典蓝牙和BLE(低功耗)蓝牙的区别

      最近在做蓝牙开发,刚接触时傻傻的分不清经典蓝牙和低功耗蓝牙的区别,一直用开发低功耗蓝牙的方法去连接经典蓝牙设备,最后当然是一直连接不上了。在此记录下经典蓝牙和低功耗蓝牙的区别和联系。 Android中的蓝牙         说到Android中的蓝牙,大家听到的可能有蓝牙1.0、蓝牙2.0、蓝牙3.0、蓝牙4.0之类的以数字结尾的蓝牙版本号,而实际上,在最新的标准中,已经不再使用数...

zqf_888的博客 4万+

2026年紫光同创数字IC笔试试卷带答案

FPGA基础知识与设计要点摘要 本文围绕FPGA与数字IC设计核心概念,通过单选题、波形分析题、多选题和简答题形式,系统梳理了以下关键知识点: FPGA基础架构 查找表(LUT)是实现组合逻辑的基本单元(题1) CLB包含LUT、触发器和进位链,后者加速算术运算(题6,10) 布局布线优化是减少关键路径延迟的核心方法(题7) 时序分析要点 建立时间(时钟沿前数据需稳定)与保持时间(时钟沿后需保持)的定义(题2,简答1) 亚稳态成因及两级同步器处理跨时钟域信号的方法(多选题1,波形题5) 特殊设计技术 异步复

Open 114

Netty入门

【零拷贝】的体现之一,对原始 ByteBuf 进行切片成多个 ByteBuf,切片后的 ByteBuf 并没有发生内存复制,还是使用原始 ByteBuf 的内存,切片后的 ByteBuf 维护独立的 read,write 指针。netty 中的 Future 与 jdk 中的 Future 同名,但是是两个接口,netty 的 Future 继承自 jdk 的 Future,而 Promise 又对 netty Future 进行了扩展。connect 方法是异步的,意味着不等连接建立,方法执行就返回了。

我的博客 1690

“/usr/lib/wsl/wsl-setup“ failed, exiting

WSL2安装Ubuntu时出现"wsl-setup failed"错误的解决方法 摘要:当Windows用户名包含中文字符时,安装WSL2+Ubuntu会出现"wsl-setup failed"错误。本文提供两种解决方案:1)修改中文用户名(风险较大);2)通过命令手动配置。推荐第二种方法:先使用"wsl -l -v"查看Ubuntu名称,再通过"wsl -d Ubuntu20.04 -e /bin/bash"命令启动WSL2系

猿小白的博客 994

【Netty篇】幽默的讲解带你入门 Netty !建议收藏

解放生产力: 你不用再跟底层NIO那些恶心的细节死磕了 😩,Netty帮你搞定!

qq_56158663的博客 1429

【网络与爬虫 61】移动端App爬虫终极指南:Android-iOS应用数据提取黑科技全解析

本文全面解析移动端App爬虫技术,涵盖Android和iOS两大平台的数据提取方法。从基础的网络抓包到高级的代码注入,从自动化测试框架到反调试技术绕过,为开发者提供移动端数据采集的完整解决方案和实战经验。

熵数实验室 3025

UE5 GAS 学习笔记 1.2游戏标签

这一节对GameplayTag游戏标签进行详细的讲解。

CloudHuCoding 1927

Netty入门 -- 什么是Netty?

通俗易懂,一文让你搞懂Netty~

wanghuichen的博客 2330

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

Netty-基础入门

Netty是一个异步的、基于事件驱动的网络应用框架,用于快速开发可维护、高性能的网络服务器和客户端。

Java就是我的道! 7828

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

Netty学习——Netty入门

二. Netty 入门 1. 概述 1.1 Netty 是什么? Netty is an asynchronous event-driven network application framework for rapid development of maintainable high performance protocol servers & clients. Netty 是一个异步的、基于事件驱动的网络应用框架,用于快速开发可维护、高性能的网络服务器和客户端。 这里的异步是指Netty采用了

maruofan666的博客 1985

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

Netty 入门

​ Netty 中所有的 I/O 操作都是异步的,即操作不会立即得到返回结果,所以 Netty 中定义了一个 ChannelFuture 对象作为这个异步操作的“代言人”,表示异步操作本身。​ Bootstrap 是客户端的引导类,Bootstrap 在调用 bind()(连接UDP)和 connect()(连接TCP)方法时,会新创建一个 Channel,仅创建一个单独的、没有父 Channel 的 Channel 来实现所有的网络交换。Worker线程通常是一个线程池,可以处理多个客户端的连接请求。

Mr_changxin的博客 1004
上一篇: 基于Netty4的HttpServer和HttpClient的简单实现
下一篇: java中内存泄漏
小瑞
博客等级 码龄19年 240粉丝 274原创
评论 3
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值