读完这一章,我们基本上能够了解到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是一个非堵塞的、事件驱动的、网络编程框架。当然,我们非常easy理解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()方法来绑定到一个port监听连接;Bootstrap用于Client端,须要调用connect()方法来连接server端,但我们也能够通过调用bind()方法返回的ChannelFuture中获取Channel去connectserver端。
2.client的Bootstrap一般用一个EventLoopGroup,而server端的ServerBootstrap会用到两个(这两个也能够是同一个实例)。为何server端要用到两个EventLoopGroup呢?这么设计有明显的优点,假设一个ServerBootstrap有两个EventLoopGroup,那么就能够把第一个EventLoopGroup用来专门负责绑定到port监听连接事件。而把第二个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中是混合在一起的。那么它们怎样区分彼此呢?事实上非常easy。由于它们各自实现的是不同的接口。对于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,非常easy便能够知道它是继承自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从某方面来说就是一套NIO框架,在Java NIO基础上做了封装。所以要想学好Netty我建议先理解好Java NIO,建议大家阅读一下我的另两篇文章:
Java NIO具体解释(一) 
Java NIO具体解释(二)
转载请说明出处,原文链接:http://blog.csdn.net/suifeng3051/article/details/28861883 

转载于:https://www.cnblogs.com/yutingliuyl/p/6740559.html

Netty4具体解释三:Netty架构设计相关推荐

  1. Netty架构设计与功能特性

    本文来说下Netty架构设计与功能特性 文章目录 Netty架构 Netty特性 丰富的缓冲实现(数据容器) 统一的异步 I/O API 基于拦截链模式的事件模型 本文小结 Netty架构 Netty ...

  2. 联发科发布天玑1200芯片:6nm工艺 采用1+3+4三丛架构设计

    1月20日消息,联发科天玑新品发布会在线上举办,联发科推出天玑1200与天玑1100. 参数方面,两款芯片均采用6nm工艺,其中,天玑1200基于台积电6纳米先进工艺制造,CPU采用1+3+4的旗舰级 ...

  3. 游戏SDK(三)架构设计之代码实现1

    前言 上一篇介绍了游戏SDK架构设计的思路,大体的项目结构如下: - sdk-demo // sdk 测试 demo - sdk-api // sdk 接口模块 - sdk-manager // sd ...

  4. 成就系统实现(三)-架构设计

    1.技术选型 之前上网找过一些关于成就系统设计的文档,推荐的都是事件驱动模型,因此底层设计也基于这个模型来做,由业务方产生可能触发成就的事件,统一放到一个队列里面,由线程去取队列里面的事件,进行分发处 ...

  5. Netty架构与原理详解

    本文来详细说下netty架构设计与原理 文章目录 概述 Netty 基础 Netty 是什么 Netty 的应用场景 Java 中的网络 IO 模型 Java NIO API 简单回顾 缓冲区(Buf ...

  6. 基于SCORM标准课件的移动客户端架构设计

    一.前言 本不想前言写些相关概念,想直奔主题了,但作为男人直奔主题好像不太好,怎么也得有个前言聊会来点气氛,怎么,已经有很懂的同学,好吧,请无视本节直奔后面的主题好了. 什么SCORM? SCORM是 ...

  7. 从业务开发中学习和理解架构设计

    作者:张东爱(当爱)  阿里自主出行研发团队 一.前言 在软件开发领域经常会接触到架构这个词汇,在我最初的印象中,架构是一个很高级的词汇.它似乎代表了复杂的工程结构.高层次的抽象设计.最新的开发语言特 ...

  8. 架构设计复杂度的6个来源

    谈到架构设计,相信每个技术人员都耳熟能详.我总结了三个架构设计相关的特性: 架构设计的思维和程序设计的思维差异很大. 架构设计没有体系化的培训和训练机制. 程序员对架构设计的理解存在很多误区. 所以, ...

  9. 云原生时代微服务的高可用架构设计

    简介: 在8月20日"阿里巴巴技术质量精品课"上,来自蚂蚁的经国分享了对云原生时代微服务的高可用架构设计的全面解析,为大家介绍了应用架构演进路径.云原生时代的技术福利.高可用架构的 ...

最新文章

  1. vue.js中请求数据v-for循环使用数据
  2. Java 10- 详解var关键字和示例教程
  3. 日历控件的android代码,Android日历控件PickTime代码实例
  4. CSS基础(part13)--浮动
  5. LeetCode:二叉树相关应用
  6. 身份证明检索失败,如何解决?
  7. 火狐导cookie文件没反应_效率指南|实操区分FireFox火狐的国内版和国际版
  8. asp.net验证空间详说
  9. C4996: 'inet_addr': Use inet_pton() or InetPton() instead or define _WINSOCK_DEPRECATED_NO_WARNINGS
  10. After Effects - Bodymovin 插件验货及感受
  11. 控制数学问题的MATLAB求解,控制数学问题的MATLAB求解.pdf
  12. itunes一直显示正在验证iphone恢复_超全面iPhone实用技巧汇总,有用收藏
  13. 海思59V200PQtool环境的搭建
  14. 尚硅谷github案例
  15. 懂户型图 如何选择好户型
  16. 忘记teamviewer密码怎么办?
  17. vue日程安排_vue 时间安排表
  18. 建筑业和VECP项目(上)
  19. DOO-SABIN 细分正方体(2)利用半边数据结构表示(一次和两次细分)
  20. Java校招面试,项目怎么聊

热门文章

  1. 【刷算法】重建二叉树
  2. 本地win7ping VM linux ipv6地址问题
  3. 【Silverlight】Bing Maps开发应用与技巧三:Bing Maps Silverlight Control的离线开发
  4. Jmeter简单应用6
  5. 办公室,手机上网不用愁
  6. TopCoder 入门教程 -- sqybi完善版
  7. Eric Lippert对C#的评论和展望
  8. Visual studio 2017基本配置
  9. KVM — 安装部署
  10. 用 Flask 来写个轻博客 (20) — 实现注册表单与应用 reCAPTCHA 来实现验证码