高併發伺服器的設計 架構與瓶頸的設計GOOD

2021-07-10 12:15:44 字數 2116 閱讀 5963

做架構設計,難免有時候被人問及系統的瓶頸在哪,那首先來了解下什麼是瓶頸?

打個形象的比方,人的嘴巴可以吞下一整個麵包,但是卻嚥不下去,因為食管不給力,它比較細,所以嘴巴能吞下的食物大小要受到食管的粗細限制。

城市內部每天會產生幾十萬件跨城快遞,可是跨城的交通不給力,只允許走小型卡車,一卡車一次就能裝幾千件,一天下來也不一定能投送的完。

人在一定時間內能嚥下多少食物,貨運公司在一天運送多少貨物,物理上叫做吞吐量,系統整體的吞吐量等於最小區域的吞吐量。

下面這張圖能夠反映:

土黃色管子的流量要受到紅色部分的制約。

伺服器上也是這樣,好一點的設計框架結合物理高配可以處理高達幾十萬的併發,像土黃色的管子,可是偏偏有一些模組像圖中紅色的管子那樣,一秒中只能同時處理幾百次,這樣就嚴重拖慢了伺服器的效能,成了瓶頸。

現實開發中有時可能會要加上資料庫模組,如mysql,雖然mysql號稱每秒處理幾十萬的查詢根本沒問題,但那只是運算能力。

伺服器連mysql 是要通過tcp網路的,有連線就需要時間,再加上資料量如果大點,自然就成了瓶頸。

相似的情況,一些特殊的業務,比如加解密服務,金鑰和隨機數的產生依賴加密機,中介軟體的效能就是我們圖中的紅管子。

系統架構的設計是爭對業務的,業務裡如果存在這些紅管子,就必須要有相應的解決辦法。

不同人的處理方法不同,據我經驗,可以將瓶頸子分成兩類:

1.阻塞序列處理

2.非同步並行處理

mysql,中介軟體的處理屬於第一類,非同步閘道器查詢屬於第二類。

對於第一類,一種通用的解決方法是增加處理程序,其實是橫向擴容的思想,打個比方,乙個程序的併發是600,10個程序就可以達到6000了,如何才能將請求均勻地分配到這10個程序是關鍵。

多個程序同時監聽乙個埠,負載均衡的方法很多,這裡介紹nginx的做法,直接上**:

[cpp]view plain

copy

print

?

//接收握手後連線

void ngx_event_accept(ngx_event_t *ev)  

//事件模型處理函式

void ngx_process_events_and_timers(ngx_cycle_t *cycle)  

else   

if (ngx_accept_mutex_held)  else   

}  }  

...  

}  //取得埠監聽的鎖

ngx_int_t ngx_trylock_accept_mutex(ngx_cycle_t *cycle)  

...  

}  //啟動埠監聽

static ngx_int_t ngx_enable_accept_events(ngx_cycle_t *cycle)  

if (ngx_event_flags & ngx_use_rtsig_event)   

} else   

}  }  

return ngx_ok;  

}  

從上面的**可以看出,nginx用乙個全域性變數ngx_accept_disabled 來控制單個程序的負載,當負載達到一定值的時候,不再接受新的負載。

對於第二類情況,解決的方法就像名字一樣,非同步並行解決。

拿跨網查詢為例:

建立乙個查詢的請求,將請求放進事件模型中,等待服務端的返回,非同步處理。

熟悉nginx的就知道nginx的upstream反向**,這個解決方案跟反向**很像,只不過在與上游伺服器互動的前後分別還有其他的業務處理,而且可能還會有多次互動。

相應的流水圖是這樣的:

當客戶端請求量大時,事件模型的容量會成為瓶頸,這樣仍然需要橫向擴容的方式來解決,增加處理程序。

這兩種情況的處理方法大致如此,有時候特殊問題特殊對待,比哪資料庫的瓶頸可以借助快取解決,有些高配伺服器的記憶體128g,甚至幾台高配伺服器只為乙個業務,這樣的情況下,不吃點記憶體難免對不起老闆的money

**:

linux c 高併發tcp伺服器架構

from epoll 接受資料到佇列,執行緒池處理佇列裡的資料 具體實現方式 只使用使用std的的資料結構,未使用boost thread pool.cpp include include include thread pool.h include thread process.h include ...

高併發伺服器邏輯處理瓶頸,如何解決?

高併發伺服器邏輯處理瓶頸,如何解決?首先我們先了解什麼是併發!併發,在作業系統中,是指乙個時間段中有幾個程式都處於已啟動執行到執行完畢之間,且這幾個程式都是在同乙個處理機上執行,但任乙個時刻點上只有乙個程式在處理機上執行。百科 顧名思義,高併發就是在指定時間內,系統同時能夠處理大量的請求 連線數 那...

併發伺服器的設計

併發 即同時 併發伺服器 實現多客戶端同時連線,同時處理多個請求。利用多程序或多執行緒的方式處理連線成功後的任務,主程式繼續等待連線。多程序 建立子程序,任務函式交給子程序執行 listen sockfd,5 允許連線的客戶機數目5 while 1 else if pid 0 printf fork...