netty系列之:netty架构概述
简介
Netty为什么这么优秀,它在JDK本身的NIO基础上又做了什么改进呢?它的架构和工作流程如何呢?请走进今天的netty系列文章之:netty架构概述。
netty架构图
netty的主要作用就是提供一个简单的NIO框架可以和上层的各种协议相结合,最终实现高性能的服务器。下面是netty官网提供的架构图:

从上图可以看到netty的核心主要分成三部分,分别是可扩展的event model、统一的API、和强大的Byte Buffer。这三个特性是netty的制胜法宝。
下面会从这几个方面对netty的特性进行详细说明,务必让读者了解到netty的优秀之处。
丰富的Buffer数据机构
首先从最底层的Buffer数据结构开始,netty提供了一个io.netty.buffer的包,该包里面定义了各种类型的ByteBuf和其衍生的类型。
netty Buffer的基础是ByteBuf类,这是一个抽象类,其他的Buffer类基本上都是由该类衍生而得的,这个类也定义了netty整体Buffer的基调。
netty重写ByteBuf其目的是让最底层的ByteBuf比JDK自带的更快更适合扩展。具体而言,netty的ByteBuf要比JDK中的ByteBuffer要快,同时,扩展也更加容易,大家可以根据需要Buf进行自定义。另外netty有一些内置的复合缓冲区类型,所以可以实现透明的零拷贝。对于动态缓冲区类型来说,可以和StringBuffer一样按需扩展,非常好用。
零拷贝
什么是零拷贝呢?零拷贝的意思是在需要拷贝的时候不做拷贝。我们知道数据在使用底层协议进行传输的过程中是会被封装成为一个个的包进行传输。当传输的数据过大,一个包放不下的时候,还需要对数据进行拆分,目的方在接收到数据之后,需要对收到的数据进行组装,一般情况下这个组装的操作是对数据的拷贝,将拆分过后的对象拷贝到一个长的数据空间中。
比如下面的例子所示,将底层的TCP包组合称为顶层的HTTP包,但是并没有进行拷贝:

具体怎么拷贝呢?在上一篇文章中,我们知道netty提供了一个工具类方法Unpooled,这个工具类中有很多wrapped开头的方法,我们举几个例子:
public static ByteBuf wrappedBuffer(byte[]... arrays) {
return wrappedBuffer(arrays.length, arrays);
}
public static ByteBuf wrappedBuffer(ByteBuf... buffers) {
return wrappedBuffer(buffers.length, buffers);
}
public static ByteBuf wrappedBuffer(ByteBuffer... buffers) {
return wrappedBuffer(buffers.length, buffers);
}
上面三个方法分别是封装byte数组、封装ByteBuf和封装ByteBuffer,这些方法都是零拷贝。大家可以在实际的项目中根据实际情况,自行选用。
统一的API
一般来说,在传统的JDK的IO API中,根据传输类型或者协议的不同,使用的API也是不同的。我们需要对不同的传输方式开发不同的应用程序,不能做到统一。这样的结果就是无法平滑的迁移,并且在程序扩展的时候需要进行额外的处理。
什么是传输方式呢?这里是指以什么样的方式来实现IO,比如传统的阻塞型IO,我们可以称之为OIO,java的new IO可以称之为NIO,异步IO可以称之为AIO等等。
并且JDK中的传统IO和NIO是割裂的,如果在最开始你使用的是传统IO,那么当你的客户数目增长到一定的程度准备切换到NIO的时候,就会发现切换起来异常复杂,因为他们是割裂的。
为了解决这个问题,netty提供了一个统一的类Channel来提供统一的API。
先看下Channel中定义的方法:

