高性能開發十大必須掌握的核心技術

csdn 發佈 2020-08-22T07:39:48+00:00

這篇文章,我們循序漸進,從內存、磁碟I/O、網絡I/O、CPU、緩存、架構、算法等多層次遞進,串聯起高性能開發十大必須掌握的核心技術。

作者 | 軒轅之風O

來源 | 編程技術宇宙(ID: xuanyuancoding)

程式設計師經常要面臨的一個問題就是:如何提高程序性能?

這篇文章,我們循序漸進,從內存、磁碟I/O、網絡I/O、CPU、緩存、架構、算法等多層次遞進,串聯起高性能開發十大必須掌握的核心技術。

首先,我們從最簡單的模型開始。

老闆告訴你,開發一個靜態 web 伺服器,把磁碟文件(網頁、圖片)通過網絡發出去,怎麼做?

你花了兩天時間,擼了一個1.0版本:

  • 主線程進入一個循環,等待連接。

  • 來一個連接就啟動一個工作線程來處理。

  • 工作線程中,等待對方請求,然後從磁碟讀文件、往套接口發送數據。

上線一天,老闆發現太慢了,大一點的圖片加載都有卡頓感。讓你優化,這個時候,你需要:

I/O 優化:零拷貝技術

上面的工作線程,從磁碟讀文件、再通過網絡發送數據,數據從磁碟到網絡,兜兜轉轉需要拷貝四次,其中 CPU 親自搬運都需要兩次。

零拷貝技術,解放 CPU,文件數據直接從內核發送出去,無需再拷貝到應用程式緩衝區,白白浪費資源。

Linux API:

ssize_t sendfile(

int out_fd,

int in_fd,

off_t *offset,

size_t count

);

函數名字已經把函數的功能解釋的很明顯了:發送文件。指定要發送的文件描述符和網絡套接字描述符,一個函數搞定!

用上了零拷貝技術後開發了2.0版本,圖片加載速度明顯有了提升。不過老闆發現同時訪問的人變多了以後,又變慢了,又讓你繼續優化。這個時候,你需要:

I/O 優化:多路復用技術

前面的版本中,每個線程都要阻塞在 recv 等待對方的請求,這來訪問的人多了,線程開的就多了,大量線程都在阻塞,系統運轉速度也隨之下降。

這個時候,你需要多路復用技術,使用 select 模型,將所有等待(accept、recv)都放在主線程里,工作線程不需要再等待。

過了一段時間之後,網站訪問的人越來越多了,就連 select 也開始有點應接不暇,老闆繼續讓你優化性能。

這個時候,你需要升級多路復用模型為 epoll。

select 有三弊,epoll 有三優。

  • select 底層採用數組來管理套接字描述符,同時管理的數量有上限,一般不超過幾千個,epoll 使用樹和鍊表來管理,同時管理數量可以很大。

  • select 不會告訴你到底哪個套接字來了消息,你需要一個個去詢問。epoll 直接告訴你誰來了消息,不用輪詢。

  • select 進行系統調用時還需要把套接字列表在用戶空間和內核空間來回拷貝,循環中調用 select 時簡直浪費。epoll 統一在內核管理套接字描述符,無需來回拷貝。

用上了 epoll 多路復用技術,開發了3.0版本,你的網站能同時處理很多用戶請求了。

但是貪心的老闆還不滿足,不捨得升級硬體伺服器,卻讓你進一步提高伺服器的吞吐量。你研究後發現,之前的方案中,工作線程總是用到才創建,用完就關閉,大量請求來的時候,線程不斷創建、關閉、創建、關閉,開銷挺大的。這個時候,你需要:

線程池技術

我們可以在程序一開始啟動後就批量啟動一波工作線程,而不是在有請求來的時候才去創建,使用一個公共的任務隊列,請求來臨時,向隊列中投遞任務,各個工作線程統一從隊列中不斷取出任務來處理,這就是線程池技術

關鍵字: