作者:老钱
链接:https://www.zhihu.com/question/24322387/answer/282001188

有了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你就可以定制编解码协议,实现自己的特定协议的服务器。

NIO并不是Java独有的概念,NIO代表的一个词汇叫着IO多路复用。它是由操作系统提供的系统调用,Linux下的epoll和Mac里的kqueue。而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兴趣大门的钥匙。

附上本人基于Netty做的两个开源项目

https://zhuanlan.zhihu.com/p/35720383

https://zhuanlan.zhihu.com/p/36064672

【Netty 】Netty 是什么?能做什么?相关推荐

  1. Netty -Netty心跳检测机制案例,Netty通过WebSocket编程实现服务器和客户端长链接

    Netty心跳检测机制案例 案例要求 编写一个Netty心跳检测机制案例,当服务器超过3秒没有读时,就提示读空闲 当服务器超过5秒没有写操作时,提示写空闲 服务器超过7秒没有读或者写操作时,就提示读写 ...

  2. Netty —— Netty 模型

    前文 NIO介绍 NIO -- 三大组件 Netty -- 概述 Netty -- 下载.安装 Reactor 模式(单 Reactor 单线程.单 Reactor 多线程.主从 Reactor 多线 ...

  3. dotnetty java netty,Netty(DotNetty)原理解析

    一.背景介绍 DotNetty是微软的Azure团队,使用C#实现的Netty的版本发布.不但使用了C#和.Net平台的技术特点,并且保留了Netty原来绝大部分的编程接口.让我们在使用时,完全可以依 ...

  4. Netty : netty 4如何解决空轮询bug

    1.美图 2.概述 空轮询bug参考:Netty : 臭名昭出的JDK的NIO bug(空轮询bug) 4.netty4 解决 4.1 构建阈值 int selectorAutoRebuildThre ...

  5. Netty : netty 3如何解决空轮询bug

    1.美图 2.概述 空轮询bug参考:Netty : 臭名昭出的JDK的NIO bug(空轮询bug) 3. netty 3 如何解决 netty3采用的是第三种方案,检测重点是select函数是否返 ...

  6. java 伪异步 netty,Netty(一) - 不死的达芬奇的个人空间 - OSCHINA - 中文开源技术交流社区...

    一.我们先来看BIO的问题: 1  没有数据缓冲区,I/O性能存在问题: 2  没有C或C++中的Channel概念,只有输入和输出流: 3  通常会导致通信线程被长时间阻塞: 4  支持的字符集有限 ...

  7. [自己做个游戏服务器二] 游戏服务器的基石-Netty全解析,有例子,多图解释

    目录 1.Netty 是什么 2.Netty的优点 3.核心组件 3.1 Netty的线程模型 3.2 EventLoopGroup 3.3 Channel 3.4  option()与childOp ...

  8. Netty 粘包 拆包 编码 解码 序列化 介绍

    目录: 粘包 & 拆包及解决方案 ByteToMessageDecoder 基于长度编解码器 基于分割符的编解码器 google 的 Protobuf 序列化介绍 其他的 前言 Netty 作 ...

  9. 工作10年从大公司离职去小公司当CTO,被同事鄙视竟然不回netty

    Netty easy of use! 面试官 不不不,咱得跟我聊聊BIO.NIO.SELECT.EPOLL Netty quick and easy development of network ap ...

最新文章

  1. python自动点赞_用Python模拟技巧带你实现自动抽屉登录自动点赞
  2. [deviceone开发]-Star分享的优惠券商户管理端App开源
  3. 将整数拆分为勾股数的问题解决
  4. 运行时错误76未找到路径怎么解决_自动化测试解决竞争问题?等待一下就行了~...
  5. python requests cookie_Python requests模块cookie实例解析
  6. 数据库面试题【十八、优化关联查询优化子查询优化LIMIT分页优化UNION查询优化WHERE子句】
  7. 消除ubuntu16.04自带的alt快捷键
  8. as3是js和java_AS3与JS进行交互(一)
  9. 全国计算机等级考试题库二级C操作题100套(第28套)
  10. java循环单链表类构造函数_C++实现双向循环链表
  11. java线程唤醒与等待_Java线程的等待与唤醒
  12. python实现批量更改xml文件中内容替换
  13. 继承的编写小结汇总。
  14. 我的学习之路_第十七章_JavaUtils
  15. Jmeter (三十)jmeter+ant+jenkins持续集成
  16. 全面解析免费及收费SSH工具的基本特性和总结
  17. 烽火fr2600怎么web登录_烽火配置教程
  18. CT前瞻(三):Adobe系列XD软件绘制简单的原型图与交互设计
  19. 失眠可以用什么东西改善一个失眠多年的朋友给我推荐
  20. XSKY新一代分布式文件系统XGFS揭秘——元数据服务

热门文章

  1. ArcGIS基础实验操作100例--实验23提取栅格有效边界值
  2. 使用win中excel打开linux下.csv文件乱码问题
  3. git tag 标签重命名
  4. Meter Bus解析1:概述
  5. CentOS yum升级GCC到4.8
  6. MySQL基础(二十八)索引优化与查询优化
  7. 【计算机科学】【2004.06】动态环境中的移动机器人导航
  8. 与君共勉之--施一公教授的演讲
  9. 怎么通过微信开发者工具打开一个项目
  10. Linux基础 第九天