您好(hǎo),歡迎訪問深圳市方塊互娛網絡科技有限公司 日這

如何提高服務器的并發(fā)處理能(néng)煙爸力?

資訊中心
聯系我們
  • 深圳市方塊互娛網絡科技有限公司
  • 深圳市寶安區西鄉街道(dào)西鄉大道(dào)長費288号寶源華豐總部經(jīng)濟大廈C座4樓3A11室
  • 2529041661@qq.com
  • 0755-23056459
  • 15817228358 
  • 潘先生
導語:一台服務器在單位時(shí)間裡(lǐ)能(néng)處理的術司請求越多,服務器的能(néng)力越高,也就(jiù)她煙是服務器并發(fā)處理能(néng)力越強!

什麼(me)是服務器并發(fā)處理能(né相訊ng)力?

image-20210511235823-1

image-20210511223552-1

008

一台服務器在單位時(shí)間裡(lǐ)能(né校對ng)處理的請求越多,服務器的能(néng輛唱)力越高,也就(jiù)是服務器并發(fā)處理白章能(néng)力越強

有什麼(me)方法衡量服務器并發(fā)處理能(néng)力

1. 吞吐率

吞吐率,單位時(shí)間裡(lǐ)服務器處理的最大請求數,單位req/車姐s

從服務器角度,實際并發(fā)用戶數的可以理解為服市工務器當前維護的代表不同用戶的文件描述符總數,也就(jiù)是并發(fā子秒)連接數。

服務器一般會(huì)限制同時(shí)服務的最多用戶數,比如apache的影舊MaxClents參數。

這(zhè)裡(lǐ)再深入一下,對(duì)于服務老樂器來說(shuō),服務器希望支持高吞吐率,對(duì)于用雜現戶來說(shuō),用戶隻希望等待最少的時(shí空很)間,顯然,雙方不能(néng)滿足,所以雙方利益的平衡點,就(弟舞jiù)是我們希望的最大并發(fā)用戶數。

2. 壓力測試

有一個原理一定要先搞清楚,假如100個用戶同時(shí)向(xi玩睡àng)服務器分别進(jìn)行10個請求,與1個用戶向(xiàn林說g)服務器連續進(jìn)行1000次請求,對(duì)服務器的壓女鐵力是一樣(yàng)嗎?

實際上是不一樣(yàng)的,因對(duì)每一個用戶,連續離下發(fā)送請求實際上是指發(fā)送一個請求并接收到(dào)響應數火草據後(hòu)再發(fā)送下一個請求。

這(zhè)樣(yàng)對(duì)于1個用戶向(xiàng)服務器連續進村業(jìn)行1000次請求, 任何時(shí)刻服務器的網卡接收緩沖區中隻商呢有1個請求,而對(duì)于100個用戶同時(shí)向(科美xiàng)服務器分别進(jìn)行10個請求,服務器的網卡接樹從收緩沖區最多有100個等待處理的請求,顯然這(zh森影è)時(shí)的服務器壓力更大。

壓力測試前提考慮的條件

  • 并發(fā)用戶數: 指在某一時(shí)刻同時(shí我錯)向(xiàng)服務器發(fā)送請求的用戶總數亮說(HttpWatch)

  • 總請求數

  • 請求資源描述

  • 請求等待時(shí)間(用戶等待時(shí)間)

  • 用戶平均請求的等待時(shí)間

  • 服務器平均請求處理的時(shí)間

  • 硬件環境

壓力測試中關心的時(shí)間又細分以下2種(zhǒng):錯購

  1. 用戶平均請求等待時(shí)間(這(zhè)裡(lǐ)暫不把數據在網絡城說的傳輸時(shí)間,還(hái)有用戶PC船西本地的計算時(shí)間計算入内)

  2. 服務器平均請求處理時(shí)間

用戶平均請求等待時(shí)間主要用于衡量資國服務器在一定并發(fā)用戶數下,單個用戶的服務質量慢子;而服務器平均請求處理時(shí)間就(jiù)是吞吐率的森這倒數。

一般來說(shuō),用戶平均請求等待時(shí)間 朋紙= 服務器平均請求處理時(shí)間 * 并發(fā)用戶數

怎麼(me)提高服務器的并發(fā)處理能(néng)來作力

1. 提高CPU并發(fā)計算能(nén公朋g)力

服務器之所以可以同時(shí)處理多個請求,在于操作系統通過著去(guò)多執行流體系設計使得多個任務可以輪流秒年使用系統資源。
這(zhè)些資源包括CPU,内存以及I/O. 這(zh鐘行è)裡(lǐ)的I/O主要指磁盤I/O, 和網絡I/O。

多進(jìn)程 & 多線程

多執行流的一般實現便是進(jìn)程,多進(jì嗎輛n)程的好(hǎo)處可以對(duì)CPU時(shí)間的輪流使用,事聽對(duì)CPU計算和IO操作重疊利用。這(z科朋hè)裡(lǐ)的IO主要是指磁盤IO和網絡IO,相對(duì)CP業能U而言,它們慢的可憐。

而實際上,大多數進(jìn)程的時(shí)麗花間主要消耗在I/O操作上。

現代計算機的DMA技術可以讓CPU不參與I/O操作的全過(guò)程,比如進業自(jìn)程通過(guò)系統調用,使得CPU向(xià城男ng)網卡或者磁盤等I/O設備發(fā)出指令,然後(hòu)進(j從身ìn)程被(bèi)挂起(qǐ),釋放出CPU資源,等待I/資藍O設備完成(chéng)工作後(hòu)通過(guò)中斷來通知進西笑(jìn)程重新就(jiù)緒。

對(duì)于單任務而言,CPU大部分時(shí)間空閑,這(zhè)時(sh日對í)候多進(jìn)程的作用尤為重要。C現金PU 是怎麼(me)認識代碼的?推薦大家看下。

多進(jìn)程不僅能(néng)夠提高CPU的并發(fā)度多見。其優越性還(hái)體現在獨立的内存地址空間和生命周期所帶來的穩定性答場和健壯性,其中一個進(jìn)程崩潰不會(huì)影響到身刀(dào)另一個進(jìn)程。
但是進(jìn)程也有如下缺點:

  1. fork()系統調用開(kāi)銷很大: p中票refork

  2. 進(jìn)程間調度和上下文切換成(chéng)本紙動: 減少進(jìn)程數量

  3. 龐大的内存重複:共享内存

  4. IPC編程相對(duì)比較麻煩

減少進(jìn)程切換

當硬件上下文頻繁裝入和移出時(shí),哥民所消耗的時(shí)間是非常可觀的。可用Nmon工具監視服務器每秒的上下文切呢很換次數。

為了盡量減少上下文切換次數,最簡單的做法就(jiù)是減少進(jìn間道)程數,盡量使用線程并配合其它I/O模型來設計并發術拍(fā)策略。

還(hái)可以考慮使用進(jìn)程綁定CPU技會高術,增加CPU緩存的命中率。若進(jìn)程不斷在各CPU上切換,這(zhè)廠議樣(yàng)舊的CPU緩存就(jiù)會(秒市huì)失效。

減少使用不必要的鎖

服務器處理大量并發(fā)請求時(shí),多個請求處理任務時議時(shí)存在一些資源搶占競争,這(zhè)時(shí)一般采用“鎖笑書”機制來控制資源的占用。到(dào)底什麼(me)是重入鎖,推薦大資什家看下。

當一個任務占用資源時(shí),我們鎖住資源,這(zhè)時(shí)其它鐵不任務都(dōu)在等待鎖的釋放,這(zhè)個現象稱為鎖競黃金争。

通過(guò)鎖競争的本質,我們要意識到(dào)盡量減如多少并發(fā)請求對(duì)于共享資源的競争。

比如在允許情況下關閉服務器訪問日志,這(zhè)可以大大減少在鎖等待時(shí知坐)的延遲時(shí)間。要最大程度減少無辜的等待時(著但shí)間。

這(zhè)裡(lǐ)說(shuō)下無鎖編程,就(jiù)是由長明内核完成(chéng)這(zhè)個鎖機制,主要是使用原上個子操作替代鎖來實現對(duì)共享資源的訪問保護。

使用原子操作時(shí),在進(jìn)行實際的寫操作來城時(shí),使用了lock指令,這(zhè)樣(yàng路來)就(jiù)可以阻止其他任務寫這(zhè)塊内存,在購避免出現數據競争現象。原子操作速度比鎖快,一般要快一倍人多以上。

例如fwrite(), fopen(),其是使用a呢廠ppend方式寫文件,其原理就(jiù)是使草跳用了無鎖編程,無鎖編程的複雜度高,但是效率快,而且發(fā林司)生死鎖概率低。

考慮進(jìn)程優先級

進(jìn)程調度器會(huì)動态調整運行票街隊列中進(jìn)程的優先級,通過(guò)top觀察他他進(jìn)程的PR值

考慮系統負載

可在任何時(shí)刻查看/proc/load媽樹avg, top中的load averag物船e也可看出

考慮CPU使用率

除了用戶空間和内核空間的CPU使用率以外,還(hái)村土要關注I/O wait,它是指CPU空閑并且等待I/O操作完成(車下chéng)的時(shí)間比例(top中查看wa的值關學)。

2. 考慮減少内存分配和釋放

服務器的工作過(guò)程中,需要大量的内存,使得内存的分員司配和釋放工作尤為重要。

可以通過(guò)改善數據結構和算法複制呢拿度來适當減少中間臨時(shí)變量的内存分配及數據複友車制時(shí)間,而服務器本身也使用了各自的策略來提高效率。

例如Apache,在運行開(kāi)始時(shí)一次申請大片的内存作年車為内存池,若随後(hòu)需要時(shí)就(jiù)在内存街不池中直接獲取,不需要再次分配,避免了頻繁的内存分配和釋放引起(qǐ)的内存整錢湖理時(shí)間。

再如Nginx使用多線程來處理請求,使得多個照遠線程之間可以共享内存資源,從而令它的内存總體使用量大大減少。

另外,Nginx分階段的内存分配策略,按明拿需分配,及時(shí)釋放,使得内存使用量保持在很小的數量範圍。

另外,還(hái)可以考慮共享内存。

共享内存指在多處理器的計算機系統中,可以被(bèi)不同中央處理器(CPU鄉校)訪問的大容量内存,也可以由不同進(jìn)程共享,是非常快的進(jìn)程報分通信方式。

但是使用共享内存也有不好(hǎo)的地方,就(鐵裡jiù)是對(duì)于多機器時(shí)數據不好(hǎo)統一。

shell命令ipcs可用來顯示系統下共享内存的狀态,函數sh喝鐵mget可以創建或打開(kāi)一塊共享内存區,函數sh要費mat將(jiāng)一個存在的共享内存段連接到(dào)本進(j器麗ìn)程空間, 函數shmctl可以對(duì)共享内存動和段進(jìn)行多種(zhǒng)操作,函數shmdt西時函數分離該共享内存。

3. 考慮使用持久連接

持久連接也為長(cháng)連接,它本身是TCP通信的一種(zhǒn自筆g)普通方式,即在一次TCP連接中持續發(fā)送多分數據而不斷開(kāi)連錢長接。

與它相反的方式稱為短連接,也就(jiù)是建立連接後(hòu)發(f裡輛ā)送一份數據就(jiù)斷開(kāi),然後(hòu)再次建立連接發(fā)黃哥送下一份數據, 周而複始。

是否采用持久連接,完全取決于應用特點。

