Home >Backend Development >Golang >golang http close connection
When using Golang for HTTP programming, we need to often consider how to close the connection. Closing connections can effectively avoid resource waste, improve performance, and reduce unnecessary trouble caused by network problems. This article will introduce in detail how to close HTTP connections in Golang and analyze some of the details.
1. How to close HTTP connections
The HTTP client and server in the Go language implement a series of underlying processes to manage HTTP connections. These low-level processing are usually not exposed to the user, but are hidden in the internal implementation by HTTP clients and servers. So how to close the connection in HTTP client and server?
In the HTTP client, we have several ways to close the connection:
package main import ( "net/http" "io/ioutil" "fmt" "log" ) func main() { client := &http.Client{} req, err := http.NewRequest("GET", "http://www.baidu.com", nil) if err != nil { log.Fatal(err) } defer client.CloseIdleConnections() // 当函数返回时释放连接 resp, err := client.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close() // 当函数返回时关闭body body, err := ioutil.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(string(body)[:50]) }
package main import ( "net/http" "io/ioutil" "fmt" "log" ) func main() { transport := &http.Transport{ MaxIdleConns: 10, // 最大空闲连接数 MaxIdleConnsPerHost: 3, // 每个域名地址最大空闲连接数 } client := &http.Client{Transport: transport} req, err := http.NewRequest("GET", "http://www.baidu.com", nil) if err != nil { log.Fatal(err) } resp, err := client.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(string(body)[:50]) }
In the HTTP server, connection management is usually automatically managed by the server. We just need to create the server and close it when the connection is no longer needed. Normally, the server automatically closes the connection after processing a request. But there are several special situations that require us to manually control the closing of the connection:
package main import ( "fmt" "net/http" ) func handler(w http.ResponseWriter, req *http.Request) { // 需要关闭连接时,使用conn.Close() conn, _, _ := w.(http.Hijacker).Hijack() conn.Close() } func main() { http.HandleFunc("/", handler) http.ListenAndServe(":8080", nil) }
package main import ( "log" "net/http" ) func handler(w http.ResponseWriter, req *http.Request) { w.Header().Set("Connection", "keep-alive") // 定义keep-alive时间 w.Write([]byte("hello world")) } func main() { http.HandleFunc("/", handler) log.Fatal(http.ListenAndServe(":8080", nil)) }
2. HTTP connection recycling mechanism
When the connection is used up, we need to recycle resources for the connection to prevent resource leakage, performance degradation and other problems. The recycling mechanism of HTTP connection resources usually needs to consider the following issues:
3. Management of HTTP connection pool
In large-scale and highly concurrent systems, we need to use connection pools to manage HTTP connections to improve system performance and stability. When calling an HTTP request, the connection pool can provide an idle network connection to avoid the overhead of frequently creating and destroying connections. Connection pools are usually managed using regular queues to ensure that the elements that enter the queue first are used first, that is, a FIFO queue. The following is the code to implement HTTP connection pool using Go language:
package main import ( "fmt" "log" "net/http" "sync" "time" ) type MyHttpClient struct { client *http.Client // http客户端对象 Transport *http.Transport // transport对象,用于管理http连接池 } var once sync.Once var myClient *MyHttpClient func GetMyHttpClient() *MyHttpClient { once.Do(func() { myClient = &MyHttpClient{ Transport: &http.Transport{ Dial: func(network, addr string) (net.Conn, error) { conn, err := net.DialTimeout(network, addr, 10*time.Second) if err != nil { return nil, err } return conn, nil }, MaxIdleConns: 100, // 连接池中最多拥有的连接数 MaxIdleConnsPerHost: 2, // 每个域名最多拥有的连接数 IdleConnTimeout: 60 * time.Second, // 连接在闲置多久后被关闭 TLSHandshakeTimeout: 10 * time.Second, // TLS握手时限 ExpectContinueTimeout: 1 * time.Second, // 100-continue超时时限 }, client: &http.Client{}, } }) return myClient } func main() { client := GetMyHttpClient().client req, err := http.NewRequest("GET", "http://www.baidu.com", nil) if err != nil { log.Fatal(err) } defer client.CloseIdleConnections() resp, err := client.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(string(body)[:50]) }
4. Summary
The control and recycling of HTTP connections is a key performance optimization point. In Golang, we can manage HTTP connections through manual control, parameter settings using the Transport class, and connection pooling to improve system performance and stability. In addition, we also need to consider issues such as the connection recycling mechanism and HTTP connection pool management, and maintain and optimize the system.
The above is the detailed content of golang http close connection. For more information, please follow other related articles on the PHP Chinese website!