原创声明
本文思维导图
简介
Java 作为一门后端语言, 对于网络编程的支持是必不可少的, 但是, 作为一个经常 CRUD 的 Java 工程师, 很多时候都不需要接触到网络编程, 自然而然地对这个东西不那么重视了, 毕竟, 即使像是 JVM 虚拟机, Java 多线程, 在平时工作的时候还会用到一些, 但是对于网络编程, 除非你做的东西确实是需要自己写通讯服务代码的, 比如网络游戏, 以及偏向中间件方向的开发, 可能会接触到一些网络编程的实践, 要不然在平时的开发工作中确实不多见.
让我们看下网络编程在百度百科上的定义: 网络编程最主要的工作就是在发送端把信息通过规定好的协议进行组装包, 在接收端按照规定好的协议把包进行解析, 从而提取出对应的信息, 达到通信的目的.
那么, 为什么网络编程重要呢, 简单来说, 计算机之间之所以能够通信, 靠的就是网络编程, 只不过平时这些代码不需要我们自己来写罢了, TCP/IP 的协议代码已经封装在了 Linux 内核中 , 而 Tomcat 里的代码则负责处理一个个网络请求, 返回请求方需要的数据. 再比如像 netty 这样的网络编程框架, 也会把复杂的 NIO 处理逻辑封装成简单的 API, 即使如此, 需要使用 netty 来做服务端开发的工程师仍然不多.
Java 网络编程对于 Java 工程师来说是很重要的能力, 这也是我在接触了一系列相关面试题, 以及 Tomcat 和 netty 实现之后才逐渐意识到的, 想要了解这两个东西的实现原理, 就必须要会网络编程的知识, 当然了, 这一切的基础就是你要首先懂得计算机网络, 这部分内容也可以参考我关于计算机网络的一篇文章.
本文思维导图
Java 网络编程该怎么学
计算机网络和 Java 网络编程的关系
计算机网络之于 Java 网络编程, 好比数据结构之于算法, 前者是后者的基础, 没有前者的支撑, 直接学习后者, 是没有意义的.
之前我也写了一篇关于计算机网络该怎么学的文章, 可以先看看. 总体来看, 计算机网络告诉我们的是, 两台计算机想要进行通信, 它们需要约定一种传输协议和编码解码的标准, 因此计算机网络通常分为 5 层, 而其中一些标准就包括 TCP 和 IP,HTTP 等等, 这些协议都是为了更好地实现网络数据传输而产生的.
但是, 这些协议只是协议而已, 要真正在 Java 代码里实现网络传输, 就需要让代码实现协议, 当然了, 像 TCP/IP 这样通用的协议栈. 还轮不到 Java 应用程序自己来实现, 否则也太麻烦了, Linux 的内核里已经对其进行了封装, 并且会向上提供 API, 所以 Java 应用程序只需要调用 Linux 内核提供的即可.
而再往上, 也就是 HTTP 这类应用层协议, Java 代码是可以直接进行解析或者组装的, 毕竟 HTTP 的报文比较简单, 我们可以直接通过 Java 提供的 API 进行操作, 大家也都知道, Java 里有一些网络编程的包, 提供了一些常用于网络通讯的类, 比如 Socket 可以用来建立网络连接, IO 流则可以用来处理网络传输的 IO 输入和输出.
换言之, 网络编程的实质就是先进行网络连接, 然后进行 IO 传输, 而网络 IO 这个东西里又大有门道, 这部分内容我们在下一节里继续分享.
网络编程里 BIO,NIO 和 AIO
说到这三个东西, 相比学过 Java 的朋友都不会陌生, 毕竟面试题也经常考, 背也都背下来了.
但是这几个东西为什么会有这样的区别呢, 不妨一起来探究一下.
BIO 是最原始的 Java IO 模式, 也叫阻塞式 IO, 多个 BIO 处理必须要串行执行, 因为 IO 此时被阻塞了.
而 NIO 则是相对较新的一种模式, 它基于 Linux 的 epoll 来进行实现, 通过一个线程对多个连接进行处理, 当发现有活跃的连接时进行对应的 IO 处理, 本质上是 IO 多路复用的一种实现.
而 AIO 和上面两者不太一样, 它强调的不是阻塞非阻塞, 而是对 IO 的处理是异步化的, 通常来说就是建立连接, 然后提供一个处理完 IO 的回调接口, 然后就可以扔在一边不管了, 等待 IO 处理结束后回调相应的接口. 值得一提的是, AIO 需要底层操作系统的支持.
通信框架 netty
了解了 BIO,NIO 和 AIO 之后, 你对于网络编程中的几个核心概念你应该已经有所了解了, 接下来就不得不看看 Java 网络编程中最牛掰的一个框架: netty 了. 比起 NIO 和 BIO, 了解 netty 的人应该更少了, 其实, netty 就是基于 NIO 实现的异步网络编程框架, 既有了 NIO 的高性能 IO 处理方式, 又通过异步化编程使得 netty 的编程方式更加简单高效.
我当时接触 netty 的时候, 还是在学习 RPC 和分布式服务的时候, 我发现每当有 RPC 出现的地方, 也总有网络编程框架的身影, 好比 netty 这样的通讯框架常常会被提到, 我当时并不太理解通讯框架是干嘛用的, 以至于我对 RPC 是什么东西都不太理解.
当我现在搞懂了 RPC 之后, 再去研究网络编程框架就有了新的感觉, 其实, 不管是 RPC 还是 HTTP, 都需要通信框架的支持, 只不过支持 HTTP 的服务器已经有很多了, 比如 Tomcat, 比如 Nginx, 这些服务器完全可以 cover 掉网络框架, 后面我们也会再来聊一下 Tomcat 这个神奇的服务器.
Tomcat 这个神奇的服务器
Tomcat 这个服务器我们 Java 工程师一直在用, 但是很多朋友对它其实知之甚少, 只知道它可以运行 Javaweb 应用.
其实 Tomcat 这个服务器, 也是基于 NIO 实现的一个服务器, 不妨把 Tomcat 分为两个部分来看, 一部分是 connector, 负责网络连接, 接受请求和处理请求, 另一部分是 container, 也就是容器, Tomcat 本质上是一个 servlet 容器, 这一部分负责的就是编排一系列容器里的处理器, 调用链以及层级结构, 比如 engine 的下一层是 host,host 的下一层是 context.
当一个网络请求到达 Tomcat 时, connector 先负责处理这个请求, 再扔到 container 跑一遍拿到结果, 但在生产环境中, connector 一次性要处理的请求就多的去了, 因此就必须要支持高并发以及 IO 多路复用, 因此 Tomcat 也采用了 NIO 的 IO 处理方式, 同时通过多线程进行请求处理, 总体来说已经达到了非常不错的性能了.
面向面试复习
一个小小的 Java 网络编程, 居然一下子牵扯出这么多复杂的知识点出来, 先是计算机网络, 再到 Java 网络编程 API, 再到 BIO,NIO 和 AIO, 然后又谈到了 Tomcat 和 netty.
其实, 网络编程的内容可能还不止这些, 比如 NIO 的底层实现是基于 Linux 的 epoll 来完成了, 而 Linux 的网络 IO 模型有 select,poll 和 epoll 等方式, 要真正搞懂 NIO, 你还需要搞懂 epoll.
其实一开始我对于 Java 网络编程也没有什么概念, 只不过在看了很多面试题之后, 才逐渐发现问题所在, 比如 BIO 和 NIO 的区别, 背了好几次面试答案仍然不解其意, 要是再问到 epoll,poll 和 select 的区别, 更是完全不得要领, 究其原因还是不知道这些东西到底是什么, 有什么用, 以及它们和一些实际场景间的关系.
因此, 我觉得, 网络编程方向的面试题重在理解概念, 对于计算机网络, IO 模型, 以及网络编程框架要能够真正理解了这些东西之后, 你才能够对面试题游刃有余, 否则, 这类面试题再怎么背都不会有什么效果, 正如计算机网络这种纯理论的课程一样, 在不理解的情况下, 分析问题和回答问题肯定是难以达到面试官要求的.
所以, 请按照这样的一个顺序进行复习和实践, 相信这对于你学习网络编程会有所帮助.
1, 计算机网络知识
2,Java 网络编程基础
3,NIO,BIO,AIO
4,Linux 的网络 IO 模型: epoll,select 和 poll
5,netty 网络编程框架
6,Tomcat 服务器
推荐资源
这方面能推荐的资源就非常多了, 我尽量按照先易后难的顺序为大家推荐资源
书籍
《Java 网络编程》
《netty 权威指南》
《How Tomcat Work》
《Tomcat 架构解析》
视频
我整理一些 Java 网络编程复习的视频资源, 习惯看视频的朋友可以了解一下.
博客
Java 技术仓库《Java 程序员复习指南》
https://github.com/h2pl/Java-Tutorial
整合全网优质 Java 学习内容, 帮助你从基础到进阶系统化复习 Java.
总结
来源: https://www.cnblogs.com/xll1025/p/12535287.html