以下代码是使用 net/http 包实现的 Http 连接池,完整代码在最后


文章目录

  • 创建连接池
  • 初始化连接池属性
  • 创建并初始化连接池
  • 结构体
  • GET方法
  • POST方法
  • 完整代码
  • 测试


创建连接池

初始化连接池属性

golang 调用docker sdk 获取docker swarm 服务id 并根据服务id重启_连接池


常用属性说明:

属性

说明

Dial

(已弃用)提供用于创建未加密的TCP连接的方法

DialContext

提供用于创建未加密的TCP连接的方法,若DialContext和Dial都未设置默认使用net包下的dial函数

DialTLS

(已弃用)提供用于创建非代理HTTPS的TLS请求的方法

DialTLSContext

提供用于创建非代理HTTPS的TLS请求的方法

设置之后,HTTPS请求将不使用 DialContext 和 Dial 的相关配置

若 DialTLSContext 和 DialTLS 都未设置,默认使用 DialContext 和 TLSClientConfig 的配置

TLSClientConfig

指定要与一起使用的TLS配置

TLSHandshakeTimeout

TLS连接握手超时时长

DisableKeepAlives

如果设置为 true 表示一个连接只能让一个请求使用,不能重用

DisableCompression

如果设置为 true 则阻止传输使用“Accept Encoding:gzip”请求压缩

MaxIdleConns

所有host允许的最大空闲连接数

MaxIdleConnsPerHost

单个host允许的最大空闲连接数,如果设置为 0 则使用默认值 2

MaxConnsPerHost

单个host允许的最大连接数,设置 0 则表示无限制

IdleConnTimeout

连接存活时长,设置 0 表示无限制

ResponseHeaderTimeout

响应头接收超时时长,不包含响应体

MaxResponseHeaderBytes

响应头内容长度最大限制,设置 0 使用默认限制

WriteBufferSize

指定写入传输时使用的写入缓冲区的大小,设置 0 默认 4KB

ReadBufferSize

指定从传输中读取时使用的读取缓冲区的大小,设置 0 默认 4KB

ForceAttemptHTTP2

true 使用HTTP2(前提是配置了 Dial 或 DialTLS 或 DialContext 方法 或提供了 TLSClientConfig 配置)

创建并初始化连接池

golang 调用docker sdk 获取docker swarm 服务id 并根据服务id重启_连接池_02

结构体

大部分下情况下,我们请求的接口都需要带有各种请求头信息,例如Cookie。

将请求头信息存放在结构体实例中,后续这个实例发起的请求都将带有同样的请求头信息。

golang 调用docker sdk 获取docker swarm 服务id 并根据服务id重启_golang_03

GET方法

如果不需要任何请求头信息,我们可以直接使用 httpClient.Get 去请求接口

golang 调用docker sdk 获取docker swarm 服务id 并根据服务id重启_初始化_04


如果我们要设置请求头信息,要先使用 http.NewRequest 声明一个请求,塞入 Header 数据并最后由 httpClient 执行

golang 调用docker sdk 获取docker swarm 服务id 并根据服务id重启_http_05


接收到响应后,处理结果是我们要记得及时关闭响应流

golang 调用docker sdk 获取docker swarm 服务id 并根据服务id重启_连接池_06

POST方法

与Get方法相差无几,我们在POST请求中通常会传递请求体。对于请求体的处理如下:

golang 调用docker sdk 获取docker swarm 服务id 并根据服务id重启_golang_07

完整代码

package cus_http

import (
	"bytes"
	"encoding/json"
	"io/ioutil"
	"net"
	"net/http"
	"time"
)

// 初始化连接池配置
var httpTrans = &http.Transport{
	DialContext: (&net.Dialer{
		Timeout:   30 * time.Second,
		KeepAlive: 30 * time.Second,
	}).DialContext,
	ForceAttemptHTTP2:     true,
	MaxIdleConns:          100,                                     //所有Host的连接池最大空闲连接数
	MaxIdleConnsPerHost:   2,                                       //每个Host的连接池最大空闲连接数
	MaxConnsPerHost:       4,                                       //每个Host的连接池最大连接数
	IdleConnTimeout:       time.Duration(90000) * time.Millisecond, //空闲连接保留时间
	TLSHandshakeTimeout:   10 * time.Second,
	ExpectContinueTimeout: 1 * time.Second,
}

// 初始化连接池
var httpClient = &http.Client{
	Timeout:   30 * time.Second,
	Transport: httpTrans,
}

type CusHttp struct {
	Header map[string]string
}

// 发送GET请求
// url:         请求地址
func (cus *CusHttp) Get(url string) string {

	// resp, err := httpClient.Get(url)

	//初始化请求
	reqest, err := http.NewRequest("GET", url, nil)

	//增加Header选项
	if cus.Header != nil && len(cus.Header) > 0 {
		for k, vla := range cus.Header {
			reqest.Header.Add(k, vla)
		}
	}

	if err != nil {
		panic(err)
	}

	resp, err := httpClient.Do(reqest)

	if err != nil {
		panic(err)
	}
	defer resp.Body.Close()

	result, _ := ioutil.ReadAll(resp.Body)
	return string(result)
}

// 发送POST请求 默认使用
// url:         请求地址
// data:        POST请求提交的数据
func (cus *CusHttp) Post(url string, data interface{}) string {
	return cus.post(url, data)
}

// 发送POST 表单
// url:         请求地址
// data:        POST请求提交的数据
func (cus *CusHttp) PostForm(url string, data interface{}) string {
	cus.Header["Content-Type"] = "application/x-www-form-urlencoded"
	return cus.post(url, data)
}

// 发送POST请求
// url:         请求地址
// data:        POST请求提交的数据
func (cus *CusHttp) post(url string, data interface{}) string {

	jsonStr, _ := json.Marshal(data)
	//初始化请求
	reqest, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonStr))
	//增加Header选项
	if cus.Header != nil && len(cus.Header) > 0 {
		for k, vla := range cus.Header {
			reqest.Header.Add(k, vla)
		}
	}

	if err != nil {
		panic(err)
	}

	resp, err := httpClient.Do(reqest)
	if err != nil {
		panic(err)
	}

	defer resp.Body.Close()

	result, _ := ioutil.ReadAll(resp.Body)
	return string(result)
}

测试

golang 调用docker sdk 获取docker swarm 服务id 并根据服务id重启_连接池_08


结果

golang 调用docker sdk 获取docker swarm 服务id 并根据服务id重启_http_09