如何根据请求记录Django应用程序的内存使用情况

时间:2012-09-03 13:48:34

标签: python django apache memory-leaks

您是否了解了根据请求记录django应用程序内存使用情况的有效方法?

我有一个apache / mod_wsgi / django堆栈,它通常运行良好,但有时一个进程最终会占用大量内存。服务器最终缺少内存,交换很多,服务也大大减慢。

这种情况很难修复,因为我不知道哪个请求会被归咎于此行为,我无法重现它。

我希望在生产中部署一些内容,在每次请求之前和之后记录进程的内存使用情况,而且开销最小。


在我开始重新发明轮子之前,我的同伴们的社区是否知道解决这个问题的任何现有解决方案? 建议,中间件,代码段或apache日志配置表示赞赏。

我认为不需要的是:

  • 一组开发阶段分析/调试工具,我已经知道了一些,如果我知道要分析/调试什么,我会使用它们,看起来有点太多,无法永远监视生产中运行的服务。最重要的是,那些tol通常显示的是代码碎片的内存使用情况报告,只是查明错误的请求真的很有帮助。
  • 关于如何优化django应用程序的mem使用的一般性建议,以及它总是很好阅读,但这里的想法是“如何有效地追踪需要优化的请求”。

我最接近的搜索结果:

2 个答案:

答案 0 :(得分:18)

用于跟踪内存使用情况并立即生成可用结果的Django中间件需要挂钩进程请求和进程响应。换句话说,查看请求的开始和结束之间的差异,如果超过某个阈值,则记录警告。

完整的中间件示例是:

import os
import psutil
import sys

THRESHOLD = 2*1024*1024

class MemoryUsageMiddleware(object):

    def process_request(self, request):
        request._mem = psutil.Process(os.getpid()).memory_info()

   def process_response(self, request, response):
        mem = psutil.Process(os.getpid()).memory_info()
        diff = mem.rss - request._mem.rss
        if diff > THRESHOLD:
            print >> sys.stderr, 'MEMORY USAGE %r' % ((diff, request.path),)
        return response

这需要安装'psutil'模块进行内存计算。

蛮力并且可能导致多线程系统中的误报。由于延迟加载,您还会看到它会在因为内容加载而针对新进程的前几个请求时触发。

答案 1 :(得分:1)

这可能不完全涵盖您的问题,但我建议尝试使用nginx + uwsgi而不是apache2 + mod_wsgi。在我的测试中,它变得更加稳定(mod_wsgi在某些时候完全被阻塞),速度更快,使用的内存更少(它可能只是完全修复你的所有问题)。

关于跟踪内存使用情况,您可以创建一个简单的中间件:

class SaveMemoryUsageMiddleware(object):
    def process_response(self, request, response):
        # track memory usage here and append to file or db
        return response

并将其添加到您的中间件。

对于内存跟踪代码,我建议您查看: Total memory used by Python process?

然而,如果你能避免在生产中这样做,那可能会更好。只是为了开发和测试来追踪真正的问题。