【发布时间】:2021-08-09 20:40:05
【问题描述】:
我有一个应用程序正在读取大量请求(大约 4-5 百万个请求/秒)
我正在使用 json.decoder 从请求正文中读取传入的 json 数据。
我的代码:
err := json.NewDecoder(c.Request.Body).Decode(&obj)
上面的代码 sn -p 耗尽了请求体。有什么办法可以将其流式传输回来,以便在代码中再次读取它?
例如,在使用 io util 库时,我可以这样做:
c.Request.Body = ioutil.NopCloser(bytes.NewBuffer(bodyBytes))
我正在寻找的解决方案类似于:
err := json.NewDecoder(c.Request.Body).Decode(&obj)
if err != nil {
return err
}
b := new(bytes.Buffer)
c.Request.Body = json.NewEncoder(b).Encode(obj)
但显然不支持c.Request.Body = json.NewEncoder(b).Encode(obj)
我不能使用 ioutil 库,因为它很难管理冗长的请求。
【问题讨论】:
-
读取阅读器而不耗尽阅读器的唯一方法是缓冲其内容(通常在内存中或磁盘上)。
-
不过,您并没有真正很好地解释您的问题。您所说的您尝试过的三个“解决方案”没有明显的共同点。目前尚不清楚其中任何一个,更不用说所有这些,如何解决您的问题。你能更清楚地解释你的问题吗?
-
再次编组和编组总是比读入缓冲区慢,并设置一个读取器来生成缓冲区的内容。所以就这样做吧。见Golang read request body multiple times
-
however I see the response time increasing over time这在我心中敲响了关于 GC 的警钟。我想建议使用sync.Pool和io.CopyBuffer减少您的分配。但我也同意 Flimzy 的评论,你的帖子不够清晰。 -
@Flimzy 请检查一下,我已经简化了问题陈述