Netty学习记录

一、Netty简介

Netty 是一个基于 JAVA NIO 类库的异步通信框架,它的架构特点是:异步非阻塞、基于事件驱动、高性能、高可靠性和高可定制性。

Netty 是一个 NIO client-server(客户端服务器)框架,使用 Netty 可以快速开发网络应用,例如服务器和客户 端协议。 Netty 提供了一种新的方式来使开发网络应用程序,这种新的方式使得它很容易使用和有很强的扩展性。
Netty 是一个利用 Java 的高级网络的能力,隐藏其背后的复杂性而提供一个易于使用的 API 的客户端/服务器框架。
Netty 是一个广泛使用的 Java 网络编程框架。它活跃和成长于用户社区,像大型公司 Facebook 和 Instagram 以及流行 开源项目如 Infinispan, HornetQ, Vert.x, Apache Cassandra 和 Elasticsearch 等,都利用其强大的对于网络抽象的核心代码。

Hadoop的RPC框架avro使用Netty作为底层通信框架,很多其它业界主流的RPC框架 dubbo,也使用Netty来构建高性能的异步通信能力。

注意:网上很多资料说Netty是异步通信框架,应该是从编程模型的角度说的。java nio的io模型是同步非阻塞,这里的同步异步指的是真正io操作(数据内核态用户态的拷贝)是否需要用户进程参与。而说java nio提供了异步处理,这个异步应该是指编程模型上的异步。基于reactor模式的事件驱动,事件处理器的注册和处理器的执行是异步的。

Netty目前4.0的版本应该是“非阻塞”的“同步IO”(按照Unix IO模型定义)。之前曾经有版本支持“异步IO”(按照Unix IO模型定义),但是因为某些原因被后来版本移除了。不管Netty是“同步IO”还是“异步IO”(按照Unix IO模型定义),其实我们应用的层面是不需要区分的,因为这是框架底层封装处理。我们应该仅仅关心是我的业务客户端代码调用Netty的API时候客户端程序是否会停顿等待。
广义的异步,非阻塞,都可以直接理解为正在执行的线程“不停顿等待”.
作为普通应用开发者调用Netty的API,无非就是关心自己调用的API方法是否让自己的主线程停顿等待API执行结果,这种场景下是其实不需要考虑异步和非阻塞的区别的,叫异步也好,叫非阻塞也好。也就是广义的异步和非阻塞等同于”不停顿等待”。
首先,在Unix的IO模型里:

异步I/O 是指用户程序发起IO请求后,不等待数据,同时操作系统内核负责I/O操作把数据从内核拷贝到用户程序的缓冲区后通知应用程序。数据拷贝是由操作系统内核完成,用户程序从一开始就没有等待数据,发起请求后不参与任何IO操作,等内核通知完成。

同步I/O 就是非异步IO的情况,也就是用户程序要参与把数据拷贝到程序缓冲区(例如java的InputStream读字节流过程)。

同步IO里的非阻塞 是指用户程序发起IO操作请求后不等待数据,而是调用会立即返回一个标志信息告知条件不满足,数据未准备好,从而用户请求程序继续执行其它任务。执行完其它任务,用户程序会主动轮询查看IO操作条件是否满足,如果满足,则用户程序亲自参与拷贝数据动作。
Unix IO模型的语境下,同步和异步的区别在于数据拷贝阶段是否需要完全由操作系统处理。阻塞和非阻塞操作是针对发起IO请求操作后是否有立刻返回一个标志信息而不让请求线程等待。基于这个语境,Netty目前的版本是没有把IO操作交过操作系统处理的,所以是属于同步的。对于网上大部分文章,如果别人说Netty是异步非阻塞,如果要深究,那真要看看Netty新的版本是否把IO操作交过操作系统处理,或者看看有否使用JDK1.7中的AIO API,否则他们说的异步其实是指客户端程序调用Netty的IO操作API“不停顿等待”。

异步和非阻塞一样吗? (内容涉及BIO,NIO,AIO,Netty)

