【编程进阶知识】高并发场景下Bio与Nio的比较及原理示意图

简介: 本文介绍了在Linux系统上使用Tomcat部署Java应用程序时,BIO(阻塞I/O)和NIO(非阻塞I/O)在网络编程中的实现和性能差异。BIO采用传统的线程模型,每个连接请求都会创建一个新线程进行处理,导致在高并发场景下存在严重的性能瓶颈,如阻塞等待和线程创建开销大等问题。而NIO则通过事件驱动机制,利用事件注册、事件轮询器和事件通知,实现了更高效的连接管理和数据传输,避免了阻塞和多级数据复制,显著提升了系统的并发处理能力。

【编程进阶知识】高并发场景下Bio与Nio的比较及原理示意图

摘要: 本文介绍了在Linux系统上使用Tomcat部署Java应用程序时,BIO(阻塞I/O)和NIO(非阻塞I/O)在网络编程中的实现和性能差异。BIO采用传统的线程模型,每个连接请求都会创建一个新线程进行处理,导致在高并发场景下存在严重的性能瓶颈,如阻塞等待和线程创建开销大等问题。而NIO则通过事件驱动机制,利用事件注册、事件轮询器和事件通知,实现了更高效的连接管理和数据传输,避免了阻塞和多级数据复制,显著提升了系统的并发处理能力。
假设是用部署在Linux操作系统上的Tomcat配置的java应用程序。

关键字:Java, Linux, Tomcat, BIO, NIO, 高并发, 阻塞I/O, 非阻塞I/O, 事件驱动, 并发性能


1.Bio的技术代码逻辑实现

Bio属于传统网络编程处理连接以及数据传输的方式,技术代码逻辑实现大致如下:

1)一个BioServerTest(服务端启动服务的main主方法入口所在类,监听是否有客户端接入请求,有的话创建线程开始业务处理)

ServerSocket.bind(ip+port);//绑定ip+port,以便监听客户端向此ip+port发起的连接请求

while(server is Run){
   

Socket socket= ServerSocker.accept();

new Thread(new BioServerTask(socket)).start(); 

}

2)一个BioServerTask extends Thread(收到客户端请求后进行具体业务处理的一个线程类)

InputStream.read (data)//读取客户端发送的数据

3)一个BioClient(客户端,向服务器监听的IP+Port发送请求)

Socket(ip+port)//向指定ip+port发起连接请求

OutputStream.writer(data//往指定ip+port发送数据

2.高并发场景下Bio存在的弊端

高并发场景下Bio存在的弊端就会被暴露出来:
1)首先在ServerSocket.accpet()时就会发生阻塞,如果没有客户端连接请求,服务器会一直被阻塞在这里什么也做不了(不优雅高效);

2)其次,当接收到一个客户端请求后,服务端会创建一个业务处理线程进行具体业务处理,而new Thread这个操作比较耗时(需要jvm分配一段内存空间)。假设并发量为50000qps(query per seconds 每秒请求数),创建一个线程耗时为0.0001s,将数量级同步缩小一千倍,并发量50qps,耗时0.1s,相当于在这被消耗的0.1s的时间窗口内,请求只能等待,暂时得不到处理。单位再换算以下,1s有50个请求=0.1s有5个请求,在这被线程创建所消耗的0.1s内有5个左右的请求同时到达,服务器只能处理其中一个,其余4个请求丢失了。

Tomcat默认配置下能支持100-150qps并发量,当并发量在150-300qps时会出现200ms延迟,当并发量超过300qps时会出现500ms延迟并伴随部分连接丢失。

3)在进行具体业务处理时,先要把客户端发送的数据接收过来,接收数据的过程中会出现阻塞和二级复制,高并发场景下效率也不高,可能会影响用户体验:

(1)阻塞出现在InputStream.read()这个方法,此方法要求数据完整性,要一次性将数据传输过来,在传输过程中程序会卡住;

(2)二级复制的产生过程:与服务器建立连接后,客户端向服务器传输数据,数据首先经过基于HTTP协议的网络层复制到Linux操作系统(将数据复制到Linux Kernel的缓冲区,一次只接收一部分数据,像个小杯子,而不是一次性接收全部数据),JVM再把数据从内核复制到JVM中(JVM不断从内核缓冲区(小杯子)里取出数据最后组成完整数据),应用程序从JVM中读取数据。过程比较复杂,数据传输效率也不高。示意图如下:

3.Nio中的连接和数据传输都基于事件处理。

1)服务端不必一直去监听是否有客户端发起连接请求接着再去进行具体业务逻辑处理,而是通过事件注册、事件轮询器和事件通知的这一整套事件处理机制,将服务器从原先一直处于的监听状态中给解放出来。

2)每次收到一个客户端连接请求后也不必再去创建新的线程去进行业务处理,对每个连接请求处理在一个连接池中统一管理,当进行业务处理所需的条件/状态事件准备好时(比如数据可读),事件处理机制会通知处于连接池中的某个连接请求进行后续处理。

3)数据传输时服务器也不会因为一次读取不到完整数据而产生阻塞(当数据传输完毕可读取的时候,会被当作一个事件通知服务器,这时服务器再去读取数据)。

