You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

GoLang net/http持续请求时内存占用异常增长问题

问题原因及解决办法

一、核心问题分析

1. 错误处理逻辑错误

在sendRequest函数中,当client.Do(req)返回错误时,resp大概率为nil,此时执行defer resp.Body.Close()会直接触发空指针panic,且该defer语句的位置完全错误——defer应在成功获取resp后立即声明,而非放在错误分支中。

2. 内存持续增长的根源

复用http.Client的思路是正确的,但默认的http.Transport配置会导致连接池内的空闲连接无法及时回收:

  • 默认IdleConnTimeout为0,意味着空闲连接会永久留存于连接池,循环请求会不断积累空闲连接,占用内存。
  • 默认MaxIdleConns和MaxIdleConnsPerHost值较高,进一步加剧了空闲连接的留存规模。

二、修复方案

  1. 修正错误处理逻辑:将defer resp.Body.Close()移至client.Do(req)成功之后,确保仅在resp非空时执行关闭操作,同时移除错误分支内的无效defer。
  2. 优化http.Transport配置:添加空闲连接超时、限制连接池大小,让闲置连接能被自动回收。
  3. (可选)替换已废弃API:Go 1.16及以后版本推荐使用io.ReadAll替代ioutil.ReadAll。

三、修复后的完整代码

package main

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

func httpClient() *http.Client {
	transport := &http.Transport{
		DisableKeepAlives: false,
		// 设置空闲连接超时,超时后自动关闭闲置连接
		IdleConnTimeout: 30 * time.Second,
		// 限制全局最大空闲连接数
		MaxIdleConns: 10,
		// 限制每个主机的最大空闲连接数
		MaxIdleConnsPerHost: 5,
	}
	client := &http.Client{Timeout: 60 * time.Second, Transport: transport}
	return client
}

func sendRequest(client *http.Client, method string) []byte {
	endpoint := "https://httpbin.org/post"
	values := map[string]string{"foo": "baz"}
	jsonData, err := json.Marshal(values)
	if err != nil {
		log.Fatalf("JSON序列化失败: %+v", err)
	}

	req, err := http.NewRequest(method, endpoint, bytes.NewBuffer(jsonData))
	if err != nil {
		log.Fatalf("创建请求失败: %+v", err)
	}

	resp, err := client.Do(req)
	if err != nil {
		log.Fatalf("发送请求失败: %+v", err)
	}
	// 成功获取响应后立即声明defer,确保后续逻辑无论如何都会关闭响应体
	defer resp.Body.Close()

	body, err := io.ReadAll(resp.Body)
	if err != nil {
		log.Fatalf("读取响应体失败: %+v", err)
	}
	return body
}

func main() {
	c := httpClient()
	for i := 1; i <= 60; i++ {
		response := sendRequest(c, http.MethodPost)
		log.Println("响应内容:", string(response))
		response = nil
		time.Sleep(time.Second * 1)
	}
}

四、额外说明

  • 调整IdleConnTimeout、MaxIdleConns等值时,可根据实际请求频率灵活配置,平衡连接复用效率与内存占用。
  • 若程序需长期运行,可借助Go的pprof工具做内存分析,确认内存占用问题是否完全解决。

内容的提问来源于stack exchange,提问作者Ahsan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 18:05:29