Netty1 Java IO 演进之路

1  Netty简介

Netty是一个异步事件驱动的网络应用框架,。Netty提供异步的、非阻塞的事件驱动的网络应用程序框架和工具,用于快速开发可维护的高性能服务器和客户端。

1.1、为什么要学Netty?

    Spring5 底层用Netty
    Spring Boot 内部实现了Web容器

    Zookeeper  也是用的Netty
    Dubbo  分布式服务框架  多协议支持(RPC) Netty

 


1.2、Netty能帮我们解决什么问题?
    
    框架:简化开发一系列解决方案的集合, 封装IO操作的框架
    
    复杂的业务场景中,一般采用  IO + 多线程来解决问题

    Netty 主要的优点有:
       1. 框架设计优雅,底层模型随意切换适应不同的网络协议要求。
       2. 提供很多标准的协议、安全、编码解码的支持。
       3. 解决了很多NIO 不易用的问题。
      4. 社区更为活跃,在很多开源框架中使用,如Dubbo、RocketMQ、Spark 等。


   
    
2、必须明白的几个概念

2.1.1 阻塞(Block)和非阻塞(Non-Block) 阻塞和非阻塞是进程在访问数据的时候,数据是否准备就绪的一种处理方式,当数据没有准备的时候。 阻塞:往往需要等待缓冲区中的数据准备好过后才处理其他的事情,否则一直等待在那里。 非阻塞:当我们的进程访问我们的数据缓冲区的时候,如果数据没有准备好则直接返回,不会等待。如果数据已经 准备好,也直接返回。

2.1.2 同步(Synchronization)和异步(Asynchronous) 同步和异步都是基于应用程序和操作系统处理 IO 事件所采用的方式。比如同步:是应用程序要直接参与 IO 读写 的操作。异步:所有的 IO 读写交给操作系统去处理,应用程序只需要等待通知。 同步方式在处理 IO 事件的时候,必须阻塞在某个方法上面等待我们的 IO 事件完成(阻塞 IO 事件或者通过轮询 IO 事件的方式),对于异步来说,所有的 IO 读写都交给了操作系统。这个时候,我们可以去做其他的事情,并不需要去完 成真正的 IO 操作,当操作完成 IO 后,会给我们的应用程序一个通知。 同步 : 阻塞到 IO 事件,阻塞到 read 或则 write。这个时候我们就完全不能做自己的事情。让读写方法加入到线 程里面,然后阻塞线程来实现,对线程的性能开销比较大。

2.1.3 IO多路复用:I/O是指网络I/O,多路指多个TCP连接(即socket或者channel),复用指复用一个或几个线程。意思说一个或一组线程处理多个TCP连接。最大优势是减少系统开销小,不必创建过多的进程/线程,也不必维护这些进程/线程。
  IO多路复用使用两个系统调用(select/poll/epoll和recvfrom),blocking IO只调用了recvfrom;select/poll/epoll 核心是可以同时处理多个connection,而不是更快,所以连接数不高的话,性能不一定比多线程+阻塞IO好,多路复用模型中,每一个socket,设置为non-blocking,阻塞是被select这个函数block,而不是被socket阻塞的。

例如select机制
基本原理:
  客户端操作服务器时就会产生这三种文件描述符(简称fd):writefds(写)、readfds(读)、和exceptfds(异常)。select会阻塞住监视3类文件描述符,等有数据、可读、可写、出异常 或超时、就会返回;返回后通过遍历fdset整个数组来找到就绪的描述符fd,然后进行对应的IO操作。
优点:
  几乎在所有的平台上支持,跨平台支持性好
缺点:
  由于是采用轮询方式全盘扫描,会随着文件描述符FD数量增多而性能下降。
  每次调用 select(),需要把 fd 集合从用户态拷贝到内核态,并进行遍历(消息传递都是从内核到用户空间)
  默认单个进程打开的FD有限制是1024个,可修改宏定义,但是效率仍然慢。

 

3、NIO 和 BIO 之间的区别

3.1.1 面向流与面向缓冲 Java NIO 和 BIO 之间第一个最大的区别是,BIO 是面向流的,NIO 是面向缓冲区的。 Java BIO 面向流意味着每 次从流中读一个或多个字节,直至读取所有字节,它们没有被缓存在任何地方。此外,它不能前后移动流中的数据。 如果需要前后移动从流中读取的数据,需要先将它缓存到一个缓冲区。 Java NIO 的缓冲导向方法略有不同。数据读取 到一个它稍后处理的缓冲区,需要时可在缓冲区中前后移动。这就增加了处理过程中的灵活性。但是,还需要检查是 否该缓冲区中包含所有您需要处理的数据。而且,需确保当更多的数据读入缓冲区时,不要覆盖缓冲区里尚未处理的 数据。

3.1.2 阻塞与非阻塞 Java BIO 的各种流是阻塞的。这意味着,当一个线程调用 read() 或 write()时,该线程被阻塞,直到有一些数据被 读取,或数据完全写入。该线程在此期间不能再干任何事情了。 Java NIO 的非阻塞模式,使一个线程从某通道发送请 求读取数据,但是它仅能得到目前可用的数据,如果目前没有数据可用时,就什么都不会获取。而不是保持线程阻塞, 所以直至数据变的可以读取之前,该线程可以继续做其他的事情。 非阻塞写也是如此。一个线程请求写入一些数据到 某通道,但不需要等待它完全写入,这个线程同时可以去做别的事情。 线程通常将非阻塞 IO 的空闲时间用于在其它 通道上执行 IO 操作,所以一个单独的线程现在可以管理多个输入和输出通道(channel)。

3.1.3 选择器的问世 Java NIO 的选择器(Selector)允许一个单独的线程来监视多个输入通道,你可以注册多个通道使用一个选择器,然 后使用一个单独的线程来“选择”通道:这些通道里已经有可以处理的输入,或者选择已准备写入的通道。这种选择机制, 使得一个单独的线程很容易来管理多个通道

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值