久久精品人人爽,华人av在线,亚洲性视频网站,欧美专区一二三

怎么深入理解Linux高性能網絡架構

160次閱讀
沒有評論

共計 4175 個字符,預計需要花費 11 分鐘才能閱讀完成。

本篇文章為大家展示了怎么深入理解 Linux 高性能網絡架構,內容簡明扼要并且容易理解,絕對能使你眼前一亮,通過這篇文章的詳細介紹希望你能有所收獲。 

1. 落寞的小黑

上周北京很冷,周五晚上大白下班奔地鐵站,收到了好基友小黑的微信:

于是大白掉頭掃了個單車奔五道口了,小黑靠譜地選了個不錯的位置。

小黑: 你今天下班挺早呀!

大白: 就咱這覺悟,心里有工作,哪里都是辦公桌,不要拘泥于形式嘛。

明顯能感覺得到小黑哥最近好像比較累,之前眼里 bulingbuling 閃的光是看不到了。

大白: 下午去面的哪家? 啥崗位? 咋樣?

小黑: 是一家做自動駕駛的創業公司,網站是看團隊介紹還不錯,就去看看了,這次沒咋準備,很多問題其實都熟悉,但是回答的不到位。

大白: 哦,明白了,那就是當時理解的不到位,稀里糊涂過去了,現在忽然問起來,想不起重點。

小黑: 差不多吧,問我都做過哪些高性能的網絡框架模型,也就是 IO 和事件驅動那一套。

話說完,小黑喝了一大口啤酒,大白看出了小黑心里有一些落寞。畢竟在帝都這個地方競爭和工作壓力,以及生活瑣事都一直圍繞著我們,但是金錢和好運都巧妙地避開了自己 …

想到這里,大白也深深喝了一大口,我命由我不由天,開整!

大白:黑哥,你說這個問題確實不好回答,全是術語和略帶歧義的東西,我覺得我們抓住本質去闡述就好。

小黑:來,請開始你的表演,我學習學習。

大白決定和小黑好好聊聊,Linux 開發中常用的高性能網絡框架中的一些事兒,火鍋的映襯下讓夜色和天氣都不那么寒冷了。

通過本文你將會了解到以下內容:

IO 事件和 IO 復用

線程模型和事件驅動模型的架構

基于事件驅動的 Reactor 模式詳解

同步 IO 和異步 IO 簡介

2. IO 事件和 IO 復用

2.1 什么是 IO 事件

IO 指的是輸入 Input/ 輸出 Output,但是從漢語角度來說,出和入是相對的,所以我們需要個參照物。這里我們的參照物選擇為程序運行時的主存儲空間,外部通常包括網卡、磁盤等。有了上述的設定理解起來就方便多了,我們來一起看下:

IO 的本質是數據的流動,數據可以從網卡到程序內存,也可以從程序內存寫到網卡,磁盤操作也是如此。

所以可以把常見的 IO 分為:

網絡 IO:內存和網卡的數據交互

文件 IO:內存和磁盤的數據交互

那什么又是 IO 事件呢? 事件可以理解為一種狀態或者動作,也就是狀態的遷移會觸發一種相應的動作。網絡 IO 的事件通常包括:

可讀事件

可寫事件

異常事件

理解可讀可寫事件是非常有必要的,一般來說一個 socket 大部分時候是可寫的,但是并不是都可讀。可讀一般代表是一個新連接或者原有連接有新數據交互,對于服務端程序來說也是重點關注的事件。

2.2 什么是 IO 復用

設想假如有幾萬個 IO 事件,那么應用程序該如何管理呢? 這就要提到 IO 復用了。IO 復用從本質上來說就是應用程序借助于 IO 復用函數向內核注冊很多類型的 IO 事件,當這些注冊的 IO 事件發生變化時內核就通過 IO 復用函數來通知應用程序。

從圖中可以看到,IO 復用中復用的就是一個負責監聽管理這些 IO 事件的線程。之所以可以實現一個線程管理成百上千個 IO 事件,是因為大部分時間里某個時刻只有少量 IO 事件被觸發。

大概就像這樣:草原上的一只大狗可以看管幾十只綿羊,因為大部分時候只有個別綿羊不守規矩亂跑,其他的都是乖乖吃草。

3. 網絡框架設計要素

要理解網絡框架有哪些,必須要清楚網絡框架完成了哪些事情。

大致描述下這個請求處理的流程:

遠端的機器 A 發送了一個 HTTP 請求到服務器 B,此時服務器 B 網卡接收到數據并產生一個 IO 可讀事件;

我們以同步 IO 為例,此時內核將該可讀事件通知到應用程序的 Listen 線程;

Listen 線程將任務甩給 Handler 線程,由 Handler 將數據從內核讀緩沖區拷貝到用戶空間讀緩沖區;

請求數據包在應用程序內部進行計算和處理并封裝響應包;

Handler 線程等待可寫事件的到來;

當這個連接可寫時將數據從用戶態寫緩沖區拷貝到內核緩沖區,并通過網卡發送出去;

備注:上述例子是以同步 IO 為例,并且將線程中的角色分為 Listen 線程、Handler 線程、Worker 線程,分別完成不同的工作,后續會詳細展開。

所以我們可以知道,要完成一個數據交互,涉及了幾大塊內容:

IO 事件監聽

數據拷貝

數據處理和計算

大白認為,這三大塊內容,不論什么形式的框架都繞不開,也是理解網絡架構的關鍵所在。

4. 高性能網絡框架實踐

4.1 基于線程模型

在早期并發數不多的場景中,有一種 One Request One  Thread 的架構模式。該模式下每次接收一個新請求就創建一個處理線程,線程雖然消耗資源并不多,但是成千上萬請求打過來,性能也是扛不住的。

這是一種比較原始的架構,思路也非常清晰,創建多個線程來提供處理能力,但在高并發生產環境中幾乎沒有應用,本文不再展開。

4.2 基于事件驅動模型

當前流行的是基于事件驅動的 IO 復用模型,相比多線程模型優勢很明顯。

在此我們先理解一下什么是事件驅動 Event-Drive-Model。

事件驅動編程是一種編程范式,程序的執行流由外部事件來決定,它的特點是包含一個事件循環,當外部事件發生時使用回調機制來觸發相應的處理。

通俗來說就是:有一個循環裝置在一直等待各種事件的到來,并將到達的事件放到隊列中,再由一個分揀裝置來調用對應的處理裝置來響應。

4.3 Reactor 反應堆模式

第一次聽到這個模式的時候很困惑,究竟反應堆是個啥? 研究了一下發現,反應堆是個核物理的概念,大致是這個樣子的:

核反應堆是核電站的心臟,它的工作原理是這樣的:原子由原子核與核外電子組成,原子核由質子與中子組成。

當鈾 235 的原子核受到外來中子轟擊時,一個原子核會吸收一個中子分裂成兩個質量較小的原子核,同時放出 2 - 3 個中子。

這裂變產生的中子又去轟擊另外的鈾 235 原子核,引起新的裂變,如此持續進行就是裂變的鏈式反應。

結合這種核裂變的圖,好像是一個請求打過來,服務器內部瞬間延伸出很多分支來完成響應,一變二,二變四,甚至更多,確實有種反應堆的感覺。接下來我們看看究竟反應堆模式是如何構建高性能網絡框架的。

5. 反應堆模式詳解

反應堆模式是一種思想,形式卻有很多種。

5.1 反應堆模式的本質是什么

從本質上理解,無論什么網絡框架都要完成兩部分操作:

IO 操作:數據包的讀取和寫入

CPU 操作:數據請求的處理和封裝

所以上述這些問題由誰來做以及多少線程來做,就衍生出了很多形式,所以不要被表面現象迷惑,出現必有原因,追溯之后我們才能真正掌握它。

反應堆模式根據處理 IO 環節和處理數據環節的數量差異分為如下幾種:

單 Reactor 線程

單 Reactor 線程和線程池

多 Reactor 線程和線程池

我們來看看這三種常見模式的特點、原理、優缺點、應用場景等。

5.2 單 Reactor 線程模式

這種模式最為簡潔,一個線程完成了連接的監聽、接收新連接、處理連接、讀取數據、寫入數據全套工作。由于只使用了一個線程,對于多核利用率偏低,但是編程簡單。是不是覺得這個種單線程的模式沒有市場? 那可未必,不信你看 Redis。

在這種模式種 IO 操作和 CPU 操作是沒有分開的,都是由 1 個線程來完成的,顯然如果在 Handler 處理某個請求超時了將會阻塞客戶端的正常連接。在 Redis 中由于都是內存操作,速度很快,這種瓶頸雖然存在但是不夠明顯。

5.3 單 Reactor 線程和線程池模式

為了解決 IO 操作和 CPU 操作的不匹配,也就是 IO 操作和 CPU 操作是在一個線程內部串行執行的,這樣就拉低了 CPU 操作效率。

一種解決方法就是將 IO 操作和 CPU 操作分別由單獨的線程來完成,各玩各的互不影響。單 Reactor 線程完成 IO 操作、復用工作線程池來完成 CPU 操作就是一種解決思路。

在這種模式種由 Reactor 線程完成連接的管理和數據讀取 寫回,完全掌管 IO 操作。工作線程池處理來自上游分發的任務,對其中的數據進行解碼、計算、編碼再返回給 Reactor 線程和客戶端完成交互。這種模式有效利用了多核,但是單 Reactor 線程來完成 IO 操作在高并發場景中仍然會出現瓶頸。換句話說,連接實在太多了,一個 Reactor 線程忙不過來建立新連接和響應舊連接這些事情,因此 Reactor 線程也需要幾個幫手。

5.4 多 Reactor 線程和線程池模式

水平擴展往往是提供性能的有效方法。

我們將 Reactor 線程進行擴展,一個 Reactor 線程負責處理新連接,多個 Reactor 線程負責處理連接成功的 IO 數據讀寫。也就是進一步將監聽 創建連接   和 處理連接 分別由兩個及以上的線程來完成,進一步提高了 IO 操作部分的效率。

這種模式算是比較高配的版本了,在實際生產環境也有使用。

5.5 拓展:同步 IO 和異步 IO

我們可以輕易區分什么是阻塞 IO 和非阻塞 IO,那么什么是同步 IO 和異步 IO 呢? 前面提到 Reactor 模式其中非常重要的一環就是調用 read/write 函數來完成數據拷貝,這部分是應用程序自己完成的,內核只負責通知監控的事件到來了,所以本質上 Reactor 模式屬于非阻塞同步 IO。還有一種 Preactor 模式,借助于系統本身的異步 IO 特性,由操作系統進行數據拷貝,在完成之后來通知應用程序來取就可以,效率更高一些,但是底層需要借助于內核的異步 IO 機制來實現。

底層的異步 IO 機制可能借助于 DMA 和 Zero-Copy 技術來實現,理論上性能更高。當前 Windows 系統通過 IOCP 實現了真正的異步 I /O,而在 Linux   系統的異步 I / O 還不完善,比如 Linux 中的 boost.asio 模塊就是異步 IO 的支持,但是目前 Linux 系統還是以基于 Reactor 模式的非阻塞同步 IO 為主。

6. 小結

本文從 IO 事件和 IO 復用出發,闡述了網絡架構最底層的組成。繼續展開了基于線程模型和基于事件驅動模型的網絡框架特點及其設計要素。之后重點描述了反應堆模式的核心本質,以及生產環境中的多種形式。最后簡單介紹了同步 IO 和異步 IO 的區別,以及 Preactor 模式的優勢。希望讀者朋友可以摒棄專業術語和表述,抓住問題的本質和重點,找到一個適合自己思維方法去理解和掌握高性能網絡架構的設計之道。或許,高性能網絡框架只是一個紙老虎。

上述內容就是怎么深入理解 Linux 高性能網絡架構,你們學到知識或技能了嗎?如果還想學到更多技能或者豐富自己的知識儲備,歡迎關注丸趣 TV 行業資訊頻道。

正文完
 
丸趣
版權聲明:本站原創文章,由 丸趣 2023-08-25發表,共計4175字。
轉載說明:除特殊說明外本站除技術相關以外文章皆由網絡搜集發布,轉載請注明出處。
評論(沒有評論)
主站蜘蛛池模板: 衡南县| 华宁县| 开原市| 天水市| 邢台市| 荃湾区| 清河县| 兴隆县| 三门峡市| 高尔夫| 兴和县| 鄂托克旗| 嘉禾县| 来安县| 新蔡县| 土默特右旗| 阿瓦提县| 贺州市| 宽城| 剑阁县| 公安县| 扎赉特旗| 西青区| 秀山| 嘉黎县| 东港市| 临武县| 青川县| 博爱县| 峨眉山市| 富阳市| 西乌珠穆沁旗| 康平县| 龙南县| 大邑县| 娄底市| 万年县| 游戏| 龙游县| 牙克石市| 徐水县|