二、为什么要用Netty

不使用NIO的原因:

  1. NIO 的类库和 API 繁杂,使用麻烦,你需要熟练掌握 Selector、ServerSocketChannel 、SocketChannel、ByteBuffer 等。
  2. 使用 JAVA NIO 需要具备其他的额外技能做铺垫,例如熟悉 Java 多线程编程。这是因为 NIO 编程涉及到 Reactor 模式,你必须对多线程和网路编程非常熟悉,才能编写出高质量的 NIO 程序。
  3. JAVA NIO 的 ByteBuffer 构造函数私有,无法扩展。Netty 提供了自己的 ByteBuffer 实现,通过简单 APIs 对其进行构造、使用和操作,一此解决 NIO 的一些限制。
  4. 可靠性能力补齐,工作量和难度都非常大。例如客户端面临断连重连、网络闪断、半包读写、失败缓存、网络拥塞和异常码流的处理等问题。
  5. 跨平台与兼容性:NIO 算是底层的 APIs 需依赖系统的 IO APIs。但 Java NIO 发现在不同系统平台会出现问题。大量测试也耗不少时间;NIO2 只支持 JDK1.7+,而且没提供DatagramSocket,故 NIO2 不支持 UDP 协议。而 Netty 提供统一接口,同一语句无论在JDK6.X 还是 JDK7.X 都可运行,无需关心底层架构功能!
  6. JDK NIO 的 BUG,例如臭名昭著的epoll bug,它会导致 Selector 空轮询,最终导致CPU 100%。官方声称在 JDK 1.6 版本的update18 修复了该问题,但是直到 JDK 1.7版本该问题仍旧存在,只不过该 BUG 发生概率降低了一些而已,它并没有得到根本性解决。

用Netty的好处:

  • API使用简单,开发门槛低。
  • 功能强大,预置了多种编解码功能,支持多种协议开发。
  • 定制能力强,可以通过ChannelHadler进行扩展。
  • 性能高,对比其它NIO框架,Netty综合性能最优。
  • 经历了大规模的应用验证。在互联网、大数据、网络游戏、企业应用、电信软件得到成功,很多著名的框架通信底层就用了Netty,比如Dubbo
  • 稳定,修复了NIO出现的所有Bug。
  • 切换IO和NIO,因为IO和NIO的API完全不同,相互切换非常困难。

Netty介绍(一)————为什么使用Netty

三、Netty的版本

官网http://netty.io/ 最新版本如下:

不同版本的差异参考:https://stackoverflow.com/questions/30457648/different-netty-versions-and-their-purposes

3.x比较旧,5.x被废弃,主要选择是4.0和4.1。

3.x是过时的。我们维护它是因为一些用户仍然广泛使用它。
4是当前稳定版本。如果有疑问,请使用这个版本。
4.1是一个向后兼容的4版本。它添加了一些很酷的新特性,如HTTP / 2和异步DNS解析器。所以,当你的应用程序已经在4上运行时,你可能想要尝试4.1版本,你想试试新的特性。

《NETTY官方文档》4.0的新特性及注意点:http://ifeve.com/netty-4-0-new/
《NETTY官方文档》4.1的新特性及注意点:http://ifeve.com/new-and-noteworthy-in-4-1/

时间: 2024-10-13 17:38:34

Netty学习记录的相关文章

netty 学习记录一

