一般的異步調用,無(wú)論是在一個(gè)服務(wù)內還是在兩個(gè)服務(wù)間,實(shí)現起來(lái)都比實(shí)現同步調用難得多。原因在于異步調用通常都需要通知最初發(fā)送消息的服務(wù),告訴它請求已經(jīng)完成了。如果你發(fā)送完請求就不再理會(huì ),那就沒(méi)必要再與調用方法通信或協(xié)作了。實(shí)現這個(gè)的方法很多且很簡(jiǎn)單,包括如下所示的PHP函數,它利用了符號在后臺運行進(jìn)程。

但是,并非所有服務(wù)發(fā)出請求后就不再管它什么狀態(tài)了。通常,調用方法想知道被調用的方法是什么時(shí)候完成的。原因可能是在結果返回前發(fā)生了其他的處理??梢栽O想一個(gè)電子商務(wù)平臺上的場(chǎng)景,即需要根據抵折扣代碼重新計算郵費。理想的情況是同步執行這兩個(gè)任務(wù),而不是計算郵費(可能需要調用供應商的第三方法),然后再對購物車(chē)中的物品處理折扣代碼。但在兩者都完成之前,我們不能把最終結果發(fā)送給用戶(hù)。
在大多數程序設計語(yǔ)言中有一種機制,是為母方法和被調用的異步子方法之間的協(xié)調和通信設計的,叫作回調。在C/C++語(yǔ)言中,這是通過(guò)函數指針實(shí)現的。在Java語(yǔ)言中,是通過(guò)對象引用實(shí)現的。有許多設計模式使用回調,如委托設計模式和觀(guān)察者設計模式。但是為什么要自找麻煩異步調用方法或服務(wù)呢?
我們之所以要自找麻煩進(jìn)行異步調用,是因為如果采用同步調用,所有的方法、服務(wù)和層都會(huì )被維系在一起,它們中的任何一個(gè)運行放慢或出了故障,都會(huì )造成整個(gè)系統發(fā)生延遲的級聯(lián)故障。把所有部件串聯(lián)起來(lái)會(huì )導致故障成倍增長(cháng)。我們只針對可用性討論了這一概念,但它其實(shí)也適用于每KLOC存在bug的概率。如果方法A、B和和C都有99.99%6的機會(huì )沒(méi)有bug,而且A方法同步地調用B方法,B方法同步地調用C方法,那么整個(gè)系統的邏輯流中有bug的概率就是99.99%×99.99%×99.9%=99.97%。
我們介紹過(guò),根據不同的客戶(hù),把系統的資源池劃分成獨立的泳道。這樣做的好處是如果一個(gè)泳道出了問(wèn)題,不會(huì )術(shù)生到其他客戶(hù)的泳道,這可以將問(wèn)題的影響最小化。此外,檢測故障也容易得多,因為同一個(gè)代碼右采用異步調用的模塊或方法也具有這種能力。
異步調用可以防止故障或運行減慢這種情況傳播,而且有助于在發(fā)生問(wèn)題時(shí)確定bug在哪里。許多遇到過(guò)數據庫問(wèn)題的人都在應用或Web層見(jiàn)證過(guò)這一點(diǎn),因為一個(gè)很慢的查詢(xún)使得連接受到阻礙堆積起來(lái)了,然后應用服務(wù)器上的套接字一直保持打開(kāi)狀態(tài)。數據庫的監控系統可能不會(huì )發(fā)出故障信號,但應用的監控系統則會(huì )發(fā)出故障信號。這種情況是在應用和數據庫服務(wù)器間使用了同步調用造成的,而且這種問(wèn)題還很難診斷。
當然,不能對系統中所有方法和層之間的調用都使用異步調用,所以真正的問(wèn)題是哪些調用應該采用異步調用。在使用非異步調用時(shí),應該具有超時(shí)設置,能夠在同步調用的方法或服務(wù)失敗時(shí),優(yōu)雅地處理錯誤或繼續進(jìn)行處理。決定哪些調用可以采用異步模式的方法是基于下列標準分析每個(gè)調用。
外部API/第三方。調用的是第三方的方法或外部API嗎?如果是,那么一定要采用異步調用。調用外部方法可能出現的問(wèn)題太多,所以不能采用同步調用。你一定不想讓自己的系統健康和可用性與你不能控制的系統緊密關(guān)聯(lián)在一起。
長(cháng)時(shí)間運行的進(jìn)程。要調用的進(jìn)程是不是運行時(shí)間很長(cháng)?運行的計算需求和1O需求是不是很高?如果是,最好采用異步調用。運行慢的進(jìn)程是比停機更棘手的問(wèn)題。
容易出錯的/頻繁更改的方法。調用的方法會(huì )頻繁更改嗎?修改的次數越多,代碼中有bug的可能性越大。不要把關(guān)鍵代碼和需要頻繁更改的代碼關(guān)聯(lián)在一起,否則會(huì )造成故障數量增加。
時(shí)間約束。當兩個(gè)進(jìn)程間沒(méi)有時(shí)間約束時(shí),考慮發(fā)出請求后就不再管什么狀態(tài)的子進(jìn)程。這個(gè)場(chǎng)景可能是新注冊的用戶(hù)收到一封歡迎郵件。雖然系統關(guān)心郵件是否發(fā)送出去了,但不應該等待郵件發(fā)送出去了才給用戶(hù)返回注冊頁(yè)面的結果。
對于決定網(wǎng)站制作是否使用異步調用來(lái)說(shuō),這只是幾條最重要的標準。我們把歸納所有標準作為練習留給讀者。雖然我們能再列出十條標準,但隨著(zhù)列出標準的增多,它們可能更適用于特定的系統。另外,和你的開(kāi)發(fā)團隊一起做這個(gè)練習,這會(huì )讓團隊中的每個(gè)人都注意到使用同步調用和異步調用的利弊,從而遵循本原則,更好地擴展系統。
本文地址:http://havencoinwallet.com//article/3518.html