下載本文檔
版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
第golang基于errgroup實(shí)現(xiàn)并發(fā)調(diào)用的方法目錄串行調(diào)用基于sync.WaitGroup實(shí)現(xiàn)簡(jiǎn)單的并發(fā)調(diào)用基于errgroup.Group實(shí)現(xiàn)并發(fā)調(diào)用總結(jié)
串行調(diào)用
在用go編寫web/rpc服務(wù)器的時(shí)候,經(jīng)常會(huì)出現(xiàn)需要對(duì)下游多個(gè)/組服務(wù)調(diào)用rpc(或者其他比較耗時(shí)的操作)的情況。
按照自然的寫法,比如對(duì)下游有ABC三個(gè)調(diào)用,串行順著寫,就總共要花費(fèi)TimeA+TimeB+TimeC的時(shí)間:
funcHandler(ctxcontext.Context){
vara,b,crespType
a=A(ctx)
b=B(ctx)
c=C(ctx)
基于sync.WaitGroup實(shí)現(xiàn)簡(jiǎn)單的并發(fā)調(diào)用
但經(jīng)常地,幾個(gè)rpc相互之間沒有依賴關(guān)系的情況,這時(shí),我們稍加思考就會(huì)想到使用并發(fā)的方式,同時(shí)發(fā)出請(qǐng)求,阻塞等到所有請(qǐng)求返回,這樣,總體耗時(shí)就變成了Max(TimeA,TimeB,TimeC),我們可以通過常用的sync.WaitGroup輕松實(shí)現(xiàn)這事:
funcHandler(ctxcontext.Context){
vara,b,crespType
wg:=sync.WaitGroup{}
wg.Add(3)
gofunc(){
deferwg.Done()
a=A(ctx)
gofunc(){
deferwg.Done()
b=B(ctx)
gofunc(){
deferwg.Done()
c=C(ctx)
wg.Wait()
但是現(xiàn)實(shí)事件是不完美的,尤其是在加入了網(wǎng)絡(luò)這一因素后,我們經(jīng)常會(huì)需要處理調(diào)用失敗的情況,很多情況下,并發(fā)的幾個(gè)操作只要任一失敗,整個(gè)處理就算失敗了,但是由于WaitGroup要等所有調(diào)用都done才能返回,因此調(diào)用時(shí)間是由耗時(shí)最長(zhǎng)的那個(gè)(不一定是失敗的)決定的,如果不是失敗的那個(gè),其實(shí)就產(chǎn)生了資源浪費(fèi),如下圖,B最先失敗了,此時(shí)邏輯上已經(jīng)可以返回,但是實(shí)際卻等到了最長(zhǎng)的調(diào)用-A返回了整個(gè)函數(shù)才返回:
funcHandler(ctxcontext.Context){
vara,b,crespType
varerrA,errB,errCerror
wg:=sync.WaitGroup{}
wg.Add(3)
gofunc(){
deferwg.Done()
a,errA=A(ctx)
gofunc(){
deferwg.Done()
b,errB=B(ctx)
gofunc(){
deferwg.Done()
c,errC=C(ctx)
wg.Wait()
iferrA!=nil{
//...
iferrB!=nil{
//...
iferrC!=nil{
//...
基于errgroup.Group實(shí)現(xiàn)并發(fā)調(diào)用
這對(duì)于追求極致的我們來說顯然是不能接受的,我們希望達(dá)到,如果有任意一個(gè)調(diào)用報(bào)錯(cuò),立刻讓所有調(diào)用返回的效果:
好在,我們有現(xiàn)成的工具可以用,通過引入/x/sync/errgroup,可以輕松實(shí)現(xiàn)上面的目的。
為了使用errgroup,先使用WithContext方法創(chuàng)建一個(gè)Group
wg,groupCtx:=errgroup.WithContext(ctx)
返回的第一個(gè)參數(shù)是*errgroup.Group,第二個(gè)則是在子調(diào)用中應(yīng)該使用的context。
然后,使用Go方法調(diào)用所有的并發(fā)方法
wg.Go(func()error{
varerrerror
a,err=A(groupCtx)
returnerr
最后,使用Wait方法等待并發(fā)結(jié)束,返回值是所有子調(diào)用中第一個(gè)非nil的error,全成功的話就是nil。
iferr:=wg.Wait();err!=nil{
//...
因此整體,我們的代碼差不多就長(zhǎng)這個(gè)樣子
funchandler(ctxcontext.Context){
vara,b,crespType
wg,groupCtx:=errgroup.WithContext(ctx)
wg.Go(func()error{
varerrerror
a,err=A(groupCtx)
returnerr
wg.Go(func()error{
varerrerror
b,err=B(groupCtx)
returnerr
wg.Go(func()error{
varerrerror
c,err=C(groupCtx)
returnerr
iferr:=wg.Wait();err!=nil{
//...錯(cuò)誤處理
//全部成功
errgroup內(nèi)部通過封裝了waitGroup和sync.Once實(shí)現(xiàn)了這個(gè)語法糖。
使用時(shí)特別要注意的是,errgroup的提前取消調(diào)用rpc是通過cancel那個(gè)返回的context(即上面的groupCtx)實(shí)現(xiàn)的,因此在所有子調(diào)用中都要實(shí)現(xiàn)監(jiān)聽groupCtx的Done事件。而在正常的rpc框架中都已經(jīng)幫我們實(shí)現(xiàn)了這件事,因此我們只要保證傳進(jìn)去的是groupCtx
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 信息化安全防護(hù)與應(yīng)急處置手冊(cè)(標(biāo)準(zhǔn)版)
- 企業(yè)合同管理培訓(xùn)指南
- 國(guó)培計(jì)劃培訓(xùn)制度
- 案場(chǎng)物業(yè)培訓(xùn)制度
- 職業(yè)培訓(xùn)實(shí)操室管理制度
- 會(huì)議制度培訓(xùn)制度
- 局培訓(xùn)管理制度
- 幼兒園教師游戲培訓(xùn)制度
- 化工培訓(xùn)教育制度
- 護(hù)理操作培訓(xùn)制度
- 廉潔應(yīng)征承諾書
- 產(chǎn)品故障分析報(bào)告
- 公司外來參觀人員安全須知培訓(xùn)課件
- 手術(shù)室查對(duì)制度
- 第三次全國(guó)國(guó)土調(diào)查工作分類與三大類對(duì)照表
- 農(nóng)村集貿(mào)市場(chǎng)改造項(xiàng)目實(shí)施方案
- 消防設(shè)施檢查記錄表
- 酒店協(xié)議價(jià)合同
- 哈爾濱工業(yè)大學(xué)簡(jiǎn)介宣傳介紹
- 中國(guó)兒童錯(cuò)頜畸形早期矯治專家共識(shí)
- GB/T 5147-2003漁具分類、命名及代號(hào)
評(píng)論
0/150
提交評(píng)論