一文徹底搞懂 BIO、NIO、AIO —— 架構(gòu)圖 + Netty Reactor + epoll 原理(面試高頻)

在 Java 高并發(fā)網(wǎng)絡(luò)編程中,I/O 模型是最核心的基礎(chǔ)之一
如果你學(xué)習(xí)過 Netty、Redis、Nginx、網(wǎng)關(guān)、RPC 框架,一定會遇到三個概念:

  • BIO(Blocking IO)
  • NIO(Non-Blocking IO)
  • AIO(Asynchronous IO)

很多文章只是簡單介紹概念,但真正面試或者做系統(tǒng)設(shè)計(jì)時(shí),需要理解:

  • I/O 架構(gòu)圖
  • Reactor 模型
  • Linux epoll
  • Netty 線程模型

這篇文章會 從架構(gòu) → 底層 → 面試題完整講清楚。


一、三種 I/O 模型對比(超清架構(gòu)圖)

1 BIO 架構(gòu)圖(同步阻塞)

                Server
                  │
        ┌─────────┼─────────┐
        │         │         │
     Thread1   Thread2   Thread3
        │         │         │
     Client1   Client2   Client3

工作方式:

客戶端連接
      ↓
創(chuàng)建線程
      ↓
線程阻塞等待數(shù)據(jù)
      ↓
處理請求

特點(diǎn):

  • 一個連接 → 一個線程
  • 線程會阻塞等待 IO

問題:

10000 個連接
≈
10000 個線程

會導(dǎo)致:

  • 線程上下文切換嚴(yán)重
  • 內(nèi)存消耗巨大
  • CPU 利用率低

因此 BIO 不適合高并發(fā)系統(tǒng)


二、NIO 架構(gòu)圖(非阻塞 IO)

NIO 的核心思想:

一個線程管理多個連接

架構(gòu):

                     ┌──────────────┐
Client1 ───────────→ │              │
Client2 ───────────→ │              │
Client3 ───────────→ │   Selector   │
Client4 ───────────→ │              │
Client5 ───────────→ │              │
                     └──────┬───────┘
                            │
                        Worker
                            │
                       業(yè)務(wù)處理

流程:

客戶端連接
      ↓
注冊到 Selector
      ↓
Selector 監(jiān)聽事件
      ↓
有 IO 事件觸發(fā)
      ↓
線程處理

NIO 核心組件:

Channel
Buffer
Selector

特點(diǎn):

  • 一個線程管理多個連接
  • 事件驅(qū)動
  • 非阻塞

適合:

高并發(fā)服務(wù)器
聊天系統(tǒng)
網(wǎng)關(guān)系統(tǒng)

三、AIO 架構(gòu)圖(異步 IO)

AIO 的核心思想:

操作系統(tǒng)負(fù)責(zé)完成 IO
完成后通知程序

架構(gòu):

Application
     │
發(fā)起 IO 請求
     │
     ▼
Operating System
     │
執(zhí)行 IO
     │
IO 完成
     │
回調(diào)通知
     ▼
Application Callback

流程:

提交 IO 請求
      ↓
系統(tǒng)異步執(zhí)行
      ↓
IO 完成
      ↓
回調(diào)通知程序

特點(diǎn):

  • 真正異步
  • 不需要輪詢
  • 編程復(fù)雜

但在 Linux 上:

支持不夠成熟

所以實(shí)際使用 遠(yuǎn)少于 NIO。


四、Netty Reactor 模型

Netty 使用的是:

NIO + Reactor

Reactor 是一種 事件驅(qū)動架構(gòu)模型

核心思想:

監(jiān)聽事件
     ↓
分發(fā)事件
     ↓
處理事件

Reactor 架構(gòu)圖

                ┌──────────────┐
Client Request →│   Reactor    │
                └──────┬───────┘
                       │
                 Event Dispatch
                       │
          ┌────────────┴────────────┐
          │                         │
     Handler1                  Handler2
          │                         │
     Business Logic           Business Logic

作用:

統(tǒng)一監(jiān)聽 IO 事件
統(tǒng)一分發(fā)業(yè)務(wù)處理

五、Netty 完整線程模型圖(主從 Reactor)

Netty 實(shí)際使用:

主從 Reactor 模型

