求助,关于 http body 的传输

2022-08-25 10:01:15 +08:00
 hzjseasea

有一个场景是要把前一个请求 get 到的 body 原模原样的拿下来作为另外一个 post 请求的请求体,然后我就有一个疑问,对于小体积的 body 来说无所谓,哪怕是直接将 body copy 一份都没事,但是对于大体积的 body 来说,如果直接用第一种方式 copy 一份的话,那整个内容都会保存在内存里,高并发的环境下对于内存小的机器会不会直接撑爆了,然后我就想了下面两种方式,第二种用函数返回的方式我觉得也是存在内存里面的,用 pipe 的方式更像是流式的方式传输? 望指教

// 直接 copy 一份
func GetBody() ([]byte, error) {
	resp, err := http.Get("http://www.baidu.com")
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()
	body, _ := ioutil.ReadAll(resp.Body)
	return body, nil
}

func main() {
	body, _ := GetBody()
	// ... deal with body
	fmt.Println(body)

}
// 直接将 response body 抛出来
func GetBody() (io.ReadCloser, error) {
	resp, err := http.Get("http://www.baidu.com")
	if err != nil {
		return nil, err
	}
	return resp.Body, nil
}

func main() {
	body, err := GetBody()
	if err != nil {
		fmt.Println(err)
	}
	defer body.Close()

	// ... deal with body

}

// 通过 io.pipe 的方式传输
func PipeBody(w *io.PipeWriter) {
	resp, err := http.Get("http://www.baidu.com")
	if err != nil {
		log.Println(err)
	}
	defer resp.Body.Close()
	io.Copy(w, resp.Body)
}

func main() {
	reader, writer := io.Pipe()
	go func() {
		defer writer.Close()
		PipeBody(writer)
	}()

	// ... deal with body, for example
	body, _ := ioutil.ReadAll(reader)
	fmt.Println(string(body))
}
2833 次点击
所在节点    Go 编程语言
24 条回复
runningman
2022-08-25 15:51:23 +08:00
@sujin190 那应该使用 类似这种 https://gitee.com/no-src/gofs
hzjseasea
2022-08-25 15:59:02 +08:00
我去看了一下阿里的 oss 用的也是第二种方式
https://help.aliyun.com/document_detail/88617.html
sujin190
2022-08-25 16:31:51 +08:00
@hzjseasea #19 如果你 http.Get 会使用 DefaultClient ,DefaultClient 默认使用的 DefaultTransport 的默认缓冲区是 4k ,超过这个大小就不会读取到内存了,如果你需要定制,自己创建 Client 和 Transport 就可以把,resp.Body 本来就 Reader 类型之间可以放到下一个 post 请求方法里吧,如果你的下一个 post 请求还需要参数,那么如上面所说用 io.Pipe copy 就可以了,DefaultTransport 的写缓冲区也是 4k ,所以单个请求的最大内存就是 8k 了
Chinsung
2022-08-25 17:55:30 +08:00
前面的本质上已经都到内存了,这种得在比较底层实现网卡里的直接修改内容才能实现内存都不过吧,只有网卡缓冲区直接对拷,才能实现真正的极致性能,到了内存差不多的

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/875234

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX