痴情的电池 · london grammar_百度百科· 3 周前 · |
逆袭的大象 · 地级市人口变局:嘉兴2021年常住人口增量排 ...· 3 月前 · |
眉毛粗的油条 · 威风的bgm_威风的近义词_威风的拼音 - 抖音· 1 年前 · |
苦闷的生姜 · 陈睿(bilibili董事长兼CEO)_百度百科· 1 年前 · |
大方的椅子 · 《刀剑神域进击篇:无星之夜的咏叹调》高清电影 ...· 1 年前 · |
我曾经开发过的几个大型Django应用程序都在某个时候出现了内存泄漏。Python进程缓慢地增加它们的内存消耗,直到崩溃。这一点也不好玩。即使自动重新启动进程之后,仍然会有一些宕机问题。
Python中的内存泄漏通常发生在无限增长的模块级变量中。这可能是一个具有无穷大maxsize的lru_cache变量,也可能是一个在错误范围内声明的简单列表。
泄漏也不是只有发生在您自己的代码中才会影响您。例如,看看BuzzFeed的Peter Karp写的这篇优秀的文章,他在Python的标准库中发现了一个内存泄漏(已经修复了!)
解决方法
下面的解决方法都会在执行了很多请求或任务之后重新启动worker进程。这是一个清除任何潜在的无限积累的Python对象的简单方法。如果您的web服务器、队列worker或类似的应用程序有此能力,但还没有被功能化,请告诉我,我会添加它!
即使您现在还没有看到任何内存泄漏,添加这些解决方法也会提高您的应用程序的弹性。
Gunicorn
如果您正在使用Gunicorn作为您的Python web服务器,您可以使用--max-requests设置来定期重启worker。与它的兄弟--max-requests-jitter配合使用以防止所有worker同时重启。这有助于减少worker的启动负载。
例如,在最近的一个项目中,我将Gunicorn配置为:
对于此项目的流量水平、worker数量和服务器数量来说,这将大约每1.5小时重新启动worker。5%的浮动足以消除重启负载的相关性。
Uwsgi
如果您正在使用uwsgi,您可以使用它类似的max-requests设置。此设置在很多次请求之后,也会重新启动worker。
例如,在以前的一个项目中,我在uwsgi.ini文件中像这样使用了这个设置:
Uwsgi还提供了max-requests-delta选项用于添加其他浮动。但由于它是一个绝对数字,所以配置起来要比Gunicorn更麻烦。如果您更改了worker的数量或max-requests的值,那您就需要重新计算max-requests-delta来保持您的浮动在一个特定的百分比。
Celery
Celery为内存泄漏提供了几个不同的设置。
首先是worker_max_tasks_per_child设置。这将在worker子进程处理了许多任务之后重新启动它们。此设置没有浮动选项,但是Celery任务的运行时间范围很广,所以会有一些自然的浮动。
例如:
或者您正在使用Django设置:
100个任务比我上面建议的web请求数要小一些。在过去,我最终为Celery使用了较小的值,因为我在后台任务中看到了更多的内存消耗。(我想我还在Celery本身中遇到了内存泄漏。)
您可以使用的另一个设置是worker_max_memory_per_child。这指定子进程在父进程替换它之前可以使用的最大千字节内存。它有点复杂,所以我还没用过。
如果您确实使用了worker_max_memory_per_child设置,那么您可能应该将其计算为总内存的百分比,并除以每个子进程。这样,如果您更改了子进程的数量或您的服务器的可用内存,它将会自动扩展。例如(未测试):
这使用psutil来查找整个系统内存。它将最多75%(0.75)的内存分配给Celery,只有在服务器是一个专用Celery服务器的情况下您才会需要它。
跟踪泄漏
在Python中调试内存泄漏是很不容易的,因为任何函数都可以在任何模块中分配全局对象。它们也可能出现在与C API集成的扩展代码中。
我用过的一些工具:
标准库模块tracemalloc.
objgraph和guppy3包都是在tracemalloc之前完成的,并尝试做类似的事情。它们都不太友好,但我以前成功地使用过它们。
Scout APM用CPython的内存分配计数来检测每个“span”(请求、SQL查询、模板标签,等等)。少数APM解决方案能做到这一点。提示:我维护着Python集成。
更新 (2019-09-19): Riccardo Magliocchetti在Twitter上提到,pyuwsgimemhog项目可以解析uwsgi日志文件,并告诉您哪些路径正在泄漏内存。很简洁!
其他一些有用的博文:
Buzzfeed Tech撰写了一篇《如何在生产Python web服务上使用tracemalloc的指南》。
Fugue的文章也使用了tracemalloc。
在Benoit Bernard的“古怪的Python内存泄漏”帖子中,他使用各种工具来跟踪C层面的泄漏。
结束语
祝您内存泄漏更少!
—Adam
英文原文:https://adamj.eu/tech/2019/09/19/working-around-memory-leaks-in-your-django-app/
译者:野生大熊猫
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2023 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号: 粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
扫码关注腾讯云开发者
领取腾讯云代金券
痴情的电池 · london grammar_百度百科 3 周前 |
眉毛粗的油条 · 威风的bgm_威风的近义词_威风的拼音 - 抖音 1 年前 |
苦闷的生姜 · 陈睿(bilibili董事长兼CEO)_百度百科 1 年前 |