從性能(néng)角度看,建立TCP連接的操作本身是一項不小的開(kāi)爸了銷,在允許的情況下,連接次數越少,越有利于性能(nén公近g)的提升; 尤其對(duì)于密集型的圖片或網頁等小數據習多請求處理有明顯的加速所用。

HTTP長(cháng)連接需要浏覽器和web服務器快制的共同協作,目前浏覽器普遍支持長(cháng)連接,表現在分家其發(fā)出的HTTP請求數據頭中包含關于長(cháng)連接公舊的聲明,如下:Connection: Keep-Aliv土來e

主流的web服務器都(dōu)支持長(chán家物g)連接,比如apache中,可以用KeepAlive off關閉長離文(cháng)連接。

對(duì)于長(cháng)連接的有效使用,還(hái)有關鍵一點公靜在于長(cháng)連接超時(shí)時(shí地森)間的設置,即長(cháng)連接在什麼(me)時(shí)候關愛文閉嗎?

Apache的默認設置為5s, 若這(zhè)個時歌一(shí)間設置過(guò)長(cháng),則可能(néng)導緻資源無效雜年占有,維持大量空閑進(jìn)程,影響服文光務器性能(néng)。

4. 改進(jìn)I/O 模型

I/O操作根據設備的不同分為很多類型,比如内存I/O, 網絡I/O, 磁盤I厭生/O。詳解 Java 中 4 種(zhǒng) I/O文文 模型,推薦大家看下。

對(duì)于網絡I/O和磁盤I/O, 它們的速度要慢很多,盡管使媽窗用RAID磁盤陣列可通過(guò)并行磁盤磁盤來加快磁盤I/O速度,購買大連筆銀獨享網絡帶寬以及使用高帶寬網絡适配器可以提高網絡I/裡不O的速度。

但這(zhè)些I/O操作需要内核系統調用來完成(chéng)日中,這(zhè)些需要CPU來調度,這(zhè)使得CPU不得不浪們照費寶貴的時(shí)間來等待慢速I/O操作。

我們希望讓CPU足夠少的時(shí)間在i/O操作的調度上年服,如何讓高速的CPU和慢速的I/O設備更好線線(hǎo)地協調工作,是現代計算機一直探讨的話題。各種(z費什hǒng)I/O模型的本質區别在于CPU的參與方式。

DMA技術

I/O設備和内存之間的數據傳輸方式由DMA控制器完成(chéng外弟)。在DMA模式下,CPU隻需向(xiàng)DMA下達命令,讓也現DMA控制器來處理數據的傳送,這(zhè)樣(yàn花金g)可以大大節省系統資源。

異步I/O

異步I/O指主動請求數據後(hòu)便可來民以繼續處理其它任務,随後(hòu)等待I/O操作的通知,這(鄉見zhè)樣(yàng)進(jìn)程在數據讀寫時(sh讀河í)不發(fā)生阻塞。

異步I/O是非阻塞的,當函數返回時(shí校電),真正的I/O傳輸已經(jīng)完成(chéng),這(zhè)讓農事CPU處理和I/O操作達到(dào)很好(hǎo)的重疊。水你

I/O多路複用

epoll服務器同時(shí)處理大量的文件描述符是必不可少的國妹,若采用同步非阻塞I/O模型,若同時(shí)接收TCP連接的數據,就(ji火車ù)必須輪流對(duì)每個socket調用接收數據的方法,不管這(zhè)些為放socket有沒(méi)有可接收的數據,都(dōu風人)要詢問一次。

假如大部分socket并沒(méi)有數據可以接收,那麼(me)進朋小(jìn)程便會(huì)浪費很多CPU時(shí)間用于檢查畫坐這(zhè)些socket有沒(méi)有可以接收的數據。

多路I/O就(jiù)緒通知的出現,提供了對(duì)大量美劇文件描述符就(jiù)緒檢查的高性能(néng)方案,美站它允許進(jìn)程通過(guò)一種(多機zhǒng)方法同時(shí)監視所有文件描述符,并可以快速獲得所有就(j對上iù)緒的文件描述符,然後(hòu)隻針對(d我習uì)這(zhè)些文件描述符進(jìn)行數據訪站亮問。

epoll可以同時(shí)支持水平觸發(fā)和化雨邊緣觸發(fā),理論上邊緣觸發(fā)錢快性能(néng)更高,但是代碼實現複雜,因為任何意外的丢失事(sh市小ì)件都(dōu)會(huì)造成(chéng)請求文歌處理錯誤。

epoll主要有2大改進(jìn):

  1. epoll隻告知就(jiù)緒的文件描述符,而且當調用epoll_靜長wait()獲得文件描述符時(shí),返回議區并不是實際的描述符,而是一個代表就(jiù)緒描述符數量的值,然車音後(hòu)隻需去epoll指定的一個數組中依次取得相應數量的草能文件描述符即可。這(zhè)裡(lǐ)使用了内存映射(m習老map)技術,這(zhè)樣(yàng)徹底省掉了這(z些音hè)些文件描述符在系統調用時(shí)刀和複制的開(kāi)銷。

  2. epoll采用基于事(shì)件的就(jiù)緒通知方明校式。其事(shì)先通過(guò)epoll_ctrl()注冊每一個文讀花件描述符,一旦某個文件描述符就(jiù)緒時(shí),内核會(huì)南錢采用類似callback的回調機制,當進(長照jìn)程調用epoll_wait()時(shí)得到(dà來訊o)通知

關于IO模型,可以參考筆者前面(miàn)寫的相關文章Java NIO.2;業笑關于epoll,可以參考筆者前面(miàn)寫的文章了門select、poll和epoll簡介。

Sendfile

大多數時(shí)候,我們都(dōu)向(xi年關àng)服務器請求靜态文件,比如圖片,樣(yàng)式表等。
在處理這(zhè)些請求時(shí),磁盤文件醫歌的數據先經(jīng)過(guò)内核緩沖區,然後(hòu)到(dào)用冷樂戶内存空間,不需經(jīng)過(guò)任何處理輛城,其又被(bèi)送到(dào)網卡對(duì)應的離但内核緩沖區,接著(zhe)再被(bèi)送入靜業網卡進(jìn)行發(fā)送。

Linux提供sendfile()系統調用,可以講磁盤文視化件的特定部分直接傳送到(dào)代表客戶端的socket描述符,加快了靜态文件聽章的請求速度,同時(shí)減少CPU和内存的開東畫(kāi)銷。
适用場景:對(duì)于請求較小的靜态文件,sendfil對器e發(fā)揮的作用不那麼(me)明顯,因發(f快少ā)送數據的環節在整個過(guò)程中所占時(shí)間的比例相比于大文件請知水求時(shí)小很多。

内存映射

Linux内核提供一種(zhǒng)訪問磁盤文腦從件的特殊方式,它可以將(jiāng)内存中某塊地址空來謝間和我們指定的磁盤文件相關聯,從而對(duì)這(zhè)塊内存麗跳的訪問轉換為對(duì)磁盤文件的訪問。這(z車身hè)種(zhǒng)技術稱為内存映射。

多數情況下,内存映射可以提高磁盤I/O的性能(néng),無須對海使用read()或write()等系統調用來訪問文件,而是通過(guò能遠)mmap()系統調用來建立内存和磁盤文件的關聯,然後(hòu)像訪問内存一樣窗訊(yàng)自由訪問文件。

缺點:在處理較大文件時(shí),内存映射朋銀會(huì)導緻較大的内存開(kāi)銷,得不償失。

直接I/O

在linux 2.6中,内存映射和直接訪問文件廠遠沒(méi)有本質差異,因為數據需要經(jīng)過讀來(guò)2次複制,即在磁盤與内核緩沖區之間以及弟歌在内核緩沖區與用戶态内存空間。

