Java NIO分析(12): NIO总结
迟来的总结,NIO系列写了11篇了,本篇做个总结吧
写这个系列的起因是各个框架比如netty
, tomcat
, jetty
这些高性能框架的
基石就是NIO
, 一直想讲讲它们高性能的原因。
1. NIO网络编程体系
本系列主要是讲NIO网络编程相关的,因为Java服务端开发最关心的就是这些。 我们记不住孤立的事实, 知识得体系化. 这里上一张笔者写本系列画的脑图
笔者先从Unix网络编程开始, 讲了5种IO模型,
- 阻塞I/O(blocking I/O)
- 非阻塞I/O(non-blocking I/O)
- I/O复用(I/O multiplexing)
- 信号驱动式I/O(signal-driven I/O)
- 异步I/O(asynchronous I/O)
并指出所有的I/O模型都要经历2个阶段,即数据准备
和内核拷贝数据到应用进程
异步I/O模型虽然效率高,但是编程复杂,在实际用的不算多。前四种模型的区别主要在第一阶段数据准备
第二阶段拷贝数据都会阻塞。
I/O多路复用是使用最广泛的I/O模型,内核帮助你完成了Event Loop
, 你select
之后得到的就是
已经准备就绪的fd集合.
接下来研究了下I/O多路复用的历史,知道了没有Socket和select之前的黑历史,全靠进程的fork来完成 进程之间的通信,一个负责读一个负责写,还经常有同步问题, 更早的还有非分时操作系统,那个感兴趣的 可以自己去维基百科瞅瞅。
在Java-NIO分析-3-I-O多路复用之select系统调用 ,Java-NIO分析-4-I-O多路复用之poll系统调用 , Java-NIO分析-5-I-O多路复用之epoll系统调用里举了几个实际的使用I/O多路复用的api例子,看了下我们是如何在操作系统提供的api上具体使用多路复用的。
以上基础完成之后,我们介绍了NIO的一些基本概念,如同步异步,阻塞非阻塞, 并指出阻塞
和非阻塞
关注的是应用进程在等待调用结果时的状态, 而同步
和异步
关注的是通信.再从BIO的设计和缺陷开始讲起,引出为什么要搞NIO.
- 客户端连接很多的时候,会创建大量的处理线程,每创建一个线程都需要分配一定的栈空间,一般是1K~1M,那么4G内存也只能起4000~40000个线程。
- 线程多导致上下文切换严重
- 阻塞导致负责网络数据读写的线程不可复用
之后我们具体分析了Selector, SocketChannel, DirectBuffer的底层实现,指出其本质上使用的依然是底层的epoll
,poll
, select
, fcntl
这些api,
只是jvm做了一层封装而已。后面我们又分析了Linux中的zero copy
技术和NIO对它的支持,底层使用的还是mmap
和send_file
系统调用。
至此,NIO系列的核心知识基本就讲完了, 关键点就是这些。
2. NIO的其他知识
其实NIO还有一些别的改进, 只是对服务端编程用处不大,比如Java7以后提供了全面的文件系统API支持
- 使用Path抽象来替代java.io.File, 代表了一个与平台无关的路径
- 提供Files和Paths类来快捷操作文件,比如新建临时文件,删除文件等等
- 提供WatchService来监听文件系统中的文件变化
- 全面的基于异步Channel的IO
举个监听文件变化的简单的例子:
|
|
3. 总结
Java4以后, 通过NIO提供了一套基于I/O多路复用的API, 本系列就讲到这里,笔者认为服务端编程还是需要 比较系统的底层知识的,可以在实践中慢慢学习。
使用Java语言写服务端的好处是轮子都是现成的,坏处亦如是。 框架屏蔽了底层细节,在高并发场景下,如果读者不知底层实现的细节,优化将无从谈起。 而且只看框架的话,Java学到深处就只学会了一些字节码诡计,比如javassist, asm等来做一些黑科技。
也不是说它们不好,它们方便了我们的开发,当然是好事。只是作为一个服务端开发, 真正要专注的东西,笔者认为是
- 软件架构知识
- 网络通信和各种协议, 如TCP/UDP细节
- 操作系统的知识
- 数据结构和算法
- 一些工程化和业务划分,异常处理的思路
这些是和语言,框架无关的扎实知识,比如哪天你不用Java了换golang
了依然用的是epoll
.
以上,共勉.
- 原文作者:Chris Wang
- 原文链接:https://www.sound2gd.wang/post/java-nio%E5%88%86%E6%9E%9012-nio%E6%80%BB%E7%BB%93/
- 版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议. 进行许可,非商业转载请注明出处(作者,原文链接),商业转载请联系作者获得授权。