最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Go語言實現(xiàn)請求超時處理的方法總結(jié)

 更新時間:2023年05月04日 10:51:42   作者:starrySky  
這篇文章主要為大家詳細介紹了Go語言中實現(xiàn)請求的超時控制的方法,主要是通過timer和timerCtx來實現(xiàn)請求的超時控制,希望對大家有所幫助

1. 簡介

本文將介紹Go語言中實現(xiàn)請求的超時控制的方法,主要是通過timertimerCtx來實現(xiàn)請求的超時控制。

但是在本文中,暫未展示在哪些場景下,timerCtx實現(xiàn)超時控制相對于timer實現(xiàn)的優(yōu)點,或者在哪些場景下,timer相對于timerCtx在哪些場景下使用更為合適,后續(xù)將會再進行描述。

2. 問題引入

當使用Go語言進行網(wǎng)絡請求時,程序可能會因為請求處理時間過長而被卡住,無法繼續(xù)執(zhí)行后續(xù)代碼。這種情況會導致程序性能下降,用戶體驗變差,甚至會導致系統(tǒng)崩潰。特別是在高并發(fā)場景下,這種問題更加突出。

舉個例子,假設我們需要從一個遠程服務獲取一些數(shù)據(jù),我們可以使用Go標準庫中的http包進行網(wǎng)絡請求。代碼可能類似于以下示例:

func makeRequest(url string) (string, error) {
    // 創(chuàng)建 http.Client 客戶端實例
    client := &http.Client{}
    // 創(chuàng)建請求
    req, err := http.NewRequest("GET", url, nil)
    if err != nil {
        return "", err
    }
    // 執(zhí)行請求
    resp, err := client.Do(req)
    if err != nil {
        return "", err
    }
    // 讀取響應內(nèi)容
    defer resp.Body.Close()
    body, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        return "", err
    }
    return string(body), nil
}
func main() {
    url := "https://baidu.com"
    result, err := makeRequest(url)
    if err != nil {
        return
    }
}

這里定義了一個makeRequest函數(shù),該函數(shù)使用http.Client客戶端發(fā)送HTTP請求并返回響應體。

但是,如果請求響應時間過長,程序就會一直等待直到請求超時或者響應返回。如果是單個請求的情況下,這種等待可能不會對系統(tǒng)產(chǎn)生太大的影響。但是在高并發(fā)場景下,這種情況可能會導致系統(tǒng)性能大幅下降。

因此,我們需要一種方法來對請求進行超時處理,確保程序能夠及時響應其他請求,而不是一直等待。

3. timer的實現(xiàn)方案

3.1 timer的基本介紹

Timer可以通過time.NewTimer()time.AfterFunc()函數(shù)創(chuàng)建。NewTimer()函數(shù)創(chuàng)建一個Timer對象,該對象在指定的時間間隔后向一個通道發(fā)送一個當前時間。AfterFunc()函數(shù)則會在指定的時間間隔后執(zhí)行一個函數(shù)。

通過timer,可以實現(xiàn)許多常見的任務,比如定期執(zhí)行某個操作、超時控制、任務調(diào)度等。同時,在Go語言中,timer還可以方便地取消或重置,能夠更加靈活地控制程序的運行。

所以,這里我們可以使用timer實現(xiàn)請求的超時控制,下面我們來看使用timer來實現(xiàn)超時控制的具體步驟。

3.2 timer實現(xiàn)超時控制

如果需要使用timer實現(xiàn)請求的超時控制,可以通過以下步驟來實現(xiàn)請求的超時處理,具體如下:

  • 創(chuàng)建一個timer對象??梢允褂?code>time.NewTimer()函數(shù)創(chuàng)建一個新的timer對象
  • 啟動一個goroutine來執(zhí)行具體的業(yè)務邏輯
  • select語句中處理超時事件。在select語句中,使用一個case來處理timer的超時事件
  • 在需要控制超時的地方使用上述邏輯

下面是一個示例代碼,演示了如何使用timer實現(xiàn)超時控制:

package main
import (
    "fmt"
    "time"
)
func main() {
    // 1. 創(chuàng)建一個timer對象,等待5秒鐘
    timeout := time.NewTimer(5 * time.Second)
    ch := make(chan string, 1)
    go func() {
       // 2. 這里我們簡單模擬一個需要執(zhí)行10秒的操作
       time.Sleep(10 * time.Second)
       ch <- "hello world"
    }()
    // 3. 在select語句中處理超時事件 或者請求正常返回
    select {
    case <-timeout.C:
        // 執(zhí)行任務超時處理
       fmt.Println("操作超時")
       return
    case result := <-ch:
        // 執(zhí)行正常業(yè)務流程
       fmt.Println(result)
    }
    // 停止timer
    if !timeout.Stop() {
       <-timeout.C
    }
    // 操作執(zhí)行完成
    fmt.Println("操作執(zhí)行完成")
}

這里在主協(xié)程處通過NewTimer創(chuàng)建一個定時器,然后啟動一個協(xié)程對任務進行處理,當處理完成后,通過channel告知其他協(xié)程。

在主協(xié)程中,通過select語句,對定時器timerchannel同時進行監(jiān)聽,當任務執(zhí)行超時時,則執(zhí)行超時邏輯;如果任務在超時前完成,則執(zhí)行正常處理流程。

通過這種方式,實現(xiàn)了請求的超時處理。

3.3 對問題的解決

下面展示使用 timer 來實現(xiàn)對請求的超時處理,從而避免程序長期處于等待狀態(tài),造成系統(tǒng)性能大幅下降。

func makeRequest(url string) (string, error) {
      // 具體的業(yè)務邏輯
}
func main() {
    url := "https://baidu.com"
    // 設置超時時間為5秒
    timeout := 5 * time.Second
    // 創(chuàng)建一個計時器,等待超時
    timer := time.NewTimer(timeout)
    // 創(chuàng)建一個 channel,用于接收請求的結(jié)果
    ch := make(chan string, 1)
    // 啟動協(xié)程執(zhí)行請求
    go func() {
        result, err := makeRequest(url)
        if err != nil {
            ch <- fmt.Sprintf("Error: %s", err.Error())
            return
        }
        ch <- result
    }()
    // 等待超時或者請求結(jié)果返回
    select {
    case result := <-ch:
        fmt.Println(result)
    case <-timer.C:
        fmt.Println("Request timed out")
    }
    // 請求完成后,停止定時器
    if !timer.Stop() {
        <-timer.C
    }
}

在這個示例中,我們使用 time 包創(chuàng)建一個計時器,等待超時。同時,我們還創(chuàng)建了一個 channel,用于接收請求的結(jié)果。然后我們啟動一個協(xié)程執(zhí)行請求,一旦請求返回,就會將結(jié)果發(fā)送到 channel 中。在主協(xié)程中,我們使用 select 語句等待超時或者請求結(jié)果返回。如果請求在超時之前返回,就會從 channel 中接收到結(jié)果并打印出來。如果請求超時,就會打印出相應的錯誤信息。

從而實現(xiàn)了避免了處理某些場景請求時,避免系統(tǒng)進入長時間等待的問題的出現(xiàn)。

4.timetCtx的實現(xiàn)方案

雖然,timerselect實現(xiàn)超時控制的邏輯并不復雜,但是在某些場景下,使用timerCtx來實現(xiàn)超時控制,相對來說是更為簡單的,而且現(xiàn)有開源框架基本上也是通過該方式來實現(xiàn)的。所以接下來,我們來對timerCtx進行基本介紹,同時使用timerCtx來實現(xiàn)超時控制。

4.1 timerCtx的基本介紹

timerCtx是一種在Go語言中使用ContextTimer結(jié)合實現(xiàn)超時控制的方式。它是一個自定義的結(jié)構(gòu)體類型,用于封裝定時器和取消函數(shù),并提供一種方便的方式來取消goroutine的執(zhí)行,從而避免出現(xiàn)goroutine泄露等問題。

4.2 timerCtx的基本使用方式

當使用timetCtx實現(xiàn)超時控制,通常需要以下幾個步驟:

  • 調(diào)用 context.WithTimeout() 方法,創(chuàng)建一個超時控制的子上下文。
  • 啟動一個協(xié)程來執(zhí)行任務。
  • 在主協(xié)程中,通過select語句調(diào)用 Done() 方法來判斷是否超時。如果 Done() 方法返回的 channel 被關閉,則意味著已經(jīng)超時,需要及時停止當前任務并返回。
  • 在函數(shù)返回時,調(diào)用取消函數(shù) cancel(),釋放占用的資源。

下面是一個示例代碼,演示了如何使用timerCtx實現(xiàn)超時控制:

