來源:北大青鳥總部 2023年08月07日 11:41
互聯(lián)網(wǎng)的發(fā)展推動了越來越多的企業(yè)加入互聯(lián)網(wǎng),越來越多的產(chǎn)品出現(xiàn)在互聯(lián)網(wǎng),越來越多的網(wǎng)民涌現(xiàn)在互聯(lián)網(wǎng),除了提供基本的服務之外,還需要提供更好玩、更便捷穩(wěn)定的服務,就像手機一樣,我們對它最基本的性能要求就是待機時間長,在互聯(lián)網(wǎng)的性能要求就是不慢不卡,因此性能優(yōu)化技術是互聯(lián)網(wǎng)程序員必須掌握的技術。
一套應用程序能運行起來,除了最上層的前端服務、業(yè)務層算法之外,還有數(shù)據(jù)庫、操作系統(tǒng),因此性能優(yōu)化技術包含了負載均衡技術、緩存技術、數(shù)據(jù)庫技術、RPC技術(RemoteP)、進程通信技術、IO多路復用技術、IO零拷貝技術,互聯(lián)網(wǎng)程序員掌握了這些技術,就像學好了數(shù)理化一樣,走到哪里都是香餑餑。
所謂負載均衡技術,就是用來將計算資源、存儲資源、網(wǎng)絡資源根據(jù)實際情況進行分配的一種技術,通過多個節(jié)點承載服務,用來達到最優(yōu)的資源利用、最快的響應時間,實現(xiàn)了性能優(yōu)化。負載均衡的分類也有很多,有客戶端負載均衡、服務器端負載均衡、軟件負載均衡、硬件負載均衡。以服務端負載均衡為例,用戶在前端發(fā)起請求后,經(jīng)過網(wǎng)絡傳輸給服務端,再通過服務端的負載均衡算法去選擇對應的服務器提供服務,最常見的就是nginx算法了。
在負載均衡之后,便是緩存技術,它是通過將訪問的熱數(shù)據(jù)提前存起來供業(yè)務訪問,降低了數(shù)據(jù)庫壓力、降低了用戶響應時間,實現(xiàn)了性能優(yōu)化。負載均衡把請求分擔為多個節(jié)點執(zhí)行,每個節(jié)點都承載著服務的提供,當用戶請求從前端經(jīng)負載均衡算法分配過來后,如果直接去訪問獲取磁盤的數(shù)據(jù)庫數(shù)據(jù),就會非常慢。如果有了緩存,在用戶請求到達之后,業(yè)務線程就會先訪問緩存,如果緩存命中就直接返回用戶,如果沒有命中,則繼續(xù)請求磁盤數(shù)據(jù)庫數(shù)據(jù),獲取后返回用戶,同時將磁盤獲取的數(shù)據(jù)結果回寫到緩存系統(tǒng),為下次請求做好準備。
在緩存之后便是數(shù)據(jù)庫技術,緩存訪問熱點數(shù)據(jù)后,執(zhí)行的交易操作需要對數(shù)據(jù)庫中的表進行增刪改查,通過將數(shù)據(jù)庫分為主庫、讀庫、大表分為小表,讓每個用戶請求都能快速訪問到數(shù)據(jù)、快速執(zhí)行操作,降低了用戶延遲,實現(xiàn)了性能優(yōu)化。數(shù)據(jù)庫的讀寫分離,使用一臺數(shù)據(jù)庫服務器作為主數(shù)據(jù)庫(master),把業(yè)務數(shù)據(jù)都寫入該數(shù)據(jù)庫,再另外使用另一臺數(shù)據(jù)庫服務器來作為從數(shù)據(jù)庫(slave),將業(yè)務數(shù)據(jù)同步到該數(shù)據(jù)庫上,當業(yè)務進行讀操作時就讀取備數(shù)據(jù)庫的數(shù)據(jù)即可,這樣即緩解了數(shù)據(jù)庫壓力,又實現(xiàn)了備份。
在數(shù)據(jù)庫技術之后,便是操作系統(tǒng)級別的IO多路復用技術。我們知道一個程序運行時是一個進程,而程序里有很多的方法要去執(zhí)行,每個方法就是一個線程,通過并發(fā)處理客戶端的多個線程請求,并同時等待多個連接發(fā)送的請求,減少系統(tǒng)的開銷、降低用戶延遲,實現(xiàn)了性能優(yōu)化。此外,IO多路復用也不需要額外創(chuàng)建和維護線程監(jiān)聽客戶端的大量連接,減少了服務器的開發(fā)和維護成本。典型的線程級別優(yōu)化技術有java線程池、數(shù)據(jù)庫連接池、PHP內存池。
在IO多路復用技術之后,便是IO零拷貝技術。在操作系統(tǒng)一般把內核劃分成內核空間、用戶空間,Linux操作系統(tǒng)中讀取數(shù)據(jù)操作都是基于數(shù)據(jù)拷貝完成的,也就是說數(shù)據(jù)會在內核地址空間的緩沖區(qū)和用戶地址空間的緩沖區(qū)進行拷貝,數(shù)據(jù)讀取流程一般包含四部分,
1.操作系統(tǒng)需要先從磁盤里讀取文件到內核頁面的緩存;
2.用戶態(tài)的應用程序從內核態(tài)讀取數(shù)據(jù)到用戶空間緩存區(qū),由于內核態(tài)的資源比較寶貴會經(jīng)常釋放;
3.用戶態(tài)的應用程序還需要將數(shù)據(jù)寫回內核空間并放入socket緩沖區(qū);
4.最后操作系統(tǒng)將數(shù)據(jù)從socket緩沖區(qū)復制到網(wǎng)卡接口,再經(jīng)由網(wǎng)絡發(fā)送給到消費者進程。
零拷貝技術,將磁盤文件的數(shù)據(jù)復制到頁面緩存中,然后將數(shù)據(jù)從頁面緩存直接發(fā)送到網(wǎng)絡給到不同的訂閱者,避免了重復拷貝操作,極大的提高了速度,實現(xiàn)了性能優(yōu)化。
從負載均衡、緩存、數(shù)據(jù)庫到IO多路復用、IO零拷貝技術,完成了單服務從業(yè)務級到操作系統(tǒng)級的性能優(yōu)化,但微服務技術的出現(xiàn)將單服務拆分成了多個微服務,對于云原生、微服務時代的性能優(yōu)化,那便是RPC遠程調用技術。
遠程是相對本地而言的概念,本地調用存在的場景是在一個服務中有不同的函數(shù)實現(xiàn)不同的功能,一個函數(shù)要使用另一個函數(shù)的功能,那必然要調用它。在本地函數(shù)調用時,一般會經(jīng)過這幾個步驟,即函數(shù)返回地址入棧、函數(shù)參數(shù)入棧、堆??臻g提升、函數(shù)參數(shù)復制、開始函數(shù)調用、堆棧情況。
當服務拆分成了微服務之后,函數(shù)是在不同的微服務、不同的機器上運行,一臺機器想要調用另一臺機器的函數(shù)執(zhí)行某個功能,只能通過網(wǎng)絡請求來實現(xiàn)(借助兩個服務共同維護的關聯(lián)式容器stub),不能再像本地調用一樣使用函數(shù)指針實現(xiàn)了。有了RPC,不僅是微服務與微服務之間的調用變得簡單,不同語言之間的調用也變得簡單了。
以前JAVA語言想要調用C++語言,那是不可能的事,因為用不同語言寫的代碼,根本無法通信啊。而現(xiàn)在有了RPC,只要框架上支持該語言的解析,那么就可以了。Java語言傳遞過來函數(shù)1的參數(shù)1、參數(shù)2,通過RPC框架解析為C++語言可以識別的參數(shù)1、參數(shù)2。RPC技術通過降低了網(wǎng)絡延遲從而降低了用戶延遲,實現(xiàn)了性能優(yōu)化。
互聯(lián)網(wǎng)從網(wǎng)頁時代走向互聯(lián)網(wǎng)時代、移動互聯(lián)網(wǎng)時代、物聯(lián)網(wǎng)時代,基礎設施從物理機走向虛擬機、容器,技術架構也從單體式服務走向SOA、微服務、分布式,一切技術都在不斷的進化演變,唯一不變的便是性能優(yōu)化技術。從單服務的負載均衡、緩存、數(shù)據(jù)庫,到操作系統(tǒng)級別的IO多路復用、IO零拷貝技術,再到微服務的RPC技術,掌握了之后,任爾技術如何變遷,我自巋然不動~