欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Golang實(shí)現(xiàn)超時(shí)退出的三種方式

 更新時(shí)間:2020年03月24日 15:37:34   作者:JackieZheng  
這篇文章主要介紹了Golang三種方式實(shí)現(xiàn)超時(shí)退出,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下

前段時(shí)間發(fā)現(xiàn)線上有個(gè)服務(wù)接口,總是間歇性告警,有時(shí)候一天兩三次,有時(shí)候一天都沒有。

告警的邏輯是在一個(gè)接口中異步調(diào)用了另一個(gè)HTTP接口,這個(gè)HTTP接口調(diào)用出現(xiàn)超時(shí)。但是我去問了負(fù)責(zé)這個(gè)HTTP接口的同學(xué),人家說他們的接口相應(yīng)都是毫秒級(jí)別,還截圖監(jiān)控了,有圖有真相,我還能說啥。

但是,超時(shí)是確實(shí)存在的,只是請(qǐng)求還可能沒有到人家服務(wù)那邊。

這種偶發(fā)性問題不好復(fù)現(xiàn),偶爾來個(gè)告警也挺煩的,第一反應(yīng)還是先解決問題,思路也簡(jiǎn)單,失敗后重試。

解決方法

且不談重試策略,先說說什么時(shí)候觸發(fā)重試。

我們可以在接口請(qǐng)求出錯(cuò)拋出err的時(shí)候重試,但是這種不好控制,如果一個(gè)請(qǐng)求出去,十來秒都沒有響應(yīng),則這個(gè)協(xié)程就要傻傻的等他報(bào)錯(cuò)才能重試,浪費(fèi)生命啊~

所以結(jié)合上面同學(xué)給出的毫秒級(jí)響應(yīng)指標(biāo),可以設(shè)定一個(gè)超時(shí)時(shí)間,如果在指定超時(shí)時(shí)間后沒有返回結(jié)果,則重試(這篇重試不是重點(diǎn))。

func AsyncCall() {
 ctx, cancel := context.WithTimeout(context.Background(), time.Duration(time.Millisecond*800))
 defer cancel()
 go func(ctx context.Context) {
 // 發(fā)送HTTP請(qǐng)求
 }()

 select {
 case <-ctx.Done():
 fmt.Println("call successfully!!!")
 return
 case <-time.After(time.Duration(time.Millisecond * 900)):
 fmt.Println("timeout!!!")
 return
 }
}

說明

1、通過context的WithTimeout設(shè)置一個(gè)有效時(shí)間為800毫秒的context。

2、該context會(huì)在耗盡800毫秒后或者方法執(zhí)行完成后結(jié)束,結(jié)束的時(shí)候會(huì)向通道ctx.Done發(fā)送信號(hào)。

3、有人可能要問,你這里已經(jīng)設(shè)置了context的有效時(shí)間,為什么還要加上這個(gè)time.After呢?

這是因?yàn)樵摲椒▋?nèi)的context是自己申明的,可以手動(dòng)設(shè)置對(duì)應(yīng)的超時(shí)時(shí)間,但是在大多數(shù)場(chǎng)景,這里的ctx是從上游一直傳遞過來的,對(duì)于上游傳遞過來的context還剩多少時(shí)間,我們是不知道的,所以這時(shí)候通過time.After設(shè)置一個(gè)自己預(yù)期的超時(shí)時(shí)間就很有必要了。

4、注意,這里要記得調(diào)用cancel(),不然即使提前執(zhí)行完了,還要傻傻等到800毫秒后context才會(huì)被釋放。

總結(jié)

上面的超時(shí)控制是搭配使用了ctx.Done和time.After。

Done通道負(fù)責(zé)監(jiān)聽context啥時(shí)候完事,如果在time.After設(shè)置的超時(shí)時(shí)間到了,你還沒完事,那我就不等了,執(zhí)行超時(shí)后的邏輯代碼。

舉一反三

那么,除了上面這種超時(shí)控制策略,還有其他的套路嗎?

有,但是大同小異。

第一種:使用time.NewTimer

func AsyncCall() {
 ctx, cancel := context.WithTimeout(context.Background(), time.Duration(time.Millisecond * 800))
 defer cancel()
 timer := time.NewTimer(time.Duration(time.Millisecond * 900))

 go func(ctx context.Context) {
 // 發(fā)送HTTP請(qǐng)求
 }()

 select {
 case <-ctx.Done():
 timer.Stop()
 timer.Reset(time.Second)
 fmt.Println("call successfully!!!")
 return
 case <-timer.C:
 fmt.Println("timeout!!!")
 return
 }
}

這里的主要區(qū)別是將time.After換成了time.NewTimer,也是同樣的思路如果接口調(diào)用提前完成,則監(jiān)聽到Done信號(hào),然后關(guān)閉定時(shí)器。

否則的話,會(huì)在指定的timer即900毫秒后執(zhí)行超時(shí)后的業(yè)務(wù)邏輯。

第二種:使用通道

