Netty源码分析之NIO

简介: Socket是两台主机之间逻辑连接的端点。TCP/IP是传输层协议,定义数据如何在忘了中进行传输。HTTP是应用成协议,主要用来定义规范,包装数据,方便数据处理。Socket是通信的基石,是支持TCP/IP协议的网络通信的基本操作单元。

1、Socket和IO模型

1、Socket

Socket是两台主机之间逻辑连接的端点。TCP/IP是传输层协议,定义数据如何在忘了中进行传输。HTTP是应用成协议,主要用来定义规范,包装数据,方便数据处理。Socket是通信的基石,是支持TCP/IP协议的网络通信的基本操作单元。它是网络通信过程中端点的抽象表示,包含进行网络通信必须的五种信息:连接使用的协议、本地主机的IP地址、本地进程的协议端口、远程主机的IP地址、远程进程的议
端口(IP+Port+Protocol)

2、Socket通信流程

在这里插入图片描述

3、IO模型

Java 共支持 3 种网络编程模型/IO 模式:BIO(同步并阻塞)、NIO(同步非阻塞)、AIO(异步非阻塞)

1、BIO(同步阻塞)

同步堵塞IO,服务器实现模式为一个连接一个线程,即客户端有连接请求时服务器端就需要启动一个线程进行处理,如果这个连接不做任何事情会造成不必要的线程开销,可以通过线程池机制优化

在这里插入图片描述
问题:

  • 每个请求需要创建独立的线程,创建线程是需要JVM内存开销的,默认好像是1kb,如果说并发比较大,资源占用比较大(调小)
  • 瞬时并发,请求回落,线程浪费严重(线程池)
  • 线程在业务处理过程中,可能会碰到IO,消费者数据消费更不上生产者线程等等,这些势必会导致线程堵塞等待(reactor-stream)
  • 连接建立后,当前线程中发现inputStram中没有数据可读,也会导致线程堵塞

NIO(同步非阻塞)

同步非阻塞,服务器实现模式为一个线程处理多个请求(连接),以事件驱动为基础,即客户端发送的连接请求都会注册到多路复用器上,多路复用器轮询到连接有 I/O 请求就进行处理

在这里插入图片描述
缺点:

  • NIO线程组需要指定大小,如果估算配置相差较大,也会造成浪费或不足
  • 线程在业务处理过程中,可能会碰到IO,消费者数据消费更不上生产者线程等等,这些势必会导致线程堵塞等待(reactor-stream)
  • 编写,理解代码相对来说复杂那么一点

AIO(异步非阻塞)

AIO 引入异步通道的概念,采用了 Proactor 模式,简化了程序编写,有效的请求才启动线程,它的特点是先由操作系统完成后才通知服务端程序启动线程去处理,一般适用于连接数较多且连接时间较长的应用

4、NIO编程

Java NIO 全称java non-blocking IO ,是指 JDK 提供的新 API。从 JDK1.4 开始,Java 提供了一系列改进的输入/输出的新特性,被统称为 NIO(即 New IO),是同步非阻塞的。

  1. NIO 有三大核心部分:Channel(通道),Buffer(缓冲区), Selector(选择器)
  2. NIO是 面向缓冲区编程的。数据读取到一个缓冲区中,需要时可在缓冲区中前后移动,这就增加了处理过程中的灵活性,使用它可以提供非阻塞式的高伸缩性网络
  1. Java NIO 的非阻塞模式,使一个线程从某通道发送请求或者读取数据,但是它仅能得到目前可用的数据,如果目前没有数据可用时,就什么都不会获取,而不是保持线程阻塞,所以直至数据变的可以读取之前,该线程可以继续做其他的事情。 非阻塞写也是如此,一个线程请求写入一些数据到某通道,但不需要等待它完全写入, 这个线程同时可以去做别的事情 通俗理解:NIO 是可以做到用一个线程来处理多个操作的。假设有 10000 个请求过来,根据实际情况,可以分配50 或者 100 个线程来处理。不像之前的阻塞 IO 那样,非得分配 10000 个

区别

  • BIO是以流方式处理数据,NIO以缓冲区处理数据,缓冲区IO效率比流IO效率高,为啥??嘿嘿,等下说
  • BIO是阻塞的,NIO是非阻塞的,内部通过事件驱动,taskQueue,Thread实现
  • IO模型内部结构设计不一样,BIO是Thread-per-request,NIO是SocketChannel,Buffer,Selector

为什么缓冲区IO效率高于流IO?

  • 流与块

IO和NIO最重要的区别就是数据打包和传输的方式,IO以流的方式处理数据,而NIO以块的方式处理数据。
面向流的IO一次处理一个字节数据:一个输入流产生一个字节数据,一个输出流消费一个字节数据。为流式数据创建过滤器非常容易,连接一个过滤器,以便每个过滤器只负责复杂处理机制的一部分。不利的一面是,面向流的IO非常慢
面向块的IO一次处理一个数据块,按照处理数据比按照流处理数据要块很多。但是面向块的IO缺少一些面向流的IO所具有的优雅性和简单性。
IO包和NIO已经很好的集合了,java.io. 已经以NIO为基础重新实现了,所以它现在可以利用NIO的一些特性。例如,java.io. 包中的一些类包含以快的形式读取数据的方法,这使得即使在面向流的系统中,处理速度也会更快。

  • channel和stream:

方向性:channel数据是双向通行(read/write) ,stream是单向通行的。
channel是必须和buffer结合使用的,stream可以和buffer配套,也可以不用。
channel是可以设置为阻塞和非阻塞的。流本身就是阻塞的

NIO核心组件关系原理

在这里插入图片描述

  1. 每个 channel 都会对应一个 Buffer
  2. Selector 对应一个线程, 一个线程对应多个 channel(连接)
  3. 每个 channel 都注册到 Selector选择器上
  4. Selector不断轮询查看Channel上的事件, 事件是通道Channel非常重要的概念
  5. Selector 会根据不同的事件,完成不同的处理操作
  6. Buffer 就是一个内存块 , 底层是有一个数组
  7. 数据的读取写入是通过 Buffer, 这个和 BIO , BIO 中要么是输入流,或者是输出流, 不能双向,但是

NIO 的 Buffer 是可以读也可以写 , channel 是双向的.

#### 数据传输流程

在这里插入图片描述

Selector大致执行流程

在这里插入图片描述
只有在通道真正有读写事件发生时,线程才会进行读写,提高了线程利用率,减少上下文切换开销,避免创建多个线程处理导致内存开销

值得注意的对象和方法

Selector有几个重要方法需要注意:

  • Selector.open() : //得到一个选择器对象
  • selector.select() : //阻塞 监控所有注册的通道,当有对应的事件操作时, 会将SelectionKey放入集合内部并返回事件数量
  • selector.select(1000): //阻塞 1000 毫秒,监控所有注册的通道,当有对应的事件操作时, 会将SelectionKey放入集合内部并返回
  • selector.selectedKeys() : // 返回存有SelectionKey的集合

SelectionKey什么意思?

在这里插入图片描述
SelectionKey:A token representing the registration of a SelectableChannel with a Selector

相关文章
|
2月前
|
设计模式
Lettuce的特性和内部实现问题之Netty NIO的性能优于BIO的问题如何解决
Lettuce的特性和内部实现问题之Netty NIO的性能优于BIO的问题如何解决
|
1月前
|
Java
Netty BIO/NIO/AIO介绍
Netty BIO/NIO/AIO介绍
|
2月前
|
网络协议 C# 开发者
WPF与Socket编程的完美邂逅:打造流畅网络通信体验——从客户端到服务器端,手把手教你实现基于Socket的实时数据交换
【8月更文挑战第31天】网络通信在现代应用中至关重要,Socket编程作为其实现基础,即便在主要用于桌面应用的Windows Presentation Foundation(WPF)中也发挥着重要作用。本文通过最佳实践,详细介绍如何在WPF应用中利用Socket实现网络通信,包括创建WPF项目、设计用户界面、实现Socket通信逻辑及搭建简单服务器端的全过程。具体步骤涵盖从UI设计到前后端交互的各个环节,并附有详尽示例代码,助力WPF开发者掌握这一关键技术,拓展应用程序的功能与实用性。
92 0
|
2月前
|
传感器 物联网 微服务
Netty的源码分析和业务场景
【8月更文挑战第2天】Netty 是一款高性能的异步事件驱动网络框架,其源码深邃且复杂。通过采用Reactor模式与主从多线程设计,Netty能高效处理网络事件。例如,`NioEventLoop`负责I/O事件及任务执行,内置线程循环机制。内存管理方面,Netty提供高效内存池与`ByteBuf`类来减少开销并优化内存操作。在业务场景上,Netty广泛应用于分布式系统、微服务架构中的高效通信,以及实时通信场景如在线游戏和直播中的大量并发连接处理,同时也在物联网领域发挥重要作用,确保设备与服务器间稳定快速的数据传输。
|
2月前
|
网络协议 大数据 Linux
Netty的源码分析和业务场景
通过深入分析 Netty 的源码和理解其在不同业务场景下的应用,开发者可以更好地利用这一强大的网络编程框架,构建高效、稳定且可扩展的网络应用。
215 1
|
2月前
|
存储 网络协议 Java
【Netty 神奇之旅】Java NIO 基础全解析:从零开始玩转高效网络编程!
【8月更文挑战第24天】本文介绍了Java NIO,一种非阻塞I/O模型,极大提升了Java应用程序在网络通信中的性能。核心组件包括Buffer、Channel、Selector和SocketChannel。通过示例代码展示了如何使用Java NIO进行服务器与客户端通信。此外,还介绍了基于Java NIO的高性能网络框架Netty,以及如何用Netty构建TCP服务器和客户端。熟悉这些技术和概念对于开发高并发网络应用至关重要。
60 0
|
5月前
|
Java 应用服务中间件 API
从零手写实现 tomcat-06-servlet bio/thread/nio/netty 池化处理
该文介绍了逐步改进的网络服务器实现,从最初的 BIO 基础版到使用线程池的 BIO+Thread,再到 NIO 版本和 NIO+Thread,最后展示了一个使用 Netty 框架的简洁实现。文章旨在说明如何解决阻塞问题,并对比不同模型的优劣,最终推荐使用 Netty 以简化 NIO 编程。
|
5月前
|
编解码 网络协议 Java
用Java的BIO和NIO、Netty实现HTTP服务器(一) BIO与绪论
用Java的BIO和NIO、Netty实现HTTP服务器(一) BIO与绪论
|
5月前
|
移动开发 编解码 网络协议
用Java的BIO和NIO、Netty来实现HTTP服务器(三) 用Netty实现
用Java的BIO和NIO、Netty来实现HTTP服务器(三) 用Netty实现
|
5月前
|
设计模式 网络协议 Java
Java NIO 网络编程 | Netty前期知识(二)
Java NIO 网络编程 | Netty前期知识(二)
112 0