从上图我们可以看到使用Channel可以判断channel当前的状态,可以对其进行参数配置,可以对其进行I/O操作,还有和channel相关的ChannelPipeline用来处理channel关联的IO请求和事件。
使用Channel就可以对NIO的TCP/IP,OIO的TCP/IP,OIO的UDP/IP和本地传输都能提供很好的支持。
传输方式的切换,只需要进行很小的成本替换。
当然,如果你对现有的实现都不满意的话,还可以对核心API进行自定义扩展。
事件驱动
netty是一个事件驱动的框架,事件驱动框架的基础就是事件模型,Netty专门为IO定义了一个非常有效的事件模型。可以在不破坏现有代码的情况下实现自己的事件类型。netty中自定义的事件类型通过严格的类型层次结构跟其他事件类型区分开来,所以可扩展性很强。
netty中的事件驱动是由ChannelEvent、ChannelHandler和ChannelPipeline共同作用的结果。其中ChannelEvent表示发生的事件,ChannelHandler定义了如何对事件进行处理,而ChannelPipeline类似一个拦截器,可以让用户自行对定义好的ChannelHandler进行控制,从而达到控制事件处理的结果。
我们看一个简单的自定义Handler:
public class MyHandler extends SimpleChannelInboundHandler<Object> {
@Override
public void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception {
// 对消息进行处理
ByteBuf in = (ByteBuf) msg;
try {
log.info("收到消息:{}",in.toString(io.netty.util.CharsetUtil.US_ASCII));
}finally {
ReferenceCountUtil.release(msg);
}
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
//异常处理
cause.printStackTrace();
ctx.close();
}
}
上面的例子中,我们定义了如何对接收到的消息和异常进行处理。在后续的文章中我们会详细对ChannelEvent、ChannelHandler和ChannelPipeline之间的交互使用进行介绍。
其他优秀的特性
除了上面提到的三大核心特性之外,netty还有其他几个优点,方便程序员的开发工作。
比如对SSL / TLS的支持,对HTTP协议的实现,对WebSockets 实现和Google Protocol Buffers的实现等等,表明netty在各个方面多个场景都有很强的应用能力。
总结
netty是由三个核心组件构成:缓冲区、通道和事件模型,通过理解这三个核心组件是如何相互工作的,那么再去理解建立在netty之上的高级功能就不难了。
本文的例子可以参考:learn-netty4
本文已收录于 http://www.flydean.com/03-netty-architecture/
最通俗的解读,最深刻的干货,最简洁的教程,众多你不知道的小技巧等你来发现!
欢迎关注我的公众号:「程序那些事」,懂技术,更懂你!
netty系列之:netty架构概述的更多相关文章
- 【读后感】Netty 系列之 Netty 高性能之道 - 相比 Mina 怎样 ?
[读后感]Netty 系列之 Netty 高性能之道 - 相比 Mina 怎样 ? 太阳火神的漂亮人生 (http://blog.csdn.net/opengl_es) 本文遵循"署名-非商 ...
- Netty 系列之 Netty 高性能之道 高性能的三个主题 Netty使得开发者能够轻松地接受大量打开的套接字 Java 序列化
Netty系列之Netty高性能之道 https://www.infoq.cn/article/netty-high-performance 李林锋 2014 年 5 月 29 日 话题:性能调优语言 ...
- Netty 系列之 Netty 高性能之道
1. 背景 1.1. 惊人的性能数据 最近一个圈内朋友通过私信告诉我,通过使用 Netty4 + Thrift 压缩二进制编解码技术,他们实现了 10 W TPS(1 K 的复杂 POJO 对象)的跨 ...
- Netty系列之Netty高性能之道
转载自http://www.infoq.com/cn/articles/netty-high-performance 1. 背景 1.1. 惊人的性能数据 最近一个圈内朋友通过私信告诉我,通过使用Ne ...
- 转:Netty系列之Netty高性能之道
1. 背景 1.1. 惊人的性能数据 最近一个圈内朋友通过私信告诉我,通过使用Netty4 + Thrift压缩二进制编解码技术,他们实现了10W TPS(1K的复杂POJO对象)的跨节点远程服务调用 ...
- Netty系列之Netty百万级推送服务设计要点
1. 背景 1.1. 话题来源 最近很多从事移动互联网和物联网开发的同学给我发邮件或者微博私信我,咨询推送服务相关的问题.问题五花八门,在帮助大家答疑解惑的过程中,我也对问题进行了总结,大概可以归纳为 ...
- 【netty】Netty系列之Netty百万级推送服务设计要点
1. 背景 1.1. 话题来源 最近很多从事移动互联网和物联网开发的同学给我发邮件或者微博私信我,咨询推送服务相关的问题.问题五花八门,在帮助大家答疑解惑的过程中,我也对问题进行了总结,大概可以归纳为 ...
- Netty系列之Netty线程模型
Reference: http://www.infoq.com/cn/articles/netty-threading-model 1. 背景 1.1. Java线程模型的演进 1.1.1. 单线程 ...
- Netty系列之Netty百万级推送服务设计要点(转)
1. 背景 1.1. 话题来源 最近很多从事移动互联网和物联网开发的同学给我发邮件或者微博私信我,咨询推送服务相关的问题.问题五花八门,在帮助大家答疑解惑的过程中,我也对问题进行了总结,大概可以归纳为 ...
随机推荐
- OO unit3 summary
Unit3 JML(Java Modeling Language) 是用于对 Java 程序进行规格化设计的一种表示语言,它对于方法内部具体是如何实现的并无要求,只是对方法的接口以及行为进行限制, ...
- 每日三道面试题,通往自由的道路4——JVM篇
茫茫人海千千万万,感谢这一秒你看到这里.希望我的面试题系列能对你的有所帮助!共勉! 愿你在未来的日子,保持热爱,奔赴山海! 每日三道面试题,成就更好自我 昨天既然你有讲到字符串常量池是吧,那这样吧 1 ...
- 【带你手撸Spring】没有哪个框架开发,能离开 Spring 的 FactoryBean!
作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 老司机,你的砖怎么搬的那么快? 是有劲?是技巧?是后门?总之,那个老司机的代码总是可 ...
- ES6 数组的方法
数组的类 数组的类是Array 数组的定义 var arr=[元素] var arr=new Array(3) 数字3,代表有三个元素或者三个空位 如果数组定义采用 new 实例,类中跟的是一个数字 ...
- Local dimming algorithm in matlab
LED局部背光算法的matlab仿真 最近公司接了华星光电(TCL)的一个项目LCD-BackLight-Local-Diming-Algorithm-IP ,由于没有实际的硬件,只能根据客户给的论文 ...
- drf-序列化器serializer
目录 一.序列化器-serializer 二.序列化器的使用 简单使用 高级使用 source **SerializerMethodField( ) ** 通用参数 三.反序列化数据校验 字段属性 局 ...
- DDoS防护方式以及产品
导航: 这里将一个案例事项按照流程进行了整合,这样查看起来比较清晰.部分资料来自于Cloudflare 1.DDoS介绍 2.常用DDoS攻击 3.DDoS防护方式以及产品 4.Cloudflare ...
- 模拟windows10计算器的实现
用户界面部分: import java.awt.*; import java.awt.event.*; import java.io.*; import java.util.HashMap; impo ...
- iOS工程师如何恍然大悟?
聊聊行情?为什么总有人在乎旁人的看法而忽略自己的初衷? 虽然iOS开发市场说不上好但也绝不算坏,想没想过那些煽风点火说iOS不行的人在做什么? 真的转行从头开始? 错.大错特错! 在劝退你的同时他们会 ...
- LeetCode解题记录(贪心算法)(一)
1. 前言 目前得到一本不错的算法书籍,页数不多,挺符合我的需要,于是正好借这个机会来好好的系统的刷一下算法题,一来呢,是可以给部分同学提供解题思路,和一些自己的思考,二来呢,我也可以在需要复习的时候 ...