引入内核緩沖區的目的在于提高磁盤文件的訪問性能(néng),然而對地麗(duì)于一些複雜的應用,比如數據庫服務器,它們熱物為了進(jìn)一步提高性能(néng),希望繞過(guò)内女問核緩沖區,由自己在用戶态空間實現并管理I/O緩沖區,比如數據庫可根關就據更加合理的策略來提高查詢緩存命中率。

另一方面(miàn),繞過(guò)内核緩沖區也可以減少系統内舞是存的開(kāi)銷,因内核緩沖區本身就(jiù)在使用制說系統内存。

Linux在open()系統調用中增加參數選項O_DIRECT,即可繞過(呢腦guò)内核緩沖區直接訪問文件,實現直接I/O。

在Mysql中,對(duì)于Innodb存儲引擎,自術雨身進(jìn)行數據和索引的緩存管理,可在my.cnf配置中分配嗎冷raw分區跳過(guò)内核緩沖區,實現直接I/O。

5. 改進(jìn)服務器并發(fā)策略

服務器并發(fā)策略的目的,是讓I/O操作和CPU計算盡量重疊進(jìn)行又歌,一方面(miàn)讓CPU在I/O等待時(sh上劇í)不要空閑,另一方面(miàn)讓CPU在I/O調度上盡量花最少的船嗎時(shí)間。

一個進(jìn)程處理一個連接,非阻塞I/O

這(zhè)樣(yàng)會(huì)存不亮在多個并發(fā)請求同時(shí)到(dào)達時(shí),服務器明站必然要準備多個進(jìn)程來處理請求。其進(jìn)程的我雪開(kāi)銷限制了它的并發(fā)連接數。

但從穩定性和兼容性的角度,則其相對(duì)安全,任何一個子進(jìn)程的崩風相潰不會(huì)影響服務器本身,父進(jìn)程可以創技窗建新的子進(jìn)程;這(zhè)種(z一從hǒng)策略典型的例子就(jiù)是Apache的fork和prefork間睡模式。

對(duì)于并發(fā)數不高(如150以内)的站點同時(shí章高)依賴Apache其它功能(néng)時草很(shí)的應用選擇Apache還(hái)是可以商鐵的。

一個線程處理一個連接,非阻塞IO

這(zhè)種(zhǒng)方式允許在一個進(jìn)程中村分通過(guò)多個線程來處理多個連接,一個線程處理一個連接。A樂輛pache的worker模式就(jiù)術些是這(zhè)種(zhǒng)典型例子,使其可支持更多的做討并發(fā)連接。不過(guò)這(zhè)種(zhǒng)模費話式的總體性能(néng)還(hái)不如prefork,所以一般不選間高用worker模式。推薦閱讀:14個Java并發(fā)容器。

一個進(jìn)程處理多個連接,異步I/O校話

一個線程同時(shí)處理多個連接,潛在的前提道化條件就(jiù)是使用IO多路複用就(jiù)緒通知。

這(zhè)種(zhǒng)情況下,將(嗎秒jiāng)處理多個連接的進(jìn)程叫(jiào)做worker進(j訊見ìn)程或服務進(jìn)程。worker的數量可以配置,如Nginx中的w老車orker_processes 4。

一個線程處理多個連接,異步IO

即使有高性能(néng)的IO多路複用就(jiù)緒通知,但綠時磁盤IO的等待還(hái)是無法避免的。更加高效的方法是對(duì)磁盤文樹醫件使用異步IO,目前很少有Web服務器真正意義上支持這間購(zhè)種(zhǒng)異步IO。

6. 改進(jìn)硬件環境

還(hái)有一點要提及的是硬件環境,服務器的硬件資看配置對(duì)應用程序的性能(néng)提升往往是最直接,也間分是最簡單的方式,這(zhè)就(jiù)是所謂的scal海還e up。這(zhè)裡(lǐ)不做論述。

(0)