感覺面試過程中一定會(huì)問到的問題有三個(gè),多線程,JVM,高并發(fā)!
盡管工作過程中基本不用這三個(gè)要命的東西!還是阻擋不了面試官的趨之若鶩,下面就圍繞其中一個(gè)---高并發(fā),來說下自己的理解!
何謂并發(fā)?同時(shí)處理操作!
何謂高并發(fā)?同時(shí)處理很多操作!
什么操作呢?頁面請(qǐng)求:一個(gè)簡單的頁面請(qǐng)求可能包含了很多內(nèi)容,比如驗(yàn)證登錄,靜態(tài)頁面加載,動(dòng)態(tài)數(shù)據(jù)加載(涉及到訪問數(shù)據(jù)庫,緩存等等),圖片加載,線程的啟動(dòng)和銷毀!每一個(gè)操作都需要花費(fèi)時(shí)間,總得加起來可能只有200ms,但是如果你的服務(wù)器處理能力只能是一個(gè)請(qǐng)求級(jí)別的,那么100萬個(gè)請(qǐng)求,你就需要20萬秒,大概是幾天的時(shí)間!
當(dāng)然實(shí)際生活中我們沒有這么水的服務(wù)器,換句話說,我們可以通過選擇好的服務(wù)器來提高我們的并發(fā)能力!也就是說硬件的指數(shù)型升級(jí)能讓我們應(yīng)付高并發(fā),但是事與愿違,如果處理一個(gè)請(qǐng)求占用的是100k內(nèi)存,那么100萬請(qǐng)求就需要100萬M,也就是差不多100G的內(nèi)存!這無疑是現(xiàn)實(shí)生活中還沒有的!
而且單機(jī)服務(wù)器容易受到網(wǎng)絡(luò),斷電等多方面原因的影響!所以一個(gè)分布式集群就是我們處理高并發(fā)最有效的方法!
在此之前,我們先來熟悉幾個(gè)關(guān)于高并發(fā)的關(guān)鍵參數(shù)!
QPS:每秒處理的請(qǐng)求數(shù)量!
響應(yīng)時(shí)間:處理一個(gè)請(qǐng)求需要的時(shí)間!
吞吐量:單位時(shí)間內(nèi)的處理請(qǐng)求數(shù)量!
最大并發(fā)數(shù):同一時(shí)間能支持的最大請(qǐng)求數(shù)!
從這些指標(biāo)來看,我們提高并發(fā)量有兩種方式:提高處理速度和減少處理時(shí)間!
一般來說有下面這些常規(guī)辦法:
1,更多的靜態(tài)資源:將代碼中的大量枚舉(容器加載時(shí)寫入map,放入本地緩存),數(shù)據(jù)庫中的定義表(定時(shí)任務(wù)放入緩存),固定配置,HTML文件等靜態(tài)化處理,緩存起來!
2,圖片服務(wù)器:一般來說,圖片在一個(gè)頁面上屬于數(shù)據(jù)量比較大的東西,盡量避免動(dòng)態(tài)數(shù)據(jù)和圖片的順序渲染,使用圖片服務(wù)器分離數(shù)據(jù)和圖片!
3,優(yōu)化代碼:盡量避免多層循環(huán),避免多次訪問數(shù)據(jù)庫,使用多線程提高cpu使用率和執(zhí)行速度,使用java8的流式處理和并行處理提高速度!
4,數(shù)據(jù)庫:采用分庫分表,mysql5.7之后,據(jù)說可以支持秒級(jí)百萬級(jí)數(shù)據(jù)查詢。速度相當(dāng)之快,使用八庫1024表,可以滿足數(shù)據(jù)庫一秒數(shù)百萬的并發(fā)!同時(shí)可以開啟緩存,寫入存儲(chǔ)過程等加快訪問時(shí)間!分庫分表之后還可以根據(jù)分表字段使用聯(lián)合查詢,避免了大多數(shù)數(shù)據(jù)庫架構(gòu)分布式之后不能聯(lián)合查詢的缺點(diǎn)!
5,使用內(nèi)存型數(shù)據(jù)存儲(chǔ):使用redis等內(nèi)存緩存可以提高讀寫速度,在數(shù)據(jù)落庫之前快速讀寫數(shù)據(jù),使用mongodb等作為大字段,多字節(jié)的key value保存方式,防止關(guān)系型數(shù)據(jù)庫的不足!
6,負(fù)載均衡:使用nginx等負(fù)載均衡中間件,將請(qǐng)求分布到不同的機(jī)器上,避免單個(gè)應(yīng)用持續(xù)的處理引起血崩!
總之,高并發(fā)是一項(xiàng)程序員必不可少缺的技術(shù),也是面試必問的知識(shí)點(diǎn),只有直面它,解決它才能對(duì)技術(shù)有更深的認(rèn)識(shí)!
高并發(fā)的路上踩了很多坑,以后再記錄下這些坑,和大家共勉!