4)客户端与应用程序进行数据传输时,可通过Nio提供的一个叫buffer的东西经由Channel(管道,双向可读可写,可以异步读写,通道中的数据总是要先读到一个buffer或总要先从一个buffer写入)与Linux Kernel缓冲区进行直接的读写实时数据操作(这个buffer应该具有将读取到的一块块数据依据某些信息组合成完整数据且能保证数据正确性的一些功能),这样就避免了两级复制。

5)Nio基于事件机制对客户连接请求及数据传输的逻辑处理示意图如下:
image.png

​# 4.总结
本文深入探讨了在Linux系统上使用Tomcat部署Java应用程序时,BIO(阻塞I/O)和NIO(非阻塞I/O)在网络编程中的实现和性能差异。BIO在高并发场景下由于其基于每个连接创建新线程的模型,导致性能瓶颈和资源消耗问题。相比之下,NIO采用事件驱动机制,通过事件注册、事件轮询和事件通知,实现了更高效的连接管理和数据传输,避免了阻塞和多级数据复制,从而显著提升了系统的并发处理能力。

在BIO模型中,服务器在接收客户端连接请求时可能会阻塞,且每次接收请求都需要创建新线程,这在高并发情况下会导致延迟和资源浪费。此外,数据传输过程中的阻塞和二级复制也会影响效率。而NIO则通过使用缓冲区(Buffer)和通道(Channel)直接与操作系统的缓冲区进行数据读写,避免了这些性能问题。

通过代码示例和原理示意图,详细解释了BIO和NIO的技术实现,以及它们在处理高并发请求时的不同表现。NIO的事件驱动模型不仅提高了性能,还减少了资源消耗,使其成为处理高并发网络应用的更佳选择。

目录
相关文章
|
1月前
|
网络协议 Dubbo Java
一文搞懂NIO、AIO、BIO的核心区别(建议收藏)
本文详细解析了NIO、AIO、BIO的核心区别,NIO的三个核心概念,以及NIO在Java框架中的应用等。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
一文搞懂NIO、AIO、BIO的核心区别(建议收藏)
|
7天前
|
监控 Java API
探索Java NIO:究竟在哪些领域能大显身手?揭秘原理、应用场景与官方示例代码
Java NIO(New IO)自Java SE 1.4引入,提供比传统IO更高效、灵活的操作,支持非阻塞IO和选择器特性,适用于高并发、高吞吐量场景。NIO的核心概念包括通道(Channel)、缓冲区(Buffer)和选择器(Selector),能实现多路复用和异步操作。其应用场景涵盖网络通信、文件操作、进程间通信及数据库操作等。NIO的优势在于提高并发性和性能,简化编程;但学习成本较高,且与传统IO存在不兼容性。尽管如此,NIO在构建高性能框架如Netty、Mina和Jetty中仍广泛应用。
23 3
|
16天前
|
缓存 NoSQL Java
高并发场景秒杀抢购超卖Bug实战重现
在电商平台的秒杀活动中,高并发场景下的抢购超卖Bug是一个常见且棘手的问题。一旦处理不当,不仅会引发用户投诉,还会对商家的信誉和利益造成严重损害。本文将详细介绍秒杀抢购超卖Bug的背景历史、业务场景、底层原理以及Java代码实现,旨在帮助开发者更好地理解和解决这一问题。
47 12
|
1月前
|
Java
BIO、NIO、AIO 有什么区别
BIO(阻塞I/O)模型中,服务器实现模式为一个连接一个线程;NIO(非阻塞I/O)使用单线程或少量线程处理多个请求;AIO(异步I/O)则是在NIO基础上进一步优化,采用事件通知机制,提高并发处理能力。
59 5
|
1月前
|
消息中间件 监控 Java
BIO、NIO、AIO在不同场景下的应用对比
BIO(阻塞I/O)、NIO(非阻塞I/O)和AIO(异步I/O)是Java中处理I/O操作的三种模式。BIO适用于连接数少且稳定的场景;NIO通过非阻塞模式提高并发处理能力,适合高并发场景;AIO则完全异步,适合需要高效、低延迟的I/O操作场景。
105 4
|
1月前
|
缓存 监控 Java
Java 线程池在高并发场景下有哪些优势和潜在问题?
Java 线程池在高并发场景下有哪些优势和潜在问题?
|
2月前
|
NoSQL Java Redis
京东双十一高并发场景下的分布式锁性能优化
【10月更文挑战第20天】在电商领域,尤其是像京东双十一这样的大促活动,系统需要处理极高的并发请求。这些请求往往涉及库存的查询和更新,如果处理不当,很容易出现库存超卖、数据不一致等问题。
72 1
|
2月前
|
并行计算 算法 搜索推荐
探索Go语言的高并发编程与性能优化
【10月更文挑战第10天】探索Go语言的高并发编程与性能优化
|
5月前
|
Java 大数据
解析Java中的NIO与传统IO的区别与应用
解析Java中的NIO与传统IO的区别与应用
|
5月前
|
Java
Java中的NIO编程详解
Java中的NIO编程详解