func AsyncCall() {
 ctx := context.Background()
 done := make(chan struct{}, 1)

 go func(ctx context.Context) {
 // 發(fā)送HTTP請(qǐng)求
 done <- struct{}{}
 }()

 select {
 case <-done:
 fmt.Println("call successfully!!!")
 return
 case <-time.After(time.Duration(800 * time.Millisecond)):
 fmt.Println("timeout!!!")
 return
 }
}

1、這里主要利用通道可以在協(xié)程之間通信的特點(diǎn),當(dāng)調(diào)用成功后,向done通道發(fā)送信號(hào)。

2、監(jiān)聽Done信號(hào),如果在time.After超時(shí)時(shí)間之前接收到,則正常返回,否則走向time.After的超時(shí)邏輯,執(zhí)行超時(shí)邏輯代碼。

3、這里使用的是通道和time.After組合,也可以使用通道和time.NewTimer組合。

總結(jié)

本篇主要介紹如何實(shí)現(xiàn)超時(shí)控制,主要有三種

1、context.WithTimeout/context.WithDeadline + time.After

2、context.WithTimeout/context.WithDeadline + time.NewTimer

3、channel + time.After/time.NewTimer

到此這篇關(guān)于Golang三種方式實(shí)現(xiàn)超時(shí)退出的文章就介紹到這了,更多相關(guān)Golang超時(shí)退出內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Go語言微服務(wù)中實(shí)現(xiàn)鏈路追蹤

    Go語言微服務(wù)中實(shí)現(xiàn)鏈路追蹤

    在微服務(wù)架構(gòu)中,鏈路追蹤技術(shù)可以幫助我們跟蹤請(qǐng)求在各個(gè)服務(wù)之間的傳播路徑,本文就來介紹一下Go語言微服務(wù)中實(shí)現(xiàn)鏈路追蹤,感興趣的可以了解一下
    2024-12-12
  • 從生成CRD到編寫自定義控制器教程示例

    從生成CRD到編寫自定義控制器教程示例

    這篇文章主要為大家介紹了從生成CRD到編寫自定義控制器的教程示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-05-05
  • golang 如何刪除二進(jìn)制文件中的源碼路徑信息

    golang 如何刪除二進(jìn)制文件中的源碼路徑信息

    這篇文章主要介紹了golang 如何刪除二進(jìn)制文件中的源碼路徑信息,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2021-04-04
  • Go語言中時(shí)間time相關(guān)處理方法詳解

    Go語言中時(shí)間time相關(guān)處理方法詳解

    在Go語言中,time?包是處理時(shí)間和日期的核心,它提供了豐富的函數(shù)和方法,用于顯示、測(cè)量、計(jì)算、格式化、解析時(shí)間等,本文給大家詳細(xì)介紹了Go時(shí)間time相關(guān)處理方法的相關(guān)資料,需要的朋友可以參考下
    2024-10-10
  • Golang中使用errors返回調(diào)用堆棧信息

    Golang中使用errors返回調(diào)用堆棧信息

    這篇文章給大家介紹了Golang中如何使用errors返回調(diào)用堆棧信息,文章通過代碼示例給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下
    2023-12-12
  • Go語言實(shí)現(xiàn)的簡(jiǎn)單網(wǎng)絡(luò)端口掃描方法

    Go語言實(shí)現(xiàn)的簡(jiǎn)單網(wǎng)絡(luò)端口掃描方法

    這篇文章主要介紹了Go語言實(shí)現(xiàn)的簡(jiǎn)單網(wǎng)絡(luò)端口掃描方法,實(shí)例分析了Go語言網(wǎng)絡(luò)程序的實(shí)現(xiàn)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-02-02
  • VS Code配置Go語言開發(fā)環(huán)境的詳細(xì)教程

    VS Code配置Go語言開發(fā)環(huán)境的詳細(xì)教程

    這篇文章主要介紹了VS Code配置Go語言開發(fā)環(huán)境的詳細(xì)教程,本文通過實(shí)例代碼圖文相結(jié)合的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-05-05
  • Go每日一庫(kù)之quicktemplate的使用

    Go每日一庫(kù)之quicktemplate的使用

    quicktemplate快速、功能強(qiáng)大、易于使用的Go模板引擎。比html/模板快20倍,本文我們就詳細(xì)的介紹一下quicktemplate的具體使用,感興趣的可以了解一下
    2021-07-07
  • 深入淺出Go:掌握基礎(chǔ)知識(shí)的關(guān)鍵要點(diǎn)

    深入淺出Go:掌握基礎(chǔ)知識(shí)的關(guān)鍵要點(diǎn)

    Go是一種開源的編程語言,由Google開發(fā),它具有簡(jiǎn)潔、高效、并發(fā)性強(qiáng)的特點(diǎn),適用于構(gòu)建可靠的、高性能的軟件系統(tǒng),本文將介紹Go的基礎(chǔ)知識(shí),需要的朋友可以參考下
    2023-10-10
  • 如何使用大學(xué)教育郵箱下載golang等軟件(推薦)

    如何使用大學(xué)教育郵箱下載golang等軟件(推薦)

    這篇文章主要介紹了如何使用大學(xué)教育郵箱下載goland等軟件,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-09-09

最新評(píng)論