Created
February 16, 2025 05:55
-
-
Save feiskyer/8191cc90a0cb41aadd384498981101e4 to your computer and use it in GitHub Desktop.
Revisions
-
feiskyer created this gist
Feb 16, 2025 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,92 @@ package main /* * Existing TCP timeout: * 1) Set http.Client.Timeout to 1m: 1m * 2) Set http2.ReadIdleTimeout=30s, http2.PingTimeout=15s, http.Client.Timeout=1m: 45s * 3) Without both: 15m * * New TCP timeout: 30s (per dialer setting) * * Notes: * http2.ReadIdleTimeout - The interval of health check for idle connections. * http2.PingTimeout - The timeout for server to respond to a client ping. * http.Client.Timeout - The timeout includes connection time, any redirects, and reading the response body. */ import ( "crypto/tls" "fmt" "io" "net" "net/http" "time" "golang.org/x/net/http2" ) func doRequest(client *http.Client, url string) { startTime := time.Now() req, err := http.NewRequest("GET", url, nil) if err != nil { fmt.Printf("HTTP NewRequest failed with duration: %v, error: %v\n", time.Since(startTime), err) return } rsp, err := client.Do(req) if err != nil { fmt.Printf("HTTP Client Do request failed with duration: %v, error: %v\n", time.Since(startTime), err) return } buf, err := io.ReadAll(rsp.Body) if err != nil { fmt.Printf("HTTP read body failed with duration: %v, error: %v\n", time.Since(startTime), err) return } defer rsp.Body.Close() fmt.Printf("HTTP succeed with duration: %v, resp: %s\n", time.Since(startTime), string(buf)[:15]) } func main() { tr := &http.Transport{ Proxy: http.ProxyFromEnvironment, ForceAttemptHTTP2: false, // default is true MaxIdleConns: 64, // default is 100 MaxIdleConnsPerHost: 64, // default is 2 IdleConnTimeout: 90 * time.Second, // same as default TLSHandshakeTimeout: 10 * time.Second, // same as default ExpectContinueTimeout: 1 * time.Second, // same as default DialContext: (&net.Dialer{ Timeout: 30 * time.Second, KeepAlive: 30 * time.Second, }).DialContext, TLSClientConfig: &tls.Config{ InsecureSkipVerify: true, MinVersion: tls.VersionTLS12, Renegotiation: tls.RenegotiateNever, }, } t2, err := http2.ConfigureTransports(tr) if err != nil { fmt.Printf("time: %v, http2 ConfigureTransports failed: %v\n", time.Now(), err) return } // ReadIdleTimeout configures the interval of health check for idle connections. // If the connection is idle for this duration, the client will send a ping to the server. t2.ReadIdleTimeout = 30 * time.Second // PingTimeout configures the timeout for server to respond to a client ping. // Response exceeding this timeout will cause the connection to be closed. t2.PingTimeout = 15 * time.Second client := &http.Client{ Transport: tr, Timeout: time.Minute, } for i := 0; i < 500; i++ { doRequest(client, "https://www.google.com") } }