線程結(jié)構(gòu):

                ┌──────────────┐
Client ───────→ │  BossGroup   │
                └──────┬───────┘
                       │
                  接收連接
                       │
                       ▼
                ┌──────────────┐
                │ WorkerGroup  │
                └──────┬───────┘
                       │
               處理讀寫 IO 事件
                       │
                       ▼
                ┌──────────────┐
                │  Pipeline    │
                └──────┬───────┘
                       │
             Handler1 → Handler2 → Handler3
                       │
                   業(yè)務(wù)處理

執(zhí)行流程:

客戶端連接
      ↓
Boss 接收連接
      ↓
分配到 Worker
      ↓
Worker 處理 IO
      ↓
Pipeline 執(zhí)行業(yè)務(wù) Handler

優(yōu)勢:

  • 線程模型清晰
  • 支持高并發(fā)
  • 擴(kuò)展性強(qiáng)

六、NIO + epoll 底層原理

NIO 在 Linux 上依賴:

epoll

epoll 是 Linux 的 高性能 IO 多路復(fù)用機(jī)制。


傳統(tǒng) select / poll

早期 IO 模型:

select
poll

問題:

需要遍歷所有連接

假設(shè):

10000 個連接
只有 1 個有數(shù)據(jù)

select 仍然要:

遍歷 10000 次

效率低。


epoll 工作方式

epoll 使用:

事件通知機(jī)制

架構(gòu):

              ┌────────────┐
Client Conn → │   epoll    │
              └─────┬──────┘
                    │
            有事件的連接
                    │
                 返回
                    │
                 程序處理

優(yōu)勢:

只返回有事件的連接

復(fù)雜度:

O(1)

因此:

Redis
Nginx
Netty
Kafka

全部基于 epoll。


七、BIO / NIO / AIO 對比總結(jié)

模型 類型 線程模型 并發(fā)能力
BIO 同步阻塞 一連接一線程
NIO 同步非阻塞 少量線程
AIO 異步非阻塞 回調(diào) 極高

一句話總結(jié):

BIO:線程等待 IO
NIO:線程輪詢 IO
AIO:系統(tǒng)完成 IO

八、大廠面試高頻題(10題)

1 BIO、NIO、AIO 的區(qū)別?

核心區(qū)別:

BIO:同步阻塞
NIO:同步非阻塞
AIO:異步非阻塞

2 為什么 NIO 可以支持高并發(fā)?

因?yàn)椋?/p>

一個線程可以管理多個連接

減少:

  • 線程創(chuàng)建
  • 線程切換
  • 內(nèi)存開銷

3 NIO 三大核心組件?

Channel
Buffer
Selector

4 什么是 IO 多路復(fù)用?

IO 多路復(fù)用:

一個線程監(jiān)聽多個 IO

典型實(shí)現(xiàn):

select
poll
epoll

5 epoll 為什么比 select 快?

因?yàn)椋?/p>

epoll 不需要遍歷所有連接

只返回:

有事件的連接

6 Netty 為什么這么快?

原因:

NIO
Reactor 模型
epoll
零拷貝
線程池

7 什么是 Reactor 模型?

Reactor 是一種:

事件驅(qū)動架構(gòu)

核心流程:

事件監(jiān)聽
事件分發(fā)
事件處理

8 Netty 為什么不用 AIO?

原因:

Linux AIO 不成熟
NIO 已經(jīng)足夠快
生態(tài)更穩(wěn)定

9 什么是零拷貝?

零拷貝指:

減少 CPU 數(shù)據(jù)復(fù)制

提升:

網(wǎng)絡(luò) IO 性能

10 Netty 的線程模型是什么?

Netty 使用:

主從 Reactor

結(jié)構(gòu):

BossGroup
WorkerGroup
Pipeline
Handler

九、總結(jié)

Java 網(wǎng)絡(luò) IO 發(fā)展:

BIO  →  NIO  →  AIO

但在實(shí)際工程中:

NIO + Reactor + epoll

仍然是 高并發(fā)服務(wù)器的主流架構(gòu)

所以像:

Netty
Redis
Nginx
Kafka

底層思想幾乎一致。

如果你想深入 Netty / 高并發(fā) / 分布式系統(tǒng),理解這套 IO 模型是非常重要的一步。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容