簡體   English   中英

(goroutine 泄漏) http.TimeoutHandler 不會殺死相應的 ServeHTTP goroutine

[英](goroutine leaks) http.TimeoutHandler does not kill respective ServeHTTP goroutine

超時處理程序在新的 goroutine 上移動 ServeHTTP 執行,但不能在計時器結束后終止該 goroutine。 對於每個請求,它都會創建兩個 goroutines,但 ServeHTTP goroutines 永遠不會被上下文殺死。

無法找到殺死 goroutines 的方法。

使用 time.Sleep 函數編輯For 循環,代表超出我們計時器的巨大計算。 可以用任何其他功能代替它。

package main

import (
    "fmt"
    "io"
    "net/http"
    "runtime"
    "time"
)

type api struct{}

func (a api) ServeHTTP(w http.ResponseWriter, req *http.Request) {
    // For-loop block represents huge computation and usually takes more time
    // Can replace with any code
    i := 0
    for {
        if i == 500 {
            break
        }
        fmt.Printf("#goroutines: %d\n", runtime.NumGoroutine())
        time.Sleep(1 * time.Second)
        i++
    }
    _, _ = io.WriteString(w, "Hello World!")
}

func main() {
    var a api
    s := http.NewServeMux()
    s.Handle("/", a)
    h := http.TimeoutHandler(s, 1*time.Second, `Timeout`)

    fmt.Printf("#goroutines: %d\n", runtime.NumGoroutine())

    _ = http.ListenAndServe(":8080", h)
}

ServeHTTP goroutine 應該與請求上下文一起終止,通常不會發生。

使用context.Context指示 go-routines 中止它們的功能。 當然,go-routines 必須監聽這樣的取消事件。

因此,對於您的代碼,請執行以下操作:

ctx := req.Context() // this will be implicitly canceled by your TimeoutHandler after 1s

i := 0
for {
    if i == 500 {
        break
    }

    // for any long wait (1s etc.) always check the state of your context
    select {
    case <-time.After(1 * time.Second): // no cancelation, so keep going
    case <-ctx.Done():
        fmt.Println("request context has been canceled:", ctx.Err())
        return // terminates go-routine
    }
    i++
}

游樂場: https : //play.golang.org/p/VEnW0vsItXm


注意: Context被設計為鏈接的——允許以級聯方式取消多個級別的子任務。

在典型的 REST 調用中,會發起一個數據庫請求。 因此,為了確保及時完成這種阻塞和/或慢速調用,而不是使用Query應該使用QueryContext - 將 http 請求的上下文作為第一個參數傳遞。

我發現,如果您無法訪問您的頻道,則無法在運行時殺死或停止 goroutine。

在大型計算任務中,您必須在特定時間間隔或特定任務完成后觀看頻道。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM