作为一个学Java的,如果没有研究过Netty,那么你对Java语言的使用和理解仅仅停留在表面水平,会点SSH,写几个MVC,访问数据库和缓存,这些只是初等Java程序员干的事。如果你要进阶,想了解Java服务器的深层高阶知识,Netty绝对是一个必须要过的门槛。

有了Netty,你可以实现自己的HTTP服务器,FTP服务器,UDP服务器,RPC服务器,WebSocket服务器,Redis的Proxy服务器,MySQL的Proxy服务器等等。

如果你想知道Nginx是怎么写出来的,如果你想知道Tomcat和Jetty是如何实现的,如果你也想实现一个简单的Redis服务器,那都应该好好理解一下Netty,它们高性能的原理都是类似的。

我们回顾一下传统的HTTP服务器的原理

  1. 创建一个ServerSocket,监听并绑定一个端口
  2. 一系列客户端来请求这个端口
  3. 服务器使用Accept,获得一个来自客户端的Socket连接对象
  4. 启动一个新线程处理连接
    1. 读Socket,得到字节流
    2. 解码协议,得到Http请求对象
    3. 处理Http请求,得到一个结果,封装成一个HttpResponse对象
    4. 编码协议,将结果序列化字节流
    5. 写Socket,将字节流发给客户端
  5. 继续循环步骤3

HTTP服务器之所以称为HTTP服务器,是因为编码解码协议是HTTP协议,如果协议是Redis协议,那它就成了Redis服务器,如果协议是WebSocket,那它就成了WebSocket服务器,等等。

使用Netty你就可以定制编解码协议,实现自己的特定协议的服务器。

上面我们说的是一个传统的多线程服务器,这个也是Apache处理请求的模式。在高并发环境下,线程数量可能会创建太多,操作系统的任务调度压力大,系统负载也会比较高。那怎么办呢?

于是NIO诞生了,NIO并不是Java独有的概念,NIO代表的一个词汇叫着IO多路复用。它是由操作系统提供的系统调用,早期这个操作系统调用的名字是select,但是性能低下,后来渐渐演化成了Linux下的epoll和Mac里的kqueue。我们一般就说是epoll,因为没有人拿苹果电脑作为服务器使用对外提供服务。而Netty就是基于Java NIO技术封装的一套框架。为什么要封装,因为原生的Java NIO使用起来没那么方便,而且还有臭名昭著的bug,Netty把它封装之后,提供了一个易于操作的使用模式和接口,用户使用起来也就便捷多了。

那NIO究竟是什么东西呢?

NIO的全称是NoneBlocking IO,非阻塞IO,区别与BIO,BIO的全称是Blocking IO,阻塞IO。那这个阻塞是什么意思呢?

  1. Accept是阻塞的,只有新连接来了,Accept才会返回,主线程才能继
  2. Read是阻塞的,只有请求消息来了,Read才能返回,子线程才能继续处理
  3. Write是阻塞的,只有客户端把消息收了,Write才能返回,子线程才能继续读取下一个请求

所以传统的多线程服务器是BlockingIO模式的,从头到尾所有的线程都是阻塞的。这些线程就干等在哪里,占用了操作系统的调度资源,什么事也不干,是浪费。

那么NIO是怎么做到非阻塞的呢。它用的是事件机制。它可以用一个线程把Accept,读写操作,请求处理的逻辑全干了。如果什么事都没得做,它也不会死循环,它会将线程休眠起来,直到下一个事件来了再继续干活,这样的一个线程称之为NIO线程。

while true {
events = takeEvents(fds) // 获取事件,如果没有事件,线程就休眠
for event in events {
if event.isAcceptable {
doAccept() // 新链接来了
} elif event.isReadable {
request = doRead() // 读消息
if request.isComplete() {
doProcess()
}
} elif event.isWriteable {
doWrite() // 写消息
}
}
}

NIO的流程大致就是上面的伪代码描述的过程,跟实际真实的代码有较多差异,不过对于初学者,这样理解也是足够了。

Netty是建立在NIO基础之上,Netty在NIO之上又提供了更高层次的抽象。

在Netty里面,Accept连接可以使用单独的线程池去处理,读写操作又是另外的线程池来处理。

Accept连接和读写操作也可以使用同一个线程池来进行处理。而请求处理逻辑既可以使用单独的线程池进行处理,也可以跟放在读写线程一块处理。线程池中的每一个线程都是NIO线程。用户可以根据实际情况进行组装,构造出满足系统需求的并发模型。

Netty提供了内置的常用编解码器,包括行编解码器[一行一个请求],前缀长度编解码器[前N个字节定义请求的字节长度],可重放解码器[记录半包消息的状态],HTTP编解码器,WebSocket消息编解码器等等

Netty提供了一些列生命周期回调接口,当一个完整的请求到达时,当一个连接关闭时,当一个连接建立时,用户都会收到回调事件,然后进行逻辑处理。

Netty可以同时管理多个端口,可以使用NIO客户端模型,这些对于RPC服务是很有必要的。

Netty除了可以处理TCP Socket之外,还可以处理UDP Socket。

在消息读写过程中,需要大量使用ByteBuffer,Netty对ByteBuffer在性能和使用的便捷性上都进行了优化和抽象。

总之,Netty是Java程序员进阶的必备神奇。如果你知其然,还想知其所以然,一定要好好研究下Netty。如果你觉得Java枯燥无谓,Netty则是重新开启你对Java兴趣大门的钥匙。

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

1)本质:JBoss做的一个Jar包

2)目的:快速开发高性能、高可靠性的网络服务器和客户端程序

3)优点:提供异步的、事件驱动的网络应用程序框架和工具

通俗的说:一个好使的处理Socket的东东

如果没有Netty?

远古:

java.net + java.io

近代:

java.nio

其他:

Mina,Grizzly

与Mina相比有什么优势?

1、都是Trustin Lee的作品,Netty更晚;

2、Mina将内核和一些特性的联系过于紧密,使得用户在不需要这些特性的时候无法脱离,相比下性能会有所下降,Netty解决了这个设计问题;

3、Netty的文档更清晰,很多Mina的特性在Netty里都有;

4、Netty更新周期更短,新版本的发布比较快;

5、它们的架构差别不大,Mina靠apache生存,而Netty靠jboss,和jboss的结合度非常高,Netty有对google protocal buf的支持,有更完整的ioc容器支持(spring,guice,jbossmc和osgi);

6、Netty比Mina使用起来更简单,Netty里你可以自定义的处理upstream events 或/和 downstream events,可以使用decoder和encoder来解码和编码发送内容;

7、Netty和Mina在处理UDP时有一些不同,Netty将UDP无连接的特性暴露出来;而Mina对UDP进行了高级层次的抽象,可以把UDP当成"面向连接"的协议,而要Netty做到这一点比较困难。

-----------------------------------------------------------------------------------------------------------------------------------------

Netty的特性

1)设计

统一的API,适用于不同的协议(阻塞和非阻塞)

基于灵活、可扩展的事件驱动模型

高度可定制的线程模型

可靠的无连接数据Socket支持(UDP)

2)性能

更好的吞吐量,低延迟

更省资源

尽量减少不必要的内存拷贝

3)安全

完整的SSL/TLS和STARTTLS的支持

能在Applet与Android的限制环境运行良好

4)健壮性

不再因过快、过慢或超负载连接导致OutOfMemoryError

不再有在高速网络环境下NIO读写频率不一致的问题

5)易用

完善的JavaDoc,用户指南和样例

简洁简单

仅信赖于JDK1.5

-------------------------------------------------------------------------------------------------------------------------------------------

Netty 在哪些行业得到了应用?

  • 互联网行业:随着网站规模的不断扩大,系统并发访问量也越来越高,传统基于 Tomcat 等 Web 容器的垂直架构已经无法满足需求,需要拆分应用进行服务化,以提高开发和维护效率。从组网情况看,垂直的架构拆分之后,系统采用分布式部署,各个节点之间需要远程服务调用,高性能的 RPC 框架必不可少,Netty 作为异步高性能的通信框架,往往作为基础通信组件被这些 RPC 框架使用。

  典型的应用有:阿里分布式服务框架 Dubbo 的 RPC 框架使用 Dubbo 协议进行节点间通信,Dubbo 协议默认使用 Netty 作为基础通信组件,用于实现各进程节点之间的内部通信。它的架构图如下:

<img src="https://pic4.zhimg.com/50/0033448fdced8b3c3897e1a41b4dfa10_hd.jpg" data-rawwidth="533" data-rawheight="356" class="origin_image zh-lightbox-thumb" width="533" data-original="https://pic4.zhimg.com/0033448fdced8b3c3897e1a41b4dfa10_r.jpg">

其中,服务提供者和服务消费者之间,服务提供者、服务消费者和性能统计节点之间使用 Netty 进行异步/同步通信。

  除了 Dubbo 之外,淘宝的消息中间件 RocketMQ 的消息生产者和消息消费者之间,也采用 Netty 进行高性能、异步通信。

  除了阿里系和淘宝系之外,很多其它的大型互联网公司或者电商内部也已经大量使用 Netty 构建高性能、分布式的网络服务器。

  • 游戏行业:无论是手游服务端、还是大型的网络游戏,Java 语言得到了越来越广泛的应用。Netty 作为高性能的基础通信组件,它本身提供了 TCP/UDP 和 HTTP 协议栈,非常方便定制和开发私有协议栈。账号登陆服务器、地图服务器之间可以方便的通过 Netty 进行高性能的通信,架构示意图如下:

  图1-2 Netty 在游戏服务器架构中的应用

  • 大数据领域:经典的 Hadoop 的高性能通信和序列化组件 Avro 的 RPC 框架,默认采用 Netty 进行跨节点通信,它的 Netty Service 基于 Netty 框架二次封装实现。

  大数据计算往往采用多个计算节点和一个/N个汇总节点进行分布式部署,各节点之间存在海量的数据交换。由于 Netty 的综合性能是目前各个成熟 NIO 框架中最高的,因此,往往会被选中用作大数据各节点间的通信。

  • 企业软件:企业和 IT 集成需要 ESB,Netty 对多协议支持、私有协议定制的简洁性和高性能是 ESB RPC 框架的首选通信组件。事实上,很多企业总线厂商会选择 Netty 作为基础通信组件,用于企业的 IT 集成。

  • 通信行业:Netty 的异步高性能、高可靠性和高成熟度的优点,使它在通信行业得到了大量的应用。

Netty 能做什么的更多相关文章

  1. 【Netty】通俗地讲,Netty 能做什么?

    作者:郭无心链接:https://www.zhihu.com/question/24322387/answer/78947405来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明 ...

  2. 通俗地讲,Netty 能做什么?

    https://www.zhihu.com/question/24322387/answer/78947405 作者:郭无心链接:https://www.zhihu.com/question/2432 ...

  3. netty同时做http和websocket(netty入门)

    ---恢复内容开始--- http://www.jianshu.com/p/5c29c6c6d28c ---恢复内容结束--- http://www.jianshu.com/p/5c29c6c6d28 ...

  4. 基于Java Netty框架构建高性能的部标808协议的GPS服务器

    使用Java语言开发一个高质量和高性能的jt808 协议的GPS通信服务器,并不是一件简单容易的事情,开发出来一段程序和能够承受数十万台车载接入是两码事,除去开发部标808协议的固有复杂性和几个月长周 ...

  5. Netty权威指南

    Netty权威指南(异步非阻塞通信领域的经典之作,国内首本深入剖析Netty的著作,全面系统讲解原理.实战和源码,带你完美进阶Netty工程师.) 李林锋 著   ISBN 978-7-121-233 ...

  6. Java NIO框架Netty教程(一) – Hello Netty

    先啰嗦两句,如果你还不知道Netty是做什么的能做什么.那可以先简单的搜索了解一下.我只能说Netty是一个NIO的框架,可以用于开发分布式的Java程序.具体能做什么,各位可以尽量发挥想象.技术,是 ...

  7. Netty之ChannelOption

    一.概述 最近在写一个分布式服务框架,打算用netty框架做底层网络通信,关于netty的学习可以参考如下资料: http://blog.csdn.net/column/details/enjoyne ...

  8. 对于Netty的十一个疑问(转)

    [说明]本文原载于码农 IO(manong.io)官方微信 developerWorks,转载.引用请注明出处及作者. 1.Netty 是什么? Netty 是一个基于 JAVA NIO 类库的异步通 ...

  9. Netty(7)源码-ByteBuf

    一.ByteBuf工作原理 1. ByteBuf是ByteBuffer的升级版: jdk中常用的是ByteBuffer,从功能角度上,ByteBuffer可以完全满足需要,但是有以下缺点: ByteB ...

随机推荐

  1. [java,2018-01-16] HttpClient发送、接收 json 请求

    最近需要用到许多在后台发送http请求的功能,可能需要发送json和xml类型的数据. 就抽取出来写了一个帮助类: 首先判断发送的数据类型是json还是xml: import org.dom4j.Do ...

  2. 重新配置dbconsole的步骤

    重新配置dbconsole的步骤emca -repos dropemca -repos createemca -config dbcontrol dbemctl start dbconsole

  3. Python :数据结构

    LearnPython :数据结构 .caret, .dropup > .btn > .caret { border-top-color: #000 !important; } .labe ...

  4. Java序列化对象-字符串转换

    package com.test; import com.alibaba.fastjson.JSON; import org.junit.Test; import java.io.ByteArrayI ...

  5. 配置Eclipse的Maven环境

  6. kvm虚拟机相关

    一.虚拟机与宿主机鼠标不同步问题: https://blog.csdn.net/u012255731/article/details/53006195 先关闭虚拟机,想要修改鼠标和宿主机界面同步方法如 ...

  7. RxJava学习(一)——简介及其优势

    参考:给 Android 开发者的 RxJava 详解 RxJava是什么 RxJava 在 GitHub 主页上的自我介绍是 "a library for composing asynch ...

  8. leetcode153

    class Solution: def findMin(self, nums: 'List[int]') -> int: l = 0 h = len(nums)-1 while l < h ...

  9. Oracle表复杂查询

    转自:https://www.cnblogs.com/w-gao/p/7288293.html Oracle表复杂查询 聚合函数 max(字段值)  -- 求最大值 min(字段值)  -- 求最小值 ...

  10. JAVA版开源微信管家—JeeWx捷微3.1小程序版本发布,支持微信公众号,微信企业号,支付窗

    支持小程序,JeeWx捷微3.1小程序版本发布^_^ JeeWx捷微V3.1--多触点小程序版本管理平台(支持微信公众号,微信企业号,支付窗) JeeWx捷微V3.1.0版本紧跟微信小程序更新,在原有 ...