优雅的读取http请求或响应的数据
副标题[/!--empirenews.page--]
从 http.Request.Body 或 http.Response.Body 中读取数据方法或许很多,标准库中大多数使用 ioutil.ReadAll 方法一次读取所有数据,如果是 json 格式的数据还可以使用 json.NewDecoder 从 io.Reader 创建一个解析器,假使使用 pprof 来分析程序总是会发现 bytes.makeSlice 分配了大量内存,且总是排行第一,,今天就这个问题来说一下如何高效优雅的读取 http 中的数据。 背景介绍 我们有许多 api 服务,全部采用 json 数据格式,请求体就是整个 json 字符串,当一个请求到服务端会经过一些业务处理,然后再请求后面更多的服务,所有的服务之间都用 http 协议来通信(啊, 为啥不用 RPC,因为所有的服务都会对第三方开放,http + json 更好对接),大多数请求数据大小在 1K~4K,响应的数据在 1K~8K,早期所有的服务都使用 ioutil.ReadAll 来读取数据,随着流量增加使用 pprof 来分析发现 bytes.makeSlice 总是排在第一,并且占用了整个程序 1/10 的内存分配,我决定针对这个问题进行优化,下面是整个优化过程的记录。 pprof 分析 这里使用 https://github.com/thinkeridea/go-extend/blob/master/exnet/exhttp/expprof/pprof.go 中的 API 来实现生产环境的 /debug/pprof 监测接口,没有使用标准库的 net/http/pprof 包因为会自动注册路由,且长期开放 API,这个包可以设定 API 是否开放,并在规定时间后自动关闭接口,避免存在工具嗅探。 服务部署上线稳定后(大约过了一天半),通过 curl 下载 allocs 数据,然后使用下面的命令查看分析。
从结果中可以看出采集期间一共分配了 1358.61GB top 10 占用了 44.50% 其中 bytes.makeSlice 占了接近 1/10,那么看看都是谁在调用 bytes.makeSlice 吧。
从上图可以看出调用 bytes.makeSlice 的最终方法是 ioutil.ReadAll, (受篇幅影响就没有截取 ioutil.ReadAll 上面的方法了),而 90% 都是 ioutil.ReadAll 读取 http 数据调用,找到地方先别急想优化方案,先看看为啥 ioutil.ReadAll 会导致这么多内存分配。
(编辑:青岛站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- 5G发牌一周年:行业应用加速融合 超高清、VR/AR将率先爆发
- Oculus Quest获得“原型版本”级别的OpenXR支持
- office2019专业增强版怎么激活 教你免费运用它
- 从7600万个5G连接中,我们发现了7种最有前景的5G物联网应用
- Pico针对海外市场发布企业版VR一体机Pico Neo 2、Pico Neo
- VR进入北京城市副中心建筑工地 施工人员实景体验增强安全意
- 一文讲弄懂什么是vlan、三层交换机、网关、DNS、子网掩码、
- VR游戏《SWORDS of GARGANTUA Tesaract Abyss》将于4月登陆
- 丹麦VR内容厂商MeetinVR发布VR协作平台MeetinVR公测版
- 关于边缘计算,你可以了解的更多一点