用通俗的話(huà)講講熔斷和服務(wù)降級(jí)
熔斷和降級(jí)(也叫服務(wù)降級(jí)),一般是通過(guò)組件實(shí)現(xiàn)的,而不是spring框架內(nèi)。比如spring boot框架做增刪改查,外加引入spring cloud框架的hystrix或spring cloud alibaba框架的sentinel做熔斷和降級(jí),當(dāng)然還可以做限流。
熔斷的本意是,當(dāng)下對(duì)某個(gè)api接口發(fā)起的服務(wù),錯(cuò)誤率太高,或者耗時(shí)過(guò)長(zhǎng)請(qǐng)求的比例過(guò)高,所以就認(rèn)為該api接口當(dāng)下負(fù)載過(guò)大,應(yīng)當(dāng)在之后的一段時(shí)間內(nèi),讓該api停止對(duì)外服務(wù)。
和熔斷相關(guān)的有如下的參數(shù)。
1 時(shí)間窗口,比如5秒。
2 最小訪(fǎng)問(wèn)量,比如100個(gè)。
3 錯(cuò)誤率或者是慢請(qǐng)求的比例下限,比如是50%。
4 熔斷后的等待時(shí)間,比如是2秒。
比如有個(gè)服務(wù)api是對(duì)外提供查詢(xún)風(fēng)控信息的,設(shè)置了上述熔斷參數(shù),遇到如下情況時(shí)會(huì)熔斷。
1 時(shí)間窗口5秒內(nèi),至少收到100個(gè)請(qǐng)求。這個(gè)是先決條件,比如5秒內(nèi)只收到99個(gè)請(qǐng)求,哪怕這99個(gè)請(qǐng)求全都失?。ɑ蚍祷剡^(guò)慢),也不會(huì)熔斷。
2 如果5秒內(nèi)收到100個(gè)請(qǐng)求后,再去看里面失效請(qǐng)求或慢查詢(xún)請(qǐng)求的比例,如果高于50%,即該接口熔斷2秒,這個(gè)過(guò)程中,發(fā)到該風(fēng)控接口的請(qǐng)求全都立即返回失敗。
3 在2秒以后,(hystrix或sentinel等)支持熔斷的組件再去采樣,如果依然是5秒內(nèi)請(qǐng)求個(gè)數(shù)大于等于100,并且失敗或慢查詢(xún)的比例高于50%,繼續(xù)熔斷2秒。否則恢復(fù)正常。
為什么要引入熔斷機(jī)制呢?因?yàn)檎?qǐng)求api的線(xiàn)程,是需要耗費(fèi)內(nèi)存等資源的,比如請(qǐng)求風(fēng)控api這個(gè)線(xiàn)程,持續(xù)了5秒,那么服務(wù)器在這5秒以?xún)?nèi),就得耗費(fèi)一定的資源維護(hù)這個(gè)線(xiàn)程。
對(duì)服務(wù)器來(lái)說(shuō),能容納的請(qǐng)求線(xiàn)程個(gè)數(shù)是有上限的,具體要看服務(wù)器的配置,假設(shè)是1000個(gè)。如果不引入熔斷機(jī)制,而并發(fā)量又高,一秒會(huì)新增1000個(gè)訪(fǎng)問(wèn)風(fēng)控API接口的線(xiàn)程,那么每個(gè)線(xiàn)程都得被維持5秒,而且由于風(fēng)控接口可能出現(xiàn)故障,不少線(xiàn)程(或者說(shuō)大多數(shù)線(xiàn)程)又拿不到期望結(jié)果。這種情況下,與其線(xiàn)程在5秒后因失敗而被終止,那么還不如立即啟動(dòng)熔斷機(jī)制,讓一些線(xiàn)程在發(fā)起請(qǐng)求后立即得到錯(cuò)誤的結(jié)果。
否則的話(huà),大量堆積的線(xiàn)程,就會(huì)耗盡服務(wù)器的內(nèi)存等資源,甚至可能還耗盡數(shù)據(jù)庫(kù)連接對(duì)象,最終導(dǎo)致部署在這臺(tái)服務(wù)器上的所有服務(wù)都不可用。所以,熔斷其實(shí)是種保護(hù)機(jī)制,尤其在高并發(fā)場(chǎng)景下,真得預(yù)先設(shè)置好熔斷策略。
服務(wù)降級(jí)的本意是,在高并發(fā)等場(chǎng)景,一些用戶(hù)請(qǐng)求難免會(huì)得不到預(yù)期的結(jié)果,這種情況下,應(yīng)當(dāng)針對(duì)這些請(qǐng)求快速返回,同時(shí)提供一個(gè)用戶(hù)尚能接受的結(jié)果。
比如在某電商網(wǎng)站,有時(shí)候去搜索一個(gè)商品,期望的結(jié)果自然是返回搜索列表,但在某個(gè)時(shí)刻,正好服務(wù)器里并發(fā)量太高,或者因?yàn)榉N種原因,搜索商品的請(qǐng)求無(wú)法得到期望結(jié)果,這種情況下,較好的處理方法是,快速(而不是等待若干時(shí)間)返回一個(gè)“請(qǐng)稍后再試”的頁(yè)面。
如果不引入服務(wù)降級(jí),那么用戶(hù)真可能會(huì)直接看到一個(gè)只有資深程序員才能看懂的異常提示,比如哪號(hào)內(nèi)存出問(wèn)題,或者xx組件的xx行出問(wèn)題。與其這樣,還不如返回個(gè)能讓用戶(hù)看得懂的界面。
在一些事件場(chǎng)景,熔斷和服務(wù)降級(jí)一般是整合一起使用的,比如查詢(xún)商品的接口方法出現(xiàn)熔斷,需要等待2秒后再采樣,在這2秒內(nèi),hystrix或sentinel等能實(shí)現(xiàn)服務(wù)降級(jí)功能的組件,會(huì)把請(qǐng)求抓發(fā)到“請(qǐng)稍后再試”的頁(yè)面,從而實(shí)現(xiàn)服務(wù)降級(jí)。