Netty is an asynchronous event-driven network application framework for rapid development of maintainable high performance protocol servers & clients.
在看微博开源的rpc框架motan的过程中,了解到其使用了Netty构建客户和服务端,为了理解motan的源码于是找了Netty的相关书籍,其中之一就是《Netty In Action》,该书作者之一就是Netty的主力开发人员之一Norman Maurer。
书主要分为四个部分:
- Netty概念和架构:提供了简单点示例,介绍了组件及其设计和架构
- Codecs:详细介绍了编码和解码的实现
- 网络协议:WebSocket和UDP
- 案例研究:Droply, Firebase, Urban Airship, Nifty, Swift和Fiangle
读完全书,对于Netty有了个基本的了解,可以尝试用其开发异步的网络服务例如企业自己的rpc框架,或者提供一些异步的高性能服务。
接下来把书中的内容做个梳理和介绍。
组件和架构
Netty组件包括如下几个类型:
- Channel: 通道,表示到一些实体例如网络socket和文件的连接,通过它能执行I/O操作,比如读和写。生命周期中状态转换依次为:Unregistered (已创建未和注册到EventLoop),Registered(注册到EventLoop),Active(已连接到远程,可以接收和发送数据)和Inactive(断开连接)。
A Channel is a basic construct of Java NIO, it represents an open connection to an entity such as a hardware device, a file, a network socket, or a program component that is capable of performing one or more distinct I/O operations, for example reading or writing.
- EventLoop & EventLoopGroup:一个EventLoopGroup包含一个或多个EventLoop,EventLoop通过一个线程处理所有的I/O事件,其被委派给一个或者多个Channel,一个Channel在其生命周期内只注册到一个的EventLoop。
https://en.wikipedia.org/wiki/Event_loop: the event loop, message dispatcher, message loop, message pump, or run loop is a programming construct that waits for and dispatches events or messages in a program.
ChannelFuture:注册监听器到异步的I/O操作,操作完成时监听器将被通知到。
ChannelHandler & ChannelHandlerContext:处理进入和输出的数据,有多种类型的handler。
ChannelPipeline:每一个Channel都会关联到一个ChannelPipeline,一个Channel一个ChannelPipeline其包含多个ChannelHandler,一个事件经过pipeline时里面所有的handler都会被按照加入顺序执行来处理事件。
BootStrap and ServerBootStrap:Bootstrap用来连接远程主机,有1个EventLoopGroup;ServerBootstrap用来绑定本地端口,有2个EventLoopGroup:一个与server自己的监听socket关联,对于所有进入的request创建channel,一个用来处理创建好的channel,分派EventLoop给channel。
一些功能
ByteBuf - Netty的数据容器
数据容器,用于数据的读写,ByteBuf有两种使用模式:堆缓冲区(HEAP BUFFERS:copy and write),直接缓冲(DIRECT BUFFER:zero copy)和组合缓冲(COMPOSITE BUFFERS: aggregate to avoid concating by copying multiple buffers),第一种在JVM的堆存储数据,第二种是在堆外存储,最后一种是在聚合多个不同的ByteBuff。Netty提供了allocator分配池化的ByteBuf以便更好的利用内存,同时也提供了非池化的实现。
编解码(Codec)
Codec组件包括encoder和decoder,是Netty的一个重要组成部分,用来做数据转换在网络传输和应用数据,重用比如有ByteToMessageDecoder,MessageToMessageDecoder,MessageToByteEncoder,MessageToMessageEncoder或ByteToMessageCodec和MessageToMessageCodec其同时包含decode和encode。Codec是pipeline的一部分,与其他handler一起顺序执行,例如对于输入的数据先decode然后送到后续的handler。
安全
- SSL/TSL/HTTPS:利用SslHandler,SslEngine和SSLEngine来加密和解密数据。
传输和不同协议的支持
- WebSocket
- UDP
- MQTT
- Protocol Buffer
- Thrift
具体实现和案例
客户端实现注意事项
- Channel的长链接和重用?例如像motan用apache的object pool缓存channel
- 如何配置和发现服务?ZooKeeper或Consul或者其他?
- 心跳实现?
- 数据传输的安全性?
服务端实现注意事项
- 如何注册服务?ZooKeeper或Consul或者其他?
- 使用线程池来处理request
- 降级开关
- 调用统计和监控
motan是一个很好的参看,架构清晰,代码模块化,简单明了和测试也比较全面。