漫谈Java IO之基础篇

Java的网络编程如果不是专门搞服务器性能开发或者消息分发,几乎可能涉及不到。但是它却是面试找工作必问的一个知识点,涵盖的知识体系也非常广泛,从Java底层IO原理到操作系统内核组成,再到网络TCP、UDP、HTTP的应用实践....因此,即便是职场多年的老油条,仍然需要时刻复习,更别提我这种只有七秒钟记忆的小菜鸟了。

Java网络IO的演化,从最开始JDK1.4之前是基于阻塞的IO;发展到1.4发布后的Nio提供了selector多路复用的机制以及channel和buffer,再到1.7的NIO升级提供了真正的异步api;再发展到后来崭露头角的MINA和Netty。因此整个网络IO编程的学习整理,也会按照下面的几个步骤来进行:

  1. 网络IO的基本知识与概念
  2. 普通IO以及BIO服务器
  3. NIO的使用与服务器Hello world
  4. Netty入门与服务器Hello world
  5. Netty深入浅出

今天就简单的了解下网络IO需要具备的基本知识与概念。

同步、异步和阻塞、非阻塞

经常听人提起,同步阻塞服务器或者异步非阻塞服务器,网上有很多的文章针对这个概念作出了讲解,每个人理解的貌似都不太一样。最容易把异步和非阻塞搞混....我这里简单的说下自己的理解:

同步synchronous、异步asynchronous,他们的区别就是发起任务后,本身的一个状态——如果是一直等待结果,那就是同步;如果立即返回,并采用其他的方式得到结果就是异步(比如,状态、通知、回调)。

举个例子:

  1. 在过去科技不发达的时候,银行取钱都是排队的模式。想取钱就得去排队,直到轮到自己,这就是同步;
  2. 现在去银行一般直接叫号,然后去休息位置休息打游戏,登到轮到自己的时候,会有通知,这就是异步;

阻塞blocking、非阻塞non-blocking,则聚焦的是CPU在等待结果的过程中的状态。比如前面的例子,排队的过程中什么也不做就是阻塞;一边排队,一遍玩王者荣耀就是非阻塞的。

用户空间与内和空间

这个概念就涉及操作系统了,为了保护操作系统的安全,会将内存分为用户空间内核空间两个部分。如果用户想要操作内核空间的数据,需要把数据从内和空间拷贝到用户控件。

举个例子:

服务器接收客户端发过来的请求,想要进行处理,大致会经过下面几个步骤:

  1. 服务器的网络驱动接收到消息,去内核上申请空间;并等待完整的数据包到达(有可能分组传送,没传完...),复制到内核空间;
  2. 数据从内核空间拷贝到用户空间
  3. 用户程序进行处理

因此大致可以把接收消息理解为两个阶段:1. 等待数据到达 2. 拷贝到用户空间

了解了这个过程,就能明白为什么会出现经典的5大网络模型了.

五大网络模型

这几个网络模型还是学生时代的时候也看过,但是理解的不够透彻,也不知道到底有什么区别。最近网上也看过不少的文章,发现有一些文章引用的小例子不错,能很简单的了解这些模型的意思。所以我这边也借鉴一下:

在大连高新万达后面有一条叫做金街的小吃街,有一个露天的路边摊叫做“小红旗”,主要是做炸臭豆腐和冷面,然后用冷面把臭豆腐卷起来,刷上臭烘烘的酱料,非常好吃。每次路过都能看到不少人在排队,队伍长的有种想让人辞职加盟的感觉....基本上排个队伍都得半个小时-一个小时吧。

这个排队的过程,明显就是上面所说的同步阻塞模式....那我这边就设想下,如果小红旗的生意做大了,可以怎么发展?正好套用下网络模型的概念...

1. 同步阻塞IO

这个就不详细说了,排队的过程哪也去不了,如果你还没有带手机,排队的过程中就只能干瞪眼了。这就是很明显的同步+阻塞模式。

2. 同步非阻塞IO

如果小红旗的老板搞了一个点菜机,来点单的顾客把自己想吃的划上,然后等着老板去做,自己可以在这一个小时的时间里去周围商场溜达下。但是由于没有任何通信方式,只能不停的回来问老板,做好了没有。

回来询问的时间是由顾客自己掌控的,如果时间很短,那么可以尽量早的知道臭豆腐炸好没,但是也会影响逛街的体验;如果时间很长,有可能臭豆腐早就做好了..结果放的时间长了,反而不好吃了。

因此非阻塞IO基于状态轮训的方式,虽然能让程序在等待的过程中做点其他的事情,但是频繁的切换运行程序,反而会造成很大的压力。

3. IO多路复用/事件驱动

小红旗老板升级了系统,放弃使用点菜机,改用麦当劳那种点餐大屏。同样是点餐,但是一个大屏里面显示了很多人的臭豆腐进度,即节省了资源,也避免大家不停的询问。

