面試官問你如何解決web高併發這樣回答就行了

所謂高併發,就是同一時間有不少流量(一般指用戶)訪問程序的接口、頁面及其餘資源,解決高併發就是當流量峯值到來時保證程序的穩定性。php

咱們通常用QPS(每秒查詢數,又叫每秒請求數)來衡量程序的綜合性能,數值越高越好,通常須要壓測(ab工具)獲得數據。css

假設咱們的一個進程(也能夠是線程或者協程)處理一次請求花費了50毫秒(業內達標範圍通常是20毫秒至60毫秒),那麼1秒鐘就能夠處理20個請求,一臺服務器是能夠開不少這樣的進程並行去處理請求的,好比開了128個,那麼這臺機器理論上的QPS=2560。程序員

千萬不要小瞧這個數字,當你的QPS真有這麼高的時候意味着你的DAU(用戶日活)有2560*200=51.2萬,業內通常是放大200倍計算,有這樣的日活說明作得很不錯了。redis

一臺服務器可以達到的最大QPS受不少因素的影響,好比機器參數配置、機房地理位置、CPU性能、內存大小、磁盤性能、帶寬大小、程序語言、數據庫性能、程序架構等,咱們一一細說。數據庫

1.機器參數配置

這個很好理解,好比服務器最大能夠開啓128個進程,你設置了最大隻開啓100個,這屬於服務器調優。編程

2.機房地理位置

若是你作海外用戶,服務器機房應該選擇國外的,反之應該選擇國內的,由於機房距離用戶越近,在傳輸上的時間損耗就越低。後端

3.CPU性能

CPU性能越好,處理速度就越快,核心數越多,可以並行開啓的進程就越多。緩存

4.內存大小

內存越大,程序就能把更多的數據直接放到內存,從內存讀取數據比從磁盤讀取數據的速度快不少。服務器

5.磁盤性能

這個不用多說吧,通常固態硬盤的性能比機械硬盤的性能好不少,性能越好讀寫數據的速度就越快。架構

6.帶寬大小

服務器的帶寬通常指流出帶寬,單位爲Mb/S,好比帶寬爲8Mb/S即1MB/S,若是提供文件下載服務,可能一個用戶的下載行爲就把服務器帶寬用完了。

通常把圖片、視頻、css文件、JavaScript腳本等資源放到第三方的CDN去,按流量計費,這樣就不佔用服務器帶寬了。

若是用戶規模小,基本上一臺服務器就行了,這個時候通常會選按固定帶寬大小計費。

若是用戶規模很大了,基本上會用到負載均衡器來分流,即把流量按照必定的規則分配到不一樣的服務器上,負載均衡器通常會按流量來計費。

若是平均一次請求返回的數據大小爲50KB,爲了達到1000QPS這個指標,須要的帶寬峯值=1000*50*8/1024=390.625Mb/S。

咱們在設計接口的時候應該儘可能減小返回的數據大小,好比user_id就能夠簡化爲uid,像圖片、視頻、css等文件壓縮的目的就是減小數據的大小。

7.程序語言

編譯型語言的性能通常好於解釋型語言的性能,好比go語言性能就好於php語言性能,當語言短時間不會替換時,能夠經過堆機器解決高併發問題。

8.數據庫性能

一臺服務器上部署的數據庫老是有一個瓶頸的,好比每秒查詢數、每秒寫入數。

咱們能夠經過增長不少從庫解決查詢(select語句)的瓶頸,稱之爲多從庫模型,須要注意的是主從同步數據可能有延遲,當修改數據後立刻須要查詢時須要設置強制從主庫讀取。

咱們能夠將業務拆分,讓某些表存儲在一個數據庫實例上,另外一些表存儲在其餘數據庫實例上,雖然一個數據庫實例有本身的瓶頸,可是不少的數據庫實例堆積起來性能就會大大改善,多個數據庫實例的方案稱之爲多主庫模型,主要是爲了解決寫入瓶頸(insert語句、update語句、delete語句)。

若是你有多個主庫又有多個從庫,你就實現了多主多從模型。

若是一個表存儲的數據量很大,這個時候就要考慮分表了(通常用中間件實現),好比按時間分表或者按用戶分表,當把一個表的全部分表都放在一個數據庫實例上都知足不了要求的時候,你應該把某些分表存儲在新的數據庫實例上,這個時候一個表的數據分佈到了不一樣的數據庫實例上,這就是所謂的分佈式數據庫方案了,你須要處理的事情就很複雜了,好比處理分佈式事務。

數據庫的併發鏈接數也是有限制的,咱們能夠用鏈接池技術來應對,就是保持必定數量的和數據庫的鏈接不斷開的長鏈接,須要鏈接數據庫的時候就從池子裏選擇一個鏈接,用完放回去就行了,這個通常也是用中間件來實現。

好的索引也能提升數據庫的性能,有時候比堆多個從庫的方案還要好。

若是可以減小數據庫的讀寫,也算間接提升了數據庫的性能,好比咱們用redis來作緩存,用消息隊列異步落庫等。

有時候某些數據用數據庫來計算須要很長時間,能夠取到元數據(最小粒度的數據)用程序來計算,這稱之爲用內存換時間。

9.程序架構

好比實現一樣的功能,初級程序員寫的程序須要循環100次,而高級程序員寫的程序只須要循環10次,效果確定不同。

總結

通常大型項目基本是先後端分離的,從性能方面說就是爲了將頁面渲染的處理在客戶端運行,下降服務器的壓力。

從帶寬層面考慮,css、圖片、視頻、JavaScript等文件資源能用CDN的就用CDN,能壓縮的就儘可能壓縮,接口能減少返回數據的大小就儘可能減少。

爲了解決編程語言的不足或者單臺服務器的瓶頸,能夠先堆機器應對。

索引、多主多從、分佈式數據庫、緩存、鏈接池、消息隊列等是從數據庫方便考慮如何優化性能。

有時候程序的低耦合性比程序的高性能更重要,不要一味地追求高性能。

TODO

持續更新

相關文章
相關標籤/搜索