zoukankan      html  css  js  c++  java
  • Netty系列之源码解析(一)

    本文首发于微信公众号【猿灯塔】,转载引用请说明出处

    接下来的时间灯塔君持续更新Netty系列一共九篇

    当前:Netty 源码解析(一)开始

    Netty 源码解析(二): Netty 的 Channel

    Netty 源码解析(三): Netty 的 Future 和 Promise

    Netty 源码解析(四): Netty 的 ChannelPipeline

    Netty 源码解析(五): Netty 的线程池分析

    Netty 源码解析(六): Channel 的 register 操作

    Netty 源码解析(七): NioEventLoop 工作流程

    Netty 源码解析(八): 回到 Channel 的 register 操作

    Netty 源码解析(九): connect 过程和 bind 过程分析

    今天呢!灯塔君跟大家讲:  

    Netty 源码解析(一)


    前言:本文将介绍Netty,Java平台上使用最广泛的 NIO 包,它是对JDK中的NIO实现的一层封装,让我们能更方便地开发NIO程序。其实,Netty 不仅仅是NIO吧,但是基本上大家都冲着NIO来的。

    灯塔君感觉国内对于Netty的吹嘘是有点过了,主要是很多人靠它吃饭,要么是搞培训的,要么是出书的,恨不得把 Netty 吹上天去,这种现象也是挺不好的,反而使得初学者觉得Netty是什么高深的技术一样。

    Netty的源码不是很简单,因为它比较多,而且各个类之间的关系错综复杂,很多人说它的源码很好,这点灯塔君觉得一般,真要说好代码,还得Doug Lea的并发源码比较漂亮,一行行都是精华,不过它们是不同类型的,也没什么好对比的。

    Netty源码好就好在它的接口使用比较灵活,往往接口好用的框架,源码都不会太简单。

    本文将立足于源码分析,如果读者已经对Netty有些了解,或者使用过,那就更好了。

    • 本文只介绍TCP相关的内容,Netty对于其他协议的支持,不在本文的讨论范围内。
    • 和并发包的源码分析不一样,我不可能一行一行源码说,所以有些异常分支是会直接略过,除非我觉得需要介绍。
    • Netty源码一直在更新,各版本之间有些差异,我是按照2018-09-06的最新版本 4.1.25.Final 来进行介绍的。

    建议初学者在看完本文以后,可以去翻翻《Netty In Action》,网上也可以找到中文文字版的。

    一.准备


    学习源码,一开始肯定是准备环境。

    灯塔君喜欢用maven,也喜欢Spring Boot,所以我一般先到https://start.spring.io/准备一个最简单的脚手架。

    10秒搞定脚手架,然后就是导入到Intellij 中,如果用新版本的Spring Boot,可能还需要等待下载依赖,期间打开https://mvnrepository.com/搜索马上要用到的maven依赖。

    Netty分为好些模块,有netty-handler,netty-buffer、netty-transport、netty-common 等等也有一个netty-all,它包含了所有的模块。

    既然我们是源码分析,那么自然是用一个最简单的。netty-all不是最好的选择,netty-example才是:

    1<dependency>2   <groupId>io.netty</groupId>3   <artifactId>netty-example</artifactId>4   <version>4.1.25.Final</version>5</dependency>

    它不仅可以解决我们的依赖,而且example里面的示例非常适合我们学习使用。

    二.Echo例子


    Netty作为NIO的库,自然既可以作为服务端接受请求,也可以作为客户端发起请求.使用Netty开发客户端或服务端都是非常简单的,Netty做了很好的封装,我们通常只要开发一个或多个handler用来处理我们的自定义逻辑就可以了。

    下面,我们来看一个经常会见到的例子,它叫Echo,也就是回声,客户端传过去什么值,服务端原样返回什么值。

    开netty-example的源码把echo包下面的代码复制出来玩一玩。
    左边是服务端代码,右边是客户端代码

    上面的代码基本就是模板代码,每次使用都是这一个套路,唯一需要我们开发的部分是handler(...)和childHandler(...)方法中指定的各个handler,如EchoServerHandlerEchoClientHandler,当然Netty源码也给我们提供了很多的handler,比如上面的 LoggingHandler,它就是Netty源码中为我们提供的,需要的时候直接拿过来用就好了。

    我们先来看一下上述代码中涉及到的一些内容:

    • ServerBootstrap类用于创建服务端实例,Bootstrap用于创建客户端实例。
    • 两个EventLoopGroup:bossGroup和workerGroup,它们涉及的是Netty的线程模型,可以看到服务端有两个group而客户端只有一个,它们就是Netty中的线程池。
    • Netty中Channel,没有直接使用Java原生的ServerSocketChannel和SocketChannel,而是包装了NioServerSocketChannel和NioSocketChannel与之对应。
     当然,也有对其他协议的支持,如支持UDP协议的 NioDatagramChannel本文只关心TCP相关的。
    • 左边handler(...)方法指定了一个handler(LoggingHandler),这个handler是给服务端收到新的请求的时候处理用的,右边handler(...)方法指定了客户端处理请求过程中需要使用的handlers。
    如果你想在EchoServer中也指定多个handler也可以像右边的EchoClient一样使用ChannelInitializer
    • 左边childHandler(…) 指定了childHandler,这边的handlers是给新创建的连接用的,我们知道服务端ServerSocketChannel在accept一个连接以后,需要创建SocketChannel的实例,childHandler(…)中设置的handler就是用于处理新创建的SocketChannel的,而不是用来处理ServerSocketChannel实例的。
    • pipeline:handler可以指定多个(需要上面的ChannelInitializer类辅助),它们会组成了一个 pipeline,它们其实就类似拦截器的概念,现在只要记住一点每个NioSocketChannel或NioServerSocketChannel实例内部都会有一个pipeline实例pipeline中还涉及到handler 的执行顺序。
    • ChannelFuture:这个涉及到Netty中的异步编程,和JDK中的Future接口类似。

    对于不了解Netty的读者,也不要有什么压力,灯塔君会一一介绍它们,本文主要面向新手,灯塔君觉得比较难理解或比较重要的部分,会花比较大的篇幅来介绍清楚。

    上面的源码中没有展示消息发送和消息接收的处理,此部分灯塔君会在介绍完上面的这些内容以后再进行介绍。

    下面,将分块来介绍这些内容。鉴于读者对NIO或Netty的了解程度可能参差不齐,灯塔君为了照顾初学者很多地方需要啰嗦一些,所以希望读者一节一节往下看,对于自己熟悉的内容可以适当看快一些,敬请期待!

    365天干货不断,可以微信搜索「 猿灯塔」第一时间阅读,回复【资料】【面试】【简历】有我准备的一线大厂面试资料和简历模板

  • 相关阅读:
    MS CRM 2011的自定义和开发(10)——CRM web服务介绍(第一部分)——IDiscoveryService
    MS CRM 2011的自定义和开发(7)——视图编辑器(第二部分)
    MS CRM 2011 SDK 5.06版本已经发布
    MS CRM 2011的自定义和开发(11)——插件(plugin)开发(一)
    近来遇到的MS CRM 2011方面的几个问题
    MS CRM 2011的自定义与开发(6)——表单编辑器(第二部分)
    Microsoft Dynamics CRM 2011中,Lookup字段的赋值
    MS CRM 2011的自定义和开发(6)——表单编辑器(第三部分)
    Visual Studio 目标框架造成 命名空间“Microsoft”中不存在类型或命名空间名称“Crm”。是否缺少程序集引用中错误的处理
    一步步学习Reporting Services(二) 在报表中使用简单的参数作为查询条件
  • 原文地址:https://www.cnblogs.com/yuandengta/p/12758736.html
Copyright © 2011-2022 走看看