前言:不断学习就是程序员的宿命
第一次听说Netty是在大学期间,当时对它并没有太大的兴趣,直到现在工作看到公司自研网关源码时,才渐渐觉得这是我必须得去了解的一个技术了,不然真的看不下去公司大牛写的网关源码(技术栈:SpringBoot+Disconf+Netty+HSF),看了网上很多教程,其中大部分还是参考http://www.iocoder.cn/,学习到很多,虽然目前没有机会去施展,但需要沉淀下来,记录下来。
Netty介绍就不扯淡了,到处都是。
一、Socket入门案例
1、服务端
1.1服务端启动类
1.2服务端--Server类
1.3服务端IO处理类-ClientHandler
分析:
①ServerBoot启动类main方法中new Server(port)通过构造方法传入端口并绑定
②Server实例通过start方法启动服务端,start()方法中开启子线程用于端口监听客户端连接(不希望阻塞主线程)
③start()方法子线程调用doStart()方法做真正客户端连接,每当监听到客户端连接,将该连接丢给ClientHandler类来处理
④ClientHandler类start()方法对于每一个新连入的客户端都会开启子线程来进行IO操作
2、客户端
分析 :
①客户端new Socket()绑定ip和端口
②开启子线程处理IO操作(不希望阻塞主线程)
3、总体分析
①服务端监听端口
②服务端while(true)循环不断accept客户端连接
③客户端发送数据,服务端接收数据
④当新客户端接入时,服务端拿到这个连接扔给一个处理器(ClientHandler)来处理IO操作,对应上图业务处理
⑤服务端将数据写回客户端
ps:自我感觉,这个小demo更有助于理解reactor线程模型,感兴趣的可以下载看看大师Doug Lea的经典文章链接如下:
http://gee.cs.oswego.edu/dl/cpjslides/nio.pdf
二、Netty对应Socket的抽象
Netty基于上述过程,抽象出一系列组件。
1、监听端口
在上述demo中有以下2层含义:
①服务端在某一个端口上不断监听新用户的连接
②新用户建立完成连接之后,在对应端口上不断监听新连接的数据
此部分对应Netty的NioEventLoop(字面意思NiO事件循环)主要包括:
①新连接的接入
②连接当前存在连接上数据流的读写
2、新连接
在IO编程模型中,新连接在java底层是一个Socket,在Nio编程模型中对应SocketChannel,而在Netty中把这个连接统一封装成自定义Channel,基于这个Channel,一系列的读写都可以在这个Channel上操作(实际上就对Socket的抽象)
3、接收(发送)数据(对应Netty-ByteBuf)
服务端接收接收用户数据流的载体,ByteBuf的api可以跟底层数据流进行通信
4、业务逻辑(对应Netty-ChannelHandler)
当用户数据流到达服务端后,服务端进行业务处理(demo中ClientHandler处理比较简单)。
通常情况下,服务端与客户端通信时,一般都会自定义二进制协议,首先需要对二进制协议数据包的拆分,对应不同类型协议数据包都对应不同的java对象,然后读取字节转化成java自定义对象,接着对不同java对象都要做不同的处理,这个过程通常在生产过程中是非常复杂的,而有了Netty之后,netty把每个过程都定义为ChannelHandler(比如第一步数据包拆分,对应Netty中的分包器;然后对每个类型数据包都要进行java对象转换扔到不同处理器去处理,用户可以定义不同的ChannelHandler来处理不同的对象,处理完成之后,Netty对对应数据进行写回客户端,写出的数据流也是基于ByteBuf) 。
重点这里包含一系列数据处理的流程,可以把它当成逻辑链(数据过来后--拆包--对象转换--逻辑处理--封包--写回客户端),Netty把这一连串的逻辑给它串起来,抽象出一个对象叫做PipeLine(底层就是一系列的ChannelHandler),有了PipeLine之后,用户可以动态进行一些逻辑的增加、修改、删除,编程起来非常方便