package main
import (
    "context"
    "fmt"
    "time"
)
func main() {
    // 創(chuàng)建一個timerCtx,設置超時時間為3秒
    ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
    // 調(diào)用cancel函數(shù),釋放占用的資源  
    defer cancel()
    // 開啟一個協(xié)程執(zhí)行任務
    ch := make(chan string, 1)
    go func() {
        // 模擬任務執(zhí)行,休眠5秒
        time.Sleep(5 * time.Second)
        ch <- "hello world"
    }()
    // 在主協(xié)程中等待timerCtx超時或任務完成
    select {
    case <-ctx.Done():
        fmt.Println("timeout")
    case result := <-ch:
        fmt.Println(result)
    }
}

這里在主協(xié)程處通過context.WithTimeout創(chuàng)建一個timerCtx,然后啟動一個協(xié)程對任務進行處理,當處理完成后,通過channel告知其他協(xié)程。

其次,對于timerCtx來說,調(diào)用Done方法將會返回一個channal,當超時后,該channel將會自動被關閉,此時通過select,將能夠從該處于close狀態(tài)的channel中接收到數(shù)據(jù)。

因此,在主協(xié)程中,通過select語句,對這兩個channel同時進行監(jiān)聽,當任務執(zhí)行超時時,則執(zhí)行超時邏輯;如果任務在超時前完成,則執(zhí)行正常處理流程。通過這種方式,實現(xiàn)了請求的超時處理。

4.3 對問題的解決

下面使用 context.WithTimeoutselect 來實現(xiàn)請求的超時處理,通過這種方式,避免程序長期處于等待狀態(tài),具體代碼實現(xiàn)如:

// 執(zhí)行具體的業(yè)務邏輯
func makeRequest(ctx context.Context, url string) (string, error) {}
func main() {
    url := "https://baidu.com"
    // 創(chuàng)建一個不帶超時的context
    ctx := context.Background()
    // 1. 創(chuàng)建一個帶超時的timerCtx
    timeout := 5 * time.Second
    timerCtx, cancel := context.WithTimeout(ctx, timeout)
    //5. 在函數(shù)返回時,調(diào)用取消函數(shù) cancel(),釋放占用的資源。
    defer cancel()
    // 創(chuàng)建一個 channel,用于接收請求的結(jié)果
    ch := make(chan string, 1)
    // 2. 將子上下文傳遞給需要進行超時控制的函數(shù), 啟動協(xié)程執(zhí)行請求
    go func() {
       result, err := makeRequest(ctx,url)
        if err != nil {
            ch <- fmt.Sprintf("Error: %s", err.Error())
            return
        }
        ch <- result
    }()
    // 函數(shù)可以通過調(diào)用 context.Context 對象的 Done() 方法來判斷是否超時。
    // 如果 Done() 方法返回的 channel 被關閉,則意味著已經(jīng)超時,需要及時停止當前任務并返回。
    select {
    case result := <-ch:
        fmt.Println(result)
    case <-timerCtx.Done():
        fmt.Println("Request timed out")
    }
}

在這個例子中,我們使用 context.WithTimeout 創(chuàng)建一個帶有超時的 context 對象,設置超時時間為 5秒鐘。handleRequest來執(zhí)行對應的任務,將timeCtx傳遞給handleRequest,如果沒有在對應時間內(nèi)正常返回,此時任務會直接返回,不會無限期執(zhí)行下去。

在任務執(zhí)行過程中,通過select不斷檢查 ctx.Done() 方法的返回值,如果超時時間到了,ctx.Done() 的結(jié)果將變?yōu)橐粋€非 nil 的值,這時我們就可以在 select 語句中執(zhí)行超時處理的邏輯。

最后,在任務返回后,調(diào)用取消函數(shù) cancel(),釋放占用的資源。

從上面timer實現(xiàn)超時控制,或者是使用timerCtx的實現(xiàn)來看,其實二者區(qū)別并不大,但是事實上,現(xiàn)在任務的超時控制,基本上都是使用timerCtx實現(xiàn)的,并非使用timer來實現(xiàn)的,后續(xù)將會對其進行說明。

5. 總結(jié)

在這篇文章中,我們通過網(wǎng)絡請求這個常見的場景,描述其可能導致的問題,從而引出了請求的超時控制。同時,在Go語言中,可以同時通過timertimerCtx來實現(xiàn)超時控制,在這篇文章中,主要的內(nèi)容,便是簡單介紹了如何通過timertimerCtx來實現(xiàn)超時控制,希望對你有所幫助。

