nginx + django + uwsgi + python2.7 如何排查内存泄露.

2019-03-11 11:29:58 +08:00
 cs8814336
背景:
该项目功能比较多, 而且在不同机房部署了多个实例, 但是只有其中一个机房的使用出现了明显的内存泄露(因为功能比较多,不同机房用的功能或者着重用的功能不一样). 发现问题是通过访问出现了 500,然后上服务器 top 发现了 uwsgi 多个进程占用比较大的内存,最大一个占用了 20% (8g 内存), 累积起来用满了内存和交换空间.


求助: 如何有一种比较通用的内存泄露排查方法来定位到源码行.

优先不考虑通过修改源码重启后收集内存对象的方法.(什么 objgraph 工具之类) 因为这种感觉不太适用于其他语言, 而且需要重启破坏掉现场,需要等待下次触发.

已经有的思路:

想通过查看具体分配堆地址看具体内容, 猜测是哪部分的功能.但是还在踩坑中.
通过 gdb --pid [pid] attach 进程, 然后 shell pmap [pid] 查看分配内存,定位到一个 anno 的比较大的内存,然后
x/big number address 来取得内存地址内容

感觉大家的回答.
4398 次点击
所在节点    Python
12 条回复
aikuzhenyan
2019-03-11 11:54:48 +08:00
建议上 gunicorn
cs8814336
2019-03-11 12:02:13 +08:00
@aikuzhenyan 恩,早有所闻,但是这个问题的话恐怕上什么应该也会重现的, 所以想要一个通用的方法来排查以后和现在的这种类似的内存泄露问题
qqxx520
2019-03-11 12:20:08 +08:00
uwsgi 有个参数,处理完一定数量的请求之后就重启一次
cs8814336
2019-03-11 12:49:02 +08:00
@qqxx520 感谢回答. 恩,我知道的, 假如是 uwsgi 的问题, 当然这个是完美解决的. 恐怕大几率是代码问题, 这样的话我更倾向于从根本上解决问题而不是临时解决.
jingxyy
2019-03-11 13:29:46 +08:00
查完了分享一下内存泄露的原因呗~
Ehco1996
2019-03-11 14:26:31 +08:00
看一下依赖,是不是用了什么 c 库,一般都是这个原因
chenqh
2019-03-11 18:29:28 +08:00
这个时间就有点羡慕 golang 的 go tool 了,python 里面就没有类似的吗?
mathgl
2019-03-11 19:29:05 +08:00
可以在 twisted 下部署测试
cs8814336
2019-03-20 11:19:11 +08:00
时隔多天之后, 再次搜索这个问题, 发现一个很好的工具 pyrasite.

能生成 payload 监听一个随机端口, 然后通过远程线程注入代码的方式注入到该进程让进程执行然后连接到这个随机端口,接下来可以像 python cmd 互动式操作. (就是一个黑客里面的反向 shell)

安装后使用过程有一点曲折, 但是躺过了没啥问题, 接下来可以用 objgraph 等库进行远程注入. 然后发现只能看到某个类型的占用的最大, 具体到定位到源码行还有一定的差距. 现在还在查实
cs8814336
2019-03-20 14:21:38 +08:00
@Ehco1996 里面没有自己写的 c 库
cs8814336
2019-12-26 15:47:39 +08:00
已解决
cs8814336
2019-12-27 10:33:25 +08:00
总结文章,大家有兴趣可以看下 https://blog.csdn.net/u012087220/article/details/103716134

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

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

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

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

© 2021 V2EX