擅长:python、mysql、java
<p>老问题了,但还是加上我的答案,以防对别人有帮助。我从最初的测试中得到的理解和大卫·沃尔夫的答案是一样的。我刚刚在芹菜3.1.19中做了更多的测试,<code>-Ofair</code>确实有效。只是它并不意味着要在工作节点级别禁用预取。这将继续发生。使用<code>-Ofair</code>在池工作线程级别有不同的效果。总之,要完全禁用预取,请执行以下操作:</p>
<ol>
<li>设置<code>CELERYD_PREFETCH_MULTIPLIER = 1</code></li>
<li>在全局级别或任务级别设置<code>CELERY_ACKS_LATE = True</code></li>
<li>启动工作进程时使用<code>-Ofair</code></li>
<li>如果将concurrency设置为1,则不需要执行步骤3。如果你想
更高的并发性,那么步骤3对于避免任务获得
备份在可以运行长时间运行任务的节点中。</li>
</ol>
<p>添加更多详细信息:</p>
<p>我发现默认情况下工作节点将始终预取。您只能通过使用<code>CELERYD_PREFETCH_MULTIPLIER</code>来控制它预取的任务数。如果设置为1,它将只预取与节点中池工作线程(并发)数量相同的任务。因此,如果concurrency=n,则节点预取的最大任务数将为n</p>
<p>如果没有<code>-Ofair</code>选项,对我来说,如果池工作进程之一正在执行长时间运行的任务,则节点中的其他工作进程也将停止处理节点已预取的任务。通过使用<code>-Ofair</code>,这就改变了。即使节点中的某个工作进程正在执行长时间运行的任务,其他工作进程也不会停止处理,而是继续处理节点预取的任务。所以我看到了两个级别的预取。一个在工作节点级别。另一个在个体工人层面。对我使用<code>-Ofair</code>似乎在工作级禁用了它。</p>
<p>如何与<code>ACKS_LATE</code>相关?<s> <code>ACKS_LATE = True</code>表示只有当任务成功时才会确认该任务。如果没有,我想当工人收到它的时候就会发生。在预取的情况下,该任务首先由工作进程接收(从日志中确认),但稍后将执行</s>。我刚刚意识到,在rabbitmq中,预取的消息显示在“未确认的消息”下。所以我不确定是否绝对需要将其设置为<code>True</code>。因为其他原因,我们的任务被设置成那样(延迟确认)。</p>