Go语言中如何分块复制请求体至io.Discard并在每次读取后短暂休眠
Go语言中如何分块复制请求体至io.Discard并在每次读取后短暂休眠
嘿,刚接触Go的话这种模拟延迟的小需求确实得琢磨琢磨细节~我来给你一步步拆解怎么实现这个逻辑:
核心思路就是用循环调用io.CopyN,每次读取固定大小的块到io.Discard,读完一块就短暂休眠,直到请求体被完全读取或者出现错误。给你写个完整的HTTP Handler示例,直接就能用:
import ( "io" "net/http" "time" ) func mockDelayHandler(w http.ResponseWriter, r *http.Request) { // 务必记得关闭请求体,避免资源泄漏,这是Go处理HTTP请求的最佳实践 defer r.Body.Close() chunkSize := int64(10) // 你想要的每块大小,这里设为10字节 sleepDuration := 100 * time.Millisecond // 每次读取后的休眠时间,可按需调整 for { // 分块复制请求体内容到Discard readBytes, err := io.CopyN(io.Discard, r.Body, chunkSize) if err != nil { if err == io.EOF { // 已经读完所有请求体,正常退出循环 break } // 读取过程中出现异常,返回500错误 w.WriteHeader(http.StatusInternalServerError) return } // 只有当实际读到数据时才休眠,避免无意义的等待 if readBytes > 0 { time.Sleep(sleepDuration) } } // 处理完成后返回成功状态码 w.WriteHeader(http.StatusOK) }
这里有几个关键细节要注意:
- 必须用
defer r.Body.Close()关闭请求体:不管读取是否成功,都要释放HTTP连接相关的资源,不然会导致连接池资源泄漏 - 每次循环后检查错误:只有
io.EOF是正常的结束信号,其他错误都要返回500状态码 - 判断
readBytes > 0再休眠:避免最后一次循环可能没读到数据却还执行休眠的情况 - 你可以自由调整
chunkSize和sleepDuration的值,来匹配你想要的延迟效果
这样调整后,你的mock接口就能完美模拟出分块处理请求体的延迟场景啦~
内容来源于stack exchange




