我有一个运行Django数据库和memcache的
Python脚本,但它特别是作为一个独立的守护进程运行(即不响应webserver请求).守护进程检查状态= STATUS_NEW的对象的Django模型请求,然后标记为STATUS_WORKING并将其放入队列.
许多进程(使用多进程包创建)将从Queue中抽出东西,并使用传递给队列的pr.id对请求进行处理.我相信内存泄漏可能在下面的代码中(但是它可能在队列的另一边的“工作者”代码中,尽管这不太可能,因为即使没有请求出现,内存大小也在增长 – 即当工作人员都阻止Queue.get()).
from requisitions.models import Requisition # our Django model
from multiprocessing import Queue
while True:
# Wait for "N"ew requisitions, then pop them into the queue.
for pr in Requisition.objects.all().filter(status=Requisition.STATUS_NEW):
pr.set_status(pr.STATUS_WORKING)
pr.save()
queue.put(pr.id)
time.sleep(settings.DAEMON_POLL_WAIT)
其中settings.DAEMON_POLL_WAIT = 0.01.
似乎如果我离开这个运行一段时间(即几天),Python进程将增长到无限大小,最终系统内存不足.
这里发生了什么(或者如何找到),更重要的是 – 如何运行这样的守护进程?
我的第一个想法是改变功能的动态,特别是通过将新的Requisition对象的检查放在django.core.cache缓存中,即
from django.core.cache import cache
while True:
time.sleep(settings.DAEMON_POLL_WAIT)
if cache.get('new_requisitions'):
# Possible race condition
cache.clear()
process_new_requisitions(queue)
def process_new_requisitions(queue):
for pr in Requisition.objects.all().filter(status=Requisition.STATUS_NEW):
pr.set_status(pr.STATUS_WORKING)
pr.save()
queue.put(pr.id)
正在创建状态= STATUS_NEW的请求的进程可以执行cache.set(‘new_requisitions’,1)(或者我们可以捕获一个信号或Requisition.save()事件,其中正在创建一个新的请购单,然后将标志设置为缓存从那里).
然而,我不确定我在这里提出的解决方案是否解决了内存问题(这可能与垃圾收集有关),所以通过process_new_requisitions可以解决这个问题).
我很感谢任何想法和反馈.