最近在学习netty相关知识,觉得<netty 权威指南>这本书还是挺好的,适合我这种初学者.加上netty本身自带的许多例子,学起来还是挺有兴趣的.简单记录下, 一般服务器代码如下: public void run() throws Exception { EventLoopGroup bossGroup = new NioEventLoopGroup(); EventLoopGroup workerGroup = new NioEventLoopGroup(); try { ServerB

netty 学习记录二

netty 最新版本是netty-5.0.0.Alpha1,去年10月份发布的,至今没有发新版本,估计这个版本还是比较稳定. 整包下载,里面包含一个 netty-example-5.0.0.Alpha1-sources.jar文件,提供了比较丰富的example例子,多看几遍还是非常有收获的,这里记录下. 先来看下channelHandler的两个不同继承: 方式一:直接从ChannelHandlerAdapter类里继承,读取操作从channelRead方法里执行 @Sharable publ

netty学习记录2

昨天晚上在看到7.2章MessagePack编码器和解码器开发这一章时,书里面没有贴出全部的代码,然后我按照我自己的想法把代码补全后,发现死活没有把代码跑通. 然后花了挺多时间在网上找,很多博客都贴出了这一节的代码,但是基本上都是把书上有的给贴出来了,严重怀疑他们敲完代码后有没有跑一遍. 不过最后还是找到了一个博客里面贴全了代码,发现是UserInfo类里面缺了一个注解@Message导致代码没跑通的. Netty使用MessagePack首先自定义编解码器 下面贴上全部代码 UserInfo.

Python学习记录-2016-12-17

今日学习记录 模块: import os#导入os模块 import sys#导入sys模块 os.system("df -h")#执行df -h命令 cmd_res = os.popen("df -h").read()#将命令的返回结果赋值给cmd_res,如果不加入.read()会显示命令的返回加过在内存的位置 print(sys.path)#显示系统变量路径,一般个人模块位于site-packages下,系统模块位于lib下 print(sys.argu[2]

Objc基础学习记录5

NSMutableString类继承的NSString类. NSMutableString是动态的字符串. 1.appendingString 方式: 向字符串尾部添加一个字符串. 2.appendingFormat:可以添加多个类型的字符串. int,chat float,double等 3.stringWithString 创建字符串, 4.rangeOfString 返回str1在另一个字符串中的位置. 5.NSMakeRange(0,3) 字符串0位到3位. 6.deleteCharac

Windows API 编程学习记录&lt;二&gt;

恩,开始写Windows API编程第二节吧. 上次介绍了几个关于Windows API编程最基本的概念,但是如果只是看这些概念,估计还是对Windows API不是很了解.这节我们就使用Windows API 让大家来了解下Windows API的用法. 第一个介绍的Windows API 当然是最经典的MessageBox,这个API 的作用就是在电脑上显示一个对话框,我们先来看看这个API的定义吧: int WINAPI MessageBox(HWND hWnd, LPCTSTR lpTe

Windows API 编程学习记录&lt;三&gt;

恩,开始写API编程的第三节,其实马上要考试了,但是不把这节写完,心里总感觉不舒服啊.写完赶紧去复习啊       在前两节中,我们介绍了Windows API 编程的一些基本概念和一个最基本API函数 MessageBox的使用,在这节中,我们就来正式编写一个Windows的窗口程序. 在具体编写代码之前,我们必须先要了解一下API 编写窗口程序具体的三个基本步骤:             1. 注册窗口类:             2.创建窗口:             3.显示窗口: 恩,

Python学习记录day6

Python学习记录day6 学习 python Python学习记录day6 1.反射 2.常用模块 2.1 sys 2.2 os 2.3 hashlib 2.3 re 1.反射 反射:利用字符串的形式去对象(默认)中操作(寻找)成员 cat commons.py #!/usr/bin/env python#_*_coding:utf-8_*_''' * Created on 2016/12/3 21:54. * @author: Chinge_Yang.''' def login(): pr

Python学习记录-2016-11-29

今日学习记录: 心灵鸡汤: 要有合适自己的目标,一个目标一个目标实现,切忌好高骛远: 最好的投资就是投资自己: 实现梦想 学习,学习,再学习: Talk is cheap. 从本身而言,余三十而立之年,从事测试行业7七年有余,一年半华为外包路由器,两年无线wifi测试,一年半网管软件测试,一年自动化测试经理,推行公司自动化测试进程,从开始的TCL,到现在的python,工欲善其事必先利其器,所以自己来学习,总体我认为我的目标是一直前进的,不断变化的,但是方向并没有大的错误,有些累,所以近期有些懈