但是,在這篇文章中,并沒有介紹timerCtx或者timer的實現(xiàn)原理。同時,也暫未展示在哪些場景下,timerCtx實現(xiàn)超時控制相對于timer實現(xiàn)的優(yōu)點,或者在哪些場景下,timer相對于timerCtx在哪些場景下使用更為合適,這些內(nèi)容將會在后文進行描述。

到此這篇關于Go語言實現(xiàn)請求超時處理的方法總結(jié)的文章就介紹到這了,更多相關Go語言請求超時處理內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • 一文帶你深入理解Golang中的泛型

    一文帶你深入理解Golang中的泛型

    Go?在泛型方面一直被詬病,因為它在這方面相對比較落后。但是,在?Go?1.18?版本中,泛型已經(jīng)被正式引入,成為了?Go?語言中一個重要的特性。本文將會詳細介紹?Go?泛型的相關概念,語法和用法,希望能夠幫助大家更好地理解和應用這一特性
    2023-05-05
  • golang 各種排序大比拼實例

    golang 各種排序大比拼實例

    這篇文章主要介紹了golang 各種排序大比拼實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-12-12
  • Go語言利用ffmpeg轉(zhuǎn)hls實現(xiàn)簡單視頻直播

    Go語言利用ffmpeg轉(zhuǎn)hls實現(xiàn)簡單視頻直播

    這篇文章主要為大家介紹了Go語言利用ffmpeg轉(zhuǎn)hls實現(xiàn)簡單視頻直播,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-04-04
  • Golang logrus 日志包及日志切割的實現(xiàn)

    Golang logrus 日志包及日志切割的實現(xiàn)

    這篇文章主要介紹了Golang logrus 日志包及日志切割的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-02-02
  • go 熔斷原理分析與源碼解讀

    go 熔斷原理分析與源碼解讀

    這篇文章主要為大家介紹了go 熔斷原理分析與源碼解讀,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-08-08
  • golang RWMutex讀寫鎖實現(xiàn)讀共享寫獨占的功能示例

    golang RWMutex讀寫鎖實現(xiàn)讀共享寫獨占的功能示例

    在 Go 里除了互斥鎖外,還有讀寫鎖 RWMutex,它主要用來實現(xiàn)讀共享,寫獨占的功能,今天我們也順便分析下讀寫鎖,加深對 Go 鎖的理解
    2023-09-09
  • GoLang?Time時間操作函數(shù)講解

    GoLang?Time時間操作函數(shù)講解

    在日常開發(fā)中,我們避免不了時間的使用,我們可能需要獲取當前時間,然后格式化保存,也可能需要在時間類型與字符串類型之間相互轉(zhuǎn)換等。本文將會對?Go?time?包里面的常用函數(shù)和方法進行介紹,需要的可以參考一下
    2023-01-01
  • go中如何獲取本機ip地址

    go中如何獲取本機ip地址

    這篇文章主要介紹了go中如何獲取本機ip地址問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-09-09
  • 對Go語言中的context包源碼分析

    對Go語言中的context包源碼分析

    這篇文章主要對Go語言中的context包源碼進行分析,context包析是1.15,context包定義了一個Context類型過這個Context接口類型,?就可以跨api邊界/跨進程傳遞一些值,下面我們就來對context包源碼進行分析,需要的小伙伴可以參考一下
    2022-02-02
  • go語言題解LeetCode1122數(shù)組的相對排序

    go語言題解LeetCode1122數(shù)組的相對排序

    這篇文章主要為大家介紹了go語言題解LeetCode1122數(shù)組的相對排序,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-12-12

最新評論

安图县| 兴海县| 韶关市| 六枝特区| 长泰县| 茌平县| 水富县| 汉寿县| 泌阳县| 洮南市| 大庆市| 乐清市| 平安县| 山东省| 桦川县| 焉耆| 定结县| 瑞安市| 怀来县| 中方县| 白山市| 蒙山县| 宽甸| 双峰县| 兴海县| 响水县| 蒙自县| 麻阳| 余江县| 大埔区| 南召县| 彭阳县| 四平市| 华容县| 二连浩特市| 县级市| 忻州市| 扬中市| 永吉县| 林口县| 育儿|