天天看點

golang http timeout說明

Server Timeouts

golang http timeout說明

http server有兩個時間選項可設定

srv := &http.Server{
    ReadTimeout: 5 * time.Second,
    WriteTimeout: 10 * time.Second,
}
log.Println(srv.ListenAndServe())
           

圖中的http.TimeoutHandler不般不控制時間, 是項目handler層開始到輸出結果的時間。

Client Timeouts

golang http timeout說明

設定 http.Client.Timeout

c := &http.Client{
    Timeout: 15 * time.Second,
}
resp, err := c.Get("https://xxx/")
           

設定net.Dialer.Timeout 和 http.Transport Timeout

c := &http.Client{
    Transport: &http.Transport{
        Dial: (&net.Dialer{
                Timeout:   30 * time.Second,
                KeepAlive: 30 * time.Second,
        }).Dial,
        TLSHandshakeTimeout:   10 * time.Second,
        ResponseHeaderTimeout: 10 * time.Second,
        ExpectContinueTimeout: 1 * time.Second,
    }
}

           

每個request 獨立設定Timeout

ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
defer cancel()
req, err := http.NewRequestWithContext(ctx, "GET", URL, nil)
           

重新整理Timeout,不斷延後Timeout的控制方法

package main

import (
	"io"
	"io/ioutil"
	"log"
	"net/http"
	"time"
)

func main() {
	c := make(chan struct{})
	timer := time.AfterFunc(5*time.Second, func() {
		close(c)
	})

        // Serve 256 bytes every second.
	req, err := http.NewRequest("GET", "http://httpbin.org/range/2048?duration=8&chunk_size=256", nil)
	if err != nil {
		log.Fatal(err)
	}
	req.Cancel = c

	log.Println("Sending request...")
	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		log.Fatal(err)
	}
	defer resp.Body.Close()

	log.Println("Reading body...")
	for {
		timer.Reset(2 * time.Second)
                // Try instead: timer.Reset(50 * time.Millisecond)
		_, err = io.CopyN(ioutil.Discard, resp.Body, 256)
		if err == io.EOF {
			break
		} else if err != nil {
			log.Fatal(err)
		}
	}
}
           

原文連接配接

有興趣可以讀一下原文, 内容要詳細很多。 本文中是摘錄了 圖檔,做簡單的說明。

The complete guide to Go net/http timeouts

https://blog.cloudflare.com/the-complete-guide-to-golang-net-http-timeouts/

繼續閱讀