Home  >  Article  >  Backend Development  >  golang http close connection

golang http close connection

WBOY
WBOYOriginal
2023-05-13 10:03:361577browse

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?

  1. HTTP client

In the HTTP client, we have several ways to close the connection:

  • Use the defer keyword to Manually close the connection: After the client calls the interface, the connection will generally be closed automatically. However, if the current client needs to request the interface multiple times, you can consider manually controlling the connection closing and using defer to delay closing the connection. The code is as follows:
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])
}
  • Use MaxIdleConns or MaxIdleConnsPerHost of the Transport class to control the connection The upper limit of connections in the pool: http.Transport of Go language contains a default connection pool for managing HTTP connections. We can use its two parameters MaxIdleConns and MaxIdleConnsPerHost to specify the maximum number of idle connections and the maximum number of idle host connections. When this idle number is reached, Transport will automatically close excess connections. The code is as follows:
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])
}
  1. HTTP server

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:

  • Use conn.Close() in an HTTP processor to close the connection: When the processor processes the HTTP request, if If the server needs to close the connection, it can use the conn.Close() method to close the connection. The code is as follows:
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)
}
  • Using Keep-Alive: When using Keep-Alive, the life cycle of the connection is managed by the server. The server can define a keep-alive time to control how long the connection should be closed after being idle. This time is usually set in the HTTP header. The code is as follows:
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:

  • Maximum lifetime of HTTP long connections: After the connection has been idle for a period of time, the server will immediately recycle the connection. This time can be determined by the server. Just set the connection timeout when creating the server object.
  • Maximum number of HTTP connections: The maximum number of connections allowed in the connection pool within a period of time. When the connection pool exceeds the connection pool size, they will be automatically closed.
  • HTTP connection reuse mechanism: Connection reuse means multiple requests share a connection at the same time. This can reduce unnecessary resource usage during long waiting states. However, it should be noted that if the connection timeout is short, it may cause a request with transient network fluctuations to fail, thus affecting the stability of the system.

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!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn