-
1 # 玩物雜談
-
2 # 此生唯一
感覺面試過程中一定會問到的問題有三個,多執行緒,JVM,高併發!
儘管工作過程中基本不用這三個要命的東西!還是阻擋不了面試官的趨之若鶩,下面就圍繞其中一個---高併發,來說下自己的理解!
何謂併發?同時處理操作!
何謂高併發?同時處理很多操作!
什麼操作呢?頁面請求:一個簡單的頁面請求可能包含了很多內容,比如驗證登入,靜態頁面載入,動態資料載入(涉及到訪問資料庫,快取等等),圖片載入,執行緒的啟動和銷燬!每一個操作都需要花費時間,總得加起來可能只有200ms,但是如果你的伺服器處理能力只能是一個請求級別的,那麼100萬個請求,你就需要20萬秒,大概是幾天的時間!
當然實際生活中我們沒有這麼水的伺服器,換句話說,我們可以透過選擇好的伺服器來提高我們的併發能力!也就是說硬體的指數型升級能讓我們應付高併發,但是事與願違,如果處理一個請求佔用的是100k記憶體,那麼100萬請求就需要100萬M,也就是差不多100G的記憶體!這無疑是現實生活中還沒有的!
而且單機伺服器容易受到網路,斷電等多方面原因的影響!所以一個分散式叢集就是我們處理高併發最有效的方法!
在此之前,我們先來熟悉幾個關於高併發的關鍵引數!
QPS:每秒處理的請求數量!
響應時間:處理一個請求需要的時間!
吞吐量:單位時間內的處理請求數量!
最大併發數:同一時間能支援的最大請求數!
從這些指標來看,我們提高併發量有兩種方式:提高處理速度和減少處理時間!
一般來說有下面這些常規辦法:
1,更多的靜態資源:將程式碼中的大量列舉(容器載入時寫入map,放入本地快取),資料庫中的定義表(定時任務放入快取),固定配置,HTML檔案等靜態化處理,快取起來!
2,圖片伺服器:一般來說,圖片在一個頁面上屬於資料量比較大的東西,儘量避免動態資料和圖片的順序渲染,使用圖片伺服器分離資料和圖片!
3,最佳化程式碼:儘量避免多層迴圈,避免多次訪問資料庫,使用多執行緒提高cpu使用率和執行速度,使用java8的流式處理和並行處理提高速度!
4,資料庫:採用分庫分表,mysql5.7之後,據說可以支援秒級百萬級資料查詢。速度相當之快,使用八庫1024表,可以滿足資料庫一秒數百萬的併發!同時可以開啟快取,寫入儲存過程等加快訪問時間!分庫分表之後還可以根據分表字段使用聯合查詢,避免了大多數資料庫架構分散式之後不能聯合查詢的缺點!
5,使用記憶體型資料儲存:使用redis等記憶體快取可以提高讀寫速度,在資料落庫之前快速讀寫資料,使用mongodb等作為大欄位,多位元組的key value儲存方式,防止關係型資料庫的不足!
6,負載均衡:使用nginx等負載均衡中介軟體,將請求分佈到不同的機器上,避免單個應用持續的處理引起血崩!
總之,高併發是一項程式設計師必不可少缺的技術,也是面試必問的知識點,只有直面它,解決它才能對技術有更深的認識!
高併發的路上踩了很多坑,以後再記錄下這些坑,和大家共勉!
-
3 # 總有叼民想害我
什麼是高併發
高併發是指,透過設計保證系統能夠同時並行處理很多請求。 高併發相關常用的一些指標有響應時間,吞吐量,每秒查詢率QPS(Query Per Second),併發使用者數等。
一般來講最佳化為兩大類,一是軟體層面的,二是硬體層面的。說到最佳化,可能更注重的是查詢的效率,所以要根據自己的業務進行拆分表建立索引,這是肯定必須要有的,再就是使用redis等高效能的資料庫,可以把熱資料放在記憶體中,並建立資料淘汰機制,redis的過期命令可以好好的利用起來,同時要注意不要有大量的資料在同一時刻過期。
軟體方面有以下幾種方案:一、負載均衡技術1.使用LVS伺服器負載均衡
LVS伺服器結合Keepalived做高可用,據估計lvs大概可以支撐5萬的併發量,由俄羅斯程式設計師使用C語言開發而成,技術7層網路架構的資料鏈路層,最接近底層的那一層。
2.LVS下面還可跟Nginx做負載均衡
再次分擔壓力,nginx也可以結合Keepalived做高可用。一旦主機掛掉了備份機立馬就能上崗。
二、資料庫最佳化1、單庫資料庫
一個初建的網站往往使用者群都是很小的,最簡單的網站架構就能解決實際的使用者需求,當然為了保證網站的穩定性和安全性,我們會把網站的應用部署到至少兩臺機器上,後臺的儲存使用資料庫,如果經濟實力允許,資料庫使用單臺伺服器部署
2、資料庫讀寫分離
一個數據庫主要負責寫操作我們稱之為主庫,一個數據庫專門負責讀操作我們稱之為副庫,副庫的資料都是從主庫匯入的,資料庫的讀寫分離可以有效的保證關鍵資料的安全性,但是有個缺點就是當用戶瀏覽資料時候,讀的資料都會有點延時,這種延時比起全站不可用那肯定是可以接受的。
3、快取技術
快取主要是適用於讀操作,並且快取的讀操作的效率要遠遠高於從資料庫以及硬碟讀取資料的效率。
5、資料庫的垂直拆分
業務再接著的增長下去,資料量也會隨之越來越大了,這樣發展下去總有一天主庫也會產生瓶頸了,那麼接下來我們又該如何解決主庫的瓶頸了?方法很簡單就是我們要拆分主庫的資料了,那麼我該以什麼維度拆分資料了?一個數據庫裡有很多張表,不同的表都針對不同的業務,網站的不同業務所帶來的資料量也不是不同的,這個時候系統的短板就是那些資料量最大的表,所以我們要把那些會讓資料庫產生瓶頸的表拆出來,例如電商系統裡商品表和交易表往往資料量非常大,那麼我們可以把這兩種表建立在單獨的兩個資料庫裡,這樣就拆分了資料庫的壓力,這種做法叫做資料垂直拆分
6、資料庫的水平拆分
表資料的處理已經超出了單臺伺服器的能力,這個時候我們就得對這個單庫單表的資料進行更進一步的拆分,也就是將一張表分佈到兩臺不同的資料庫裡,這個做法就是叫做資料的水平拆分了。可以根據專案拆分,再結合按年的拆分等。
硬體方面最佳化:加機器、分散式必不可少、換更強大的CPU、使用PCIE固態、高速記憶體等,相比軟體來說硬體對於高併發能力的提升也是同等重要的,要軟硬結合的提升才是終極解決方案。不斷的榨取硬體的效能。
-
4 # 會點程式碼的大叔
面對高併發的訪問,我總結了一下之前用過的方法,也查詢了一些資料進行了補充,跟大家分享一下:
HTML靜態化相比開啟一個靜態頁面來說,如果頁面需要連線後臺資料庫查詢資料,那麼後者的速度一定會比前者要慢。
HTML靜態化就是要把連線後臺資料庫查詢資料的工作提前做好,生成靜態化的頁面,那麼訪問的效率一定會提高很多。並且生成一套靜態化的頁面,所有使用者都可以訪問,這樣也會減少資料庫的壓力。
快取這個也比較常見了,快取也在好多個環節中發生奇效:
資料從資料庫到瀏覽器的過程:資料庫->應用資料集->記憶體物件->動態頁面->HTTP伺服器->使用者瀏覽器。
HTTP伺服器->使用者瀏覽器:瀏覽器都有本地快取
動態頁面->HTTP伺服器:動態頁面靜態化,然後把靜態化頁面放在快取裡
本地資料集->記憶體物件->動態頁面:一些語言框架本身就帶快取機制,也可以使用Memcached或Redis。
資料庫->應用資料集:資料庫有查詢快取
圖片伺服器分離圖片儲存在單獨的圖片伺服器上。
資料庫讀寫分離/分庫分表等一臺服務很難滿足業務上的壓力,那麼資料庫可以做讀寫分離,或者分庫分表。
負載均衡負載均衡分硬體和軟體。硬體我們用過F5,軟體經常用的是Nginx。
後臺應用部署多套,前面掛負載均衡,客戶端都直接訪問負載均衡,由它把訪問分攤到實際應用伺服器上。
映象解決不同網路接入商和地域帶來的使用者訪問速度差異。
CDNCDN=更智慧的映象+快取+流量導流
-
5 # 小鳥攻城獅
建議,
總原則:
最大化系統調優,最大化壓榨現有機器資源;資源不夠用了,加機器,同時可做到容量彈性擴充套件,削峰填谷,最後容錯容災,探活,高可用。
架構層面:從縱向擴充套件,變橫向擴充套件,分散式
說白了就是你的程式碼模組在一個機器上跑,也可以在多個機器上跑。
元件層面:前向代理,快取,反向代理
引數方面:適度連線超時,讀超時,寫超時,重試,降級。
切記:不同流量階段做不同的室,切勿為了高併發而併發。
-
6 # 一個存在感小透明
可以從引入Nginx,最佳化server邏輯,引入快取三個方面來最佳化網站,實現高併發。其中引入Nginx是見效最快,可擴充套件性最好的方法。
最佳化server邏輯我們先來討論這個費力又沒那麼討好的最差的方案。為什麼說費力呢,因為這就意味著你要去深挖程式碼邏輯,看看是否哪裡存在資源的浪費,導致了當前的qps瓶頸。如果不是初級Java工程師寫的專案,通常花了大把時間去review程式碼,能改進提高的空間也是十分有限的。因此,我說這是一個費力不討好的方案。因此,除非是之前埋了什麼坑,否則輕易不推薦這個方法。
引入快取根據我目前的經驗,大部分網站高併發的訪問都可以透過引入快取來最佳化。原本每個請求都要server到資料庫去查詢資料,再交給前端渲染,這個過程的查詢讀取操作是非常浪費資源的,而且當讀請求太多的時候,資料持久層若是扛不住的話,也會影響整個服務的併發性。這時候,將目前常用的資料放到快取中,利用快取的高速讀取優勢,就能緩解資料持久層的讀寫壓力,從而抗住更多的併發請求。舉個例子,情人節到了,那麼外賣網站上搜索花店的頻率一定會很高,這個時候,就可以將更多的花店,買花相關的資料放到快取裡,這樣就算請求很大,也都是與快取進行讀操作,緩解了資料持久層壓力,避免由於它的瓶頸而影響服務整體的併發性。
引入Nginx最後來說,可擴充套件性最佳的引入Nginx方案。Nginx最突出的功能是負載均衡,即可以將請求根據情況轉發給N臺伺服器(功能相同),這就意味著,如果一臺Tomcat的qps為W的話,那麼Nginx連線了N臺伺服器後,從使用者側感受到的服務整體qps就能夠達到N*W,這直接可以實現動態擴容。
比如情人節當天,搜尋花店相關的人實在是太多了,redis等快取抗住了,但是Tomcat還是沒抗住,這個時候,就可以動態的增加幾臺Tomcat,分流了每臺Tomcat要承載的請求量,這個高併發的問題自然就解決啦。
-
7 # 數通暢聯
高併發是系統能夠同時並行處理很多請求,它是網際網路系統架構設計中必須考慮的因素之一,相關常用的一些指標有響應時間、吞吐量、每秒查詢率QPS等。
想要提高網站的併發能力需要從以下幾個方面入手:
一、靜態資源伺服器對於Web伺服器來說,圖片是最消耗資源的,因此我們有必要將圖片與頁面進行分離。這也是基本上大型網站都會採用的策略,他們都有獨立的甚至很多臺的圖片伺服器,如FastDFS,這樣的架構可以降低提供頁面訪問請求的伺服器的系統壓力,並且可以保證系統不會因為圖片問題而崩潰,從而保證更高的系統消耗和執行效率。
二、負載均衡負載均衡將是大型網站解決高負荷訪問和大量併發請求採用的高階解決辦法,一般來說採用Nginx作為負載均衡伺服器。
三、叢集搭建透過搭建叢集環境實現高可用,叢集可以利用多個計算機進行平行計算從而獲得很高的計算速度,這種情況下,即使單一機器出現故障,整個系統還是能正常執行。一旦在伺服器上安裝並運行了群集服務,該伺服器即可加入群集。群集化操作可以減少單點故障數量,同時也實現了群集化資源的高可用性。
四、資料庫層面在資料庫中新增索引、SQL最佳化等效能最佳化手段來提升網站的併發訪問能力,還可以採取資料庫讀寫分離的方式,針對海量資料可以採用分庫分表技術提高訪問效能
五、快取層面在應用伺服器端,可以使用伺服器本地快取和分散式快取,透過快取在記憶體中的熱點資料處理使用者請求,加快請求處理過程,減輕資料庫負載壓力。常用的快取資料庫有Redis、Memecache、Ehcache等。
回覆列表
一般來說最佳化方向有兩個。將請求儘量攔截在系統上游(不要讓鎖衝突落到資料庫上去);充分利用快取,秒殺買票,這是一個典型的讀多些少的應用場景,大部分請求是車次查詢,票查詢,下單和支付才是寫請求。分為4個層次:瀏覽器,站點,服務,資料。瀏覽器端,攔截一些無效的功能操作,比如等待期間的多次點選提交;站點層面,防止程式設計師寫for迴圈呼叫呼叫服務,對前段過來的呼叫去重,對頁面快取;服務層來攔截,對於寫請求,做請求佇列,每次只透有限的寫請求去資料層,對於讀請求使用快取,業務邏輯的非同步;瀏覽器攔截了80%,站點層攔截了99.9%並做了頁面快取,服務層又做了寫請求佇列與資料快取,每次透到資料庫層的請求都是可控的。