【服務器】構建高性能Linux網絡服務器

關鍵

高性能網絡服務器的關鍵在於併發,如何高效的使用多核心的服務器,讓多個線程併發處理程序。web


併發方式

  • 基於時間的並行
  • 基於空間的並行,
  • 其餘提法,

在計算機內部,最本質的是時間(CPU)空間(內存)這兩種資源,各類並行的界限並無那麼明顯。所謂基於時間的並行,有兩隻貓,共同看守一個大倉庫,但一個工做,另外一個睡覺,二者不一樣時工做。所謂基於空間的並行,將倉庫分爲兩個部分,這樣兩隻貓能夠分別看守不一樣的部分,兩隻貓在工做不緊張的時候就能夠睡覺。安全


網絡併發程序優化

對於網絡併發程序,能夠從各個角度進行優化,先談單個UDP的服務器,再談單個TCP服務器,最後再談服務器集羣。服務器


UDP服務器

典型的UDP服務器,例如DNS服務器,有一個缺點,只能經過其著名的服務端口發佈給客戶端,全部客戶端的流量集中在單個端口上,採用單個線程讀取端口的數據效率最高,在讀套接字時採用任何形式的併發都會致使性能的降低,對於某些版本的內核,多線程收同一套接字將產生驚羣現象,這主要是由操做系統的進程調度方式引發的。於是比較好的模式是單個線程收,而後再將數據分發到後臺不一樣的處理線程,然而在接收線程和處理線程之間的的數據傳遞可能須要採用鎖的方式,這樣就致使程序性能降低(然而在採起分主的情境下,即單生產者和單消費者,能夠採用無鎖隊列的方式來實現,這樣就能夠大幅提升程序性能),若是某種形式的鎖,爲了不頻繁的加鎖解鎖操做,比較好的改進是數據的批傳遞,這樣能夠數百倍的減小加解鎖的調用,也能夠大幅減小線程的上下文切換開銷。網絡

在數據的返回階段,典型的作法是在處理線程處理完成後,再把數據傳遞到發送線程,再經過原來的接收套接字將數據返回。這樣在數據的發送段,又遇到了單點瓶頸。與讀套接字相同,在單個套接字上發送數據時,任何併發的寫也會致使發送效率的降低,這樣看來只好使用單個線程來進行發送。但若是咱們有多個處理線程,它們將數據聚集到單個發送線程隊列中,必然又遇到一個加鎖解鎖開銷。雖然在同一個套接字上讀和寫是對系統而言是採用不一樣的緩衝區,收發性能能夠互不影響,但咱們爲了極大的提高程序的性能,必須解決掉髮送瓶頸。這就是採用地址重用,經過多個套接字併發的發送數據。若是客戶端對服務器的發送端口有要求,咱們必須把多個套按字綁定到同一地址和端口上屢次,這樣就產生了一個時序的問題。因爲內核在實現時,能夠接收數據的套按字,只有最後一次綁定的能夠接收 。所以必須將發送套接字在接收套接字綁定前完成綁定,不然應用程序就收不到任何數據了。經過這樣的處理,再進行某些熱點的優化,UDP程序就能夠作到收和發將千兆網卡跑滿。固然若是你有更快的網卡,就能夠以讀寫內存的速度來處理數據。多線程


TCP服務器

TCP服務器分爲兩種併發

  • 短鏈接服務器如web服務器,
  • 一些特殊的長鏈接服務器。

對於單個服務器而言,再強大也沒有一羣服務器強大,這樣就涉及到集羣的部署和負載均衡策略,最後若是服務器過多,還須要解決服務器的動態加入和退出,以及服務器安全防禦問題。負載均衡

相關文章
相關標籤/搜索