其实Nio活着Netty就是基于这种模式,一个线程就可以监听很多IO操作,这样在IO等待上就高效多了。具体实现是依赖于操作系统的,windows和linux都有不同的实现方式。最初的select或者poll,都有并发数的限制,并且NIO的select还有空轮训的问题;epool则突破了连接数的限制,一个线程就可以监听大量的IO操作。这个感兴趣的朋友,可以深入了解下select、poll、epool的原理。

4. 信号驱动IO

小红旗老板又时髦了,搞了一个升级版的美味不用等。顾客基于微信小程序点菜,菜做好了自动提醒顾客取餐....这个提醒的过程,就像是发射了一个特殊的信号。

不过UNIX网络编程里面的信号驱动,可没这么简单,这个信号是依赖于操作系统底层的,捕获信号或者处理都很麻烦,所以现在应用的也不是很广泛。

5. 异步非阻塞IO

一对小情侣李雷和韩梅梅,韩梅梅口味很重,特别喜欢吃臭豆腐,但是李雷完全不感兴趣,闻到味道就想吐。于是李雷就跟韩梅梅约定,让韩梅梅自己去吃,李雷跑到旁边的咖啡厅喝咖啡。韩梅梅自己去排队买臭豆腐,买完顺便吃完,然后回来找李雷....

这个过程就是异步非阻塞的,消息的等待和处理都在服务器端完成,用户只要最后接收到消息处理完的通知就行了。

总结

总结来说,这几种网络模型:

  1. 同步阻塞:强调的是我要做! —— 别的啥也别说,就是要做!
  2. 同步非阻塞:强调的是我想做! —— 在想的过程中,干点其他的事情更好。
  3. 异步非阻塞:强调的是我做完了!—— 等得到结果通知的时候,工作已经做完了。

其中细节,还需慢慢体会...后面的文章将会挑几个模型做代码的演示,更多内容还请持续关注。

参考

  1. 并发编程网
  2. Netty源码分析
  3. Netty源码分析
  4. Netty源码分析
  5. IO多路复用之select、poll、epoll
  6. 聊聊Linux五种IO模型
  7. 聊聊同步、异步、阻塞、非阻塞
  8. Netty官方文档
  9. 一篇文章,读懂Netty的高性能架构之道
  10. 代码示例分享

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏程序你好

如何保证你的智能手机安全和私密,手机安全需要做到的事

近十年以来,智能手机的应用越来广泛,各种流行的App层出不穷,可以说iPhone这样的智能手机已经彻底改变了我们的生活和行为习惯。请允许我指出一个显而易见的事实...

11720
来自专栏phodal

GitHub 更新 License 界面,让你对 License 一目了然

在前天的文章里,我们提到了 License 相关的信息,开源世界的 License 相当的复杂。 而在三个小时前,GitHub 为 License 页面添加了更...

208100
来自专栏编程坑太多

『高级篇』docker之springboot,springcloud(八)

PS:下面我们一步一步spring cloud+spring boot创建的微服务,部署在服务编排框架上。

34920
来自专栏纯洁的微笑

历时25天,我的博客(www.ityouknow.com)终于又活了过来

21030
来自专栏大魏分享(微信公众号:david-share)

深度分析:为啥说API是IT的未来?

本文在第一节,参考引用了 刘国强 CA Technologies中国区技术总监的《到底什么是“API经济学”》文章部分内容。本文其他章节技术部分则参考了社区和红...

28520
来自专栏java一日一条

采用断路器设计模式来保护软件

程序员的人生就像在一个快车道上行驶。几周甚至几小时完成某些特性编码,打包测试没有问题,盖上QA认证,代码部署到生产环境。然而最坏的事情发生了,你所部署的软件在运...

10120
来自专栏北京马哥教育

做Linux背锅2年,我总结了这六类好习惯和30个血的教训

一、线上操作规范 1.测试使用 当初学习Linux的使用,从基础到服务到集群,都是在虚拟机做的,虽然老师告诉我们跟真机没有什么差别,可是对真实环境的渴望日渐上升...

448120
来自专栏ThoughtWorks

微网关与服务啮合 | 洞见

技术雷达:现在越来越多的大型组织在向更加自组织的团队结构转型,这些团队拥有并运营自己的微服务,但他们如何在不依赖集中式托管的基础架构下,确保服务之间必要的一致性...

38750
来自专栏轮子工厂

十点总结,为何 Linux 如此深得人心

Linux 过去主要作为服务器运行,但经过几年的发展,其用户界面有了很大的改善。如今,Linux 已经成为美观易用,用户友好的桌面操作系统。在某些方面,Linu...

13030
来自专栏Vamei实验室

Linux简介与厂商版本

1. Linux简介 Linux可以有狭义和广义两种定义。狭义来说,Linux实际上指Linux kernel (内核)。内核负责管理硬件,并为上层应用提供接口...

26990

扫码关注云+社区

领取腾讯云代金券