golang timeoutHandler解析及kubernetes中的变种 (3)

谈完TimeoutHandler, 再回到golang timeout,有时虽然我们正常timeout返回, 但并不意味整个groutine就正常返回了。此时调用返回也只是上层返回了, 异步调用的底层逻辑没有办法撤回的。 因为我们没办法cancel掉另一个grouine,只能是groutine主动退出, 主动退出的实现思路大部分是通过传递一个context或者close channel给该groutine, 该groutine监听到退出信号就终止, 但是目前很多调用是不支持接收一个context或close channle作为参数的。
例如下面这段代码:因为在主逻辑中sleep了4s是没有办法中断的, 即时此时request已经返回,但是server端该groutine还是没有被释放, 所以golang timeout这块还是非常容易leak grouine的, 使用的时候需要小心。

package main import ( "fmt" "net/http" "runtime" "time" ) func main() { go func() { for { time.Sleep(time.Second) fmt.Printf("groutine num: %d\n", runtime.NumGoroutine()) } }() handleFunc := func(w http.ResponseWriter, r *http.Request) { fmt.Printf("request %v\n", r.URL) time.Sleep(4 * time.Second) _, err := fmt.Fprintln(w, "ok") if err != nil { fmt.Printf("write err: %v\n", err) } } err := http.ListenAndServe("localhost:9999", http.TimeoutHandler(http.HandlerFunc(handleFunc), 2*time.Second, "err: timeout")) if err != nil { fmt.Printf("%v", err) } } 写在最后

golang timeout 简单但是比较繁琐,只有明白其原理才能真正防患于未然

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpdzdf.html