IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> Netty -> 正文阅读

[Java知识库]Netty

了解Netty之前我们先了解一下IO与NIO

传统IO编程

每个客户端连接过来后,服务端都会启动一个线程去处理该客户端的请求
在这里插入图片描述
这样做在用户线程比较少的情况下是没有问题的,可是用户线程一旦多了,服务器就要承受成千万的的连接,压力大了故障频发

例如:如果有一万个连接就要创建一个线程,会存在一下问题:

1.当客户端越多就会创建越多的线程,线程是操作系统中非常宝贵的资源。同一时刻有大量线程
阻塞(为什么会阻塞,因为线程如果是读操作,读不到数据就会一直阻塞在这里直到读到数据,这也是
io编程的的一个特点)是非常严重的资源浪费,如果是类似双十一的活动又会造成线程池瞬间耗尽,
导致服务器瘫痪。
2.因为是阻塞式通信,线程爆炸之后操作系统频繁进行线程切换,应用性能急剧下降。
3.IO编程中数据读写是以字节流为单位,效率不高。

标题NIO编程

NIO,也叫做new-IO或者non-blocking-IO,可理解为非阻塞IO。NIO编程模型中,新来一个连接不再创建一个新的线程,而是可以把这条连接直接绑定到某个固定的线程,然后这条连接所有的读写都由这个线程来负责,我们用一幅图来对比一下IO与NIO:
在这里插入图片描述
如上图所示,IO模型中,一个连接都会创建一个线程,对应一个while死循环,死循环的目的就是不断监测这条连接上是否有数据可以读。但是在大多数情况下,1万个连接里面同一时刻只有少量的连接有数据可读,因此,很多个while死循环都白白浪费掉了,因为没有数据。

而在NIO模型中,可以把这么多的while死循环变成一个死循环,这个死循环由一个线程控制。这就是NIO模型中选择器(Selector)的作用,一条连接来了之后,现在不创建一个while死循环去监听是否有数据可读了,而是直接把这条连接注册到选择器上,通过检查这个选择器,就可以批量监测出有数据可读的连接,进而读取数据。

这就是NIO模型解决线程资源受限的方案,实际开发过程中,我们会开多个线程,每个线程都管理着一批连接,相对于IO模型中一个线程管理一条连接,消耗的线程资源大幅减少。

NIO的三大核心组件:通道(Channel)、缓冲(Buffer)、选择器(Selector)

通道(Channel)

是传统IO中的Stream()的升级版。Stream是单向的、读写分离(inputstream和outputstream),
Channel是双向的,既可以进行读操作,又可以进行写操作。

缓冲(BufferBuffer可以理解为一块内存区域,可以写入数据,并且在之后读取它。

选择器(Selector)

选择器(Selector)可以实现一个单独的线程来监控多个注册在她上面的信道(Channel),
通过一定的选择机制,实现多路复用的效果。
 

NIO相对于IO的优势:

1.IO是面向流的,每次都是从操作系统底层一个字节一个字节地读取数据,并且数据只能从一端读取到另一端,不能前后移动流中的数据。NIO则是面向缓冲区的,每次可以从这个缓冲区里面读取一块的数据,并且可以在需要时在缓冲区中前后移动。
2.IO是阻塞的,这意味着,当一个线程读取数据或写数据时,该线程被阻塞,直到有一些数据被读取,或数据完全写入,在此期间该线程不能干其他任何事情。而NIO是非阻塞的,不需要一直等待操作完成才能干其他事情,而是在等待的过程中可以同时去做别的事情,所以能最大限度地使用服务器的资源。
3.NIO引入了IO多路复用器selector。selector是一个提供channel注册服务的线程,可以同时对接多个Channel,并在线程池中为channel适配、选择合适的线程来处理channel。NIO相对于IO的优势:

IO是面向流的,每次都是从操作系统底层一个字节一个字节地读取数据,并且数据只能从一端读取到另一端,不能前后移动流中的数据。NIO则是面向缓冲区的,每次可以从这个缓冲区里面读取一块的数据,并且可以在需要时在缓冲区中前后移动。
IO是阻塞的,这意味着,当一个线程读取数据或写数据时,该线程被阻塞,直到有一些数据被读取,或数据完全写入,在此期间该线程不能干其他任何事情。而NIO是非阻塞的,不需要一直等待操作完成才能干其他事情,而是在等待的过程中可以同时去做别的事情,所以能最大限度地使用服务器的资源。
NIO引入了IO多路复用器selector。selector是一个提供channel注册服务的线程,可以同时对接多个Channel,并在线程池中为channel适配、选择合适的线程来处理channel。由于NIO模型中线程数量大大降低,线程切换效率因此也大幅度提高。

为什么使用Netty

简单的说:Netty封装了JDK的NIO,让你用得更爽,你不用再写一大堆复杂的代码了。

官方术语:Netty是一个异步事件驱动的网络应用框架,用于快速开发可维护的高性能服务器和客户端。

下面是使用Netty不使用JDK原生NIO的一些原因:

使用JDK自带的NIO需要了解太多的概念,编程复杂
Netty底层IO模型随意切换,而这一切只需要做微小的改动,就可以直接从NIO模型变身为IO模型
Netty自带的拆包解包,异常检测等机制,可以从NIO的繁重细节中脱离出来,只需要关心业务逻辑
Netty解决了JDK的很多包括空轮询在内的bug
Netty底层对线程,selector做了很多细小的优化,精心设计的线程模型做到非常高效的并发处理
自带各种协议栈让你处理任何一种通用协议都几乎不用亲自动手
Netty社区活跃,遇到问题随时邮件列表或者issue
Netty已经历各大rpc框架,消息中间件,分布式通信中间件线上的广泛验证,健壮性无比强大

Netty的事件驱动

例如很多系统都会提供 onClick() 事件,这个事件就代表鼠标按下事件。事件驱动模型的大体思路如下:

有一个事件队列;
鼠标按下时,往事件队列中增加一个点击事件;
有个事件泵,不断循环从队列取出事件,根据不同的事件,调用不同的函数;
事件一般都各自保存各自的处理方法的引用。这样,每个事件都能找到对应的处理方法;
在这里插入图片描述
为什么使用事件驱动?

程序中的任务可以并行执行

任务之间高度独立,彼此之间不需要互相等待

在等待的事件到来之前,任务不会阻塞

Netty使用事件驱动的方式作为底层架构,包括:

事件队列(event queue):接收事件的入口。
分发器(event mediator):将不同的事件分发到不同的业务逻辑单元。
事件通道(event channel):分发器与处理器之间的联系渠道。
事件处理器(event processor):实现业务逻辑,处理完成后会发出事件,触发下一步操作。
在这里插入图片描述
Netty 功能特性:

传输服务,支持 BIO 和 NIO。
容器集成:支持 OSGI、JBossMC、Spring、Guice 容器。
协议支持:HTTP、Protobuf、二进制、文本、WebSocket 等,支持自定义协议。
在这里插入图片描述

Netty框架包含如下的组件:

ServerBootstrap :用于接受客户端的连接以及为已接受的连接创建子通道,一般用于服务端。
Bootstrap:不接受新的连接,并且是在父通道类完成一些操作,一般用于客户端的。

Channel:对网络套接字的I/O操作,例如读、写、连接、绑定等操作进行适配和封装的组件。
EventLoop:处理所有注册其上的channel的I/O操作。通常情况一个EventLoop可为多个channel提供服务。
EventLoopGroup:包含有多个EventLoop的实例,用来管理 event Loop 的组件,可以理解为一个线程池,内部维护了一组线程。

ChannelHandler和ChannelPipeline:例如一个流水线车间,当组件从流水线头部进入,穿越流水线,流水线上的工人按顺序对组件进行加工,到达流水线尾部时商品组装完成。流水线相当于ChannelPipeline,流水线工人相当于ChannelHandler,源头的组件当做event。
ChannelInitializer:用于对刚创建的channel进行初始化,将ChannelHandler添加到channel的ChannelPipeline处理链路中。

ChannelFuture:与jdk中线程的Future接口类似,即实现并行处理的效果。可以在操作执行成功或失败时自动触发监听器中的事件处理方法。

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2021-11-27 09:46:50  更:2021-11-27 09:48:31 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 3:24:59-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码