Netty面试深度解析:BIO、NIO与AIO对比

版权申诉
0 下载量 136 浏览量 更新于2024-09-07 收藏 312KB PDF 举报
"Netty面试专题及答案涵盖了BIO、NIO和AIO的区别,以及NIO的组成和相关操作。" 在Java的网络编程中,BIO(Blocking IO)、NIO(Non-blocking IO)和AIO(Asynchronous IO)是三种不同的I/O模型,它们在处理并发连接和资源管理方面有所不同。 1. **BIO(阻塞IO)**:在BIO模型中,每一个客户端的连接都需要一个独立的线程进行处理。当客户端发起请求时,服务器会为这个请求创建一个新的线程,并保持这个线程直到服务完成。这种模型在面对大量并发连接时,线程资源消耗大,可能导致服务器性能下降甚至线程耗尽。 2. **伪异步IO**:这是一种改进的BIO,通过线程池处理多个连接,但本质上仍然是阻塞的,线程仍然会被每个连接的I/O操作阻塞。 3. **NIO(非阻塞IO)**:NIO的核心在于多路复用器(Selector),它允许单个线程处理多个连接。客户端的连接请求会被注册到Selector,Selector轮询检查哪些连接有I/O事件,然后启动线程处理。NIO的特点包括事件驱动、单线程处理多任务、非阻塞I/O,以及基于缓冲区的传输,使得其在处理高并发场景时更具优势。 4. **AIO(异步IO)**:AIO也称为NIO 2,与NIO不同的是,AIO在操作系统层面完成了真正的异步I/O操作,即客户端的I/O请求由操作系统先处理,待操作完成后才通知服务器应用程序。这样避免了服务器端线程的阻塞,提升了效率。 **NIO的组成主要包括:** - **Buffer(缓冲区)**:Buffer是与Channel进行交互的基础,数据从Channel读入Buffer,再从Buffer写入Channel。Buffer提供了一些方法如`flip()`(切换读写模式),`clear()`(清空缓冲区),和`rewind()`(重置位置)等。 - **Channel(通道)**:代表IO源与目标之间的连接,可以双向读写,但不直接操作数据,而是通过Buffer进行数据交换。 - **Selector(选择器)**:用于监听多个Channel上的事件,比如连接请求、数据到达等,通过注册和选择操作,使得单线程可以处理多个连接。 - **Pipe(管道)**:用于两个线程间的通信,一个线程写入,另一个线程读取。 **DirectByteBuffer**:在NIO中,直接缓冲区通过避免Java堆与系统内存间的额外复制,提高了性能,特别适用于大型、持久的缓冲区。然而,它的创建和销毁成本较高,因此对于小数据量的应用,可能会考虑使用HeapBuffer,由JVM直接管理,性能相对较低但更可控。 在Netty框架中,充分利用了NIO的特性,采用Reactor线程模型,实现了高效的网络通信。在Reactor模式下,事件分发器等待事件发生,然后调用预先注册的处理器来执行实际的读写操作,极大地提高了并发处理能力,使得Netty成为高性能、高并发网络应用的理想选择。

com.fmall58.wechatsub.business.bizs.UException at com.fmall58.wechatsub.business.service.PubService.isBindWeChatSub(PubService.java:76) at com.fmall58.wechatsub.business.bizs.PubHelper.isBindWeChatSub(PubHelper.java:125) at com.fmall58.wechatsub.business.bizs.PubHelper.execute(PubHelper.java:38) at com.fmall58.wechatsub.server.handlers.ServerHandler.channelRead(ServerHandler.java:103) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348) at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340) at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:102) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348) at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340) at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:323) at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:297) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348) at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340) at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1434) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348) at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:965) at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:163) at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:656) at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:591) at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:508) at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:470) at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:909) at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)

2023-06-11 上传
2023-06-12 上传

2023-07-14 15:19:01.215 WARN 7308 --- [sson-netty-2-15] io.netty.util.concurrent.DefaultPromise : An exception was thrown by org.redisson.misc.RedissonPromise$$Lambda$888/0x00000008008f7440.operationComplete() java.lang.NullPointerException: null 2023-07-14 15:19:01.216 ERROR 7308 --- [sson-netty-2-15] o.r.c.SentinelConnectionManager : Can't execute SENTINEL commands on /172.24.107.11:26379 org.redisson.client.RedisException: ERR No such master with that name. channel: [id: 0x2d66827d, L:/172.23.9.103:46812 - R:/172.24.107.11:26379] command: (SENTINEL SLAVES), params: [mymaster] at org.redisson.client.handler.CommandDecoder.decode(CommandDecoder.java:365) ~[redisson-3.13.3.jar:3.13.3] at org.redisson.client.handler.CommandDecoder.decodeCommand(CommandDecoder.java:196) ~[redisson-3.13.3.jar:3.13.3] at org.redisson.client.handler.CommandDecoder.decode(CommandDecoder.java:134) ~[redisson-3.13.3.jar:3.13.3] at org.redisson.client.handler.CommandDecoder.decode(CommandDecoder.java:104) ~[redisson-3.13.3.jar:3.13.3] at io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:501) ~[netty-codec-4.1.51.Final.jar:4.1.51.Final] at io.netty.handler.codec.ReplayingDecoder.callDecode(ReplayingDecoder.java:366) ~[netty-codec-4.1.51.Final.jar:4.1.51.Final] at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:276) ~[netty-codec-4.1.51.Final.jar:4.1.51.Final] at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) ~[netty-transport-4.1.51.Final.jar:4.1.51.Final] at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) ~[netty-transport-4.1.51.Final.jar:4.1.51.Final] at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357) ~[netty-transport-4.1.51.Final.jar:4.1.51.Final] at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410) ~[netty-transport-4.1.51.Final.jar:4.1.51.Final] at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) ~[netty-transport-4.1.51.Final.jar:4.1.51.Final] at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) ~[netty-transport-4.1.51.Final.jar:4.1.51.Final] at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919) ~[netty-transport-4.1.51.Final.jar:4.1.51.Final] at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:163) ~[netty-transport-4.1.51.Final.jar:4.1.51.Final] at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:714) ~[netty-transport-4.1.51.Final.jar:4.1.51.Final] at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:650) ~[netty-transport-4.1.51.Final.jar:4.1.51.Final] at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:576) ~[netty-transport-4.1.51.Final.jar:4.1.51.Final] at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:493) ~[netty-transport-4.1.51.Final.jar:4.1.51.Final] at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:989) ~[netty-common-4.1.51.Final.jar:4.1.51.Final] at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) ~[netty-common-4.1.51.Final.jar:4.1.51.Final] at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) ~[netty-common-4.1.51.Final.jar:4.1.51.Final] at java.base/java.lang.Thread.run(Thread.java:834) ~[na:na] 解决方法

2023-07-15 上传