当前位置: 首页 > 面试题库 >

Celery不适用于全局变量

姜学海
2023-03-14
问题内容

from celery import Celery

app = Celery('tasks', backend='amqp://guest@localhost//', broker='amqp://guest@localhost//')

a_num = 0

@app.task
def addone():
    global a_num
    a_num = a_num + 1
    return a_num

这是我用来测试芹菜的代码。我希望每次使用addone()时,返回值都应该增加。但是为什么总是1?

结果

python
>> from tasks import addone
>> r = addone.delay()
>> r.get()
   1
>> r = addone.delay()
>> r.get()
   1
>> r = addone.delay()
>> r.get()
   1

问题答案:

默认情况下,启动工作程序时,Celery以并发4启动它,这意味着它已启动4个进程来处理任务请求。(加上一个控制其他进程的进程。)我不知道该使用哪种算法将任务请求分配给为工作人员启动的进程,但是最终,如果执行addone.delay().get()足够,您将看到该数字大于1。发生的事情是每个
进程 (不是每个 任务 )都有自己的副本a_num。当我在这里尝试时,我第五次执行addone.delay().get()return
2

您可以通过使用单个进程来启动您的工作程序来处理请求,从而强制每次增加该数量。(例如celery -A tasks worker -c1)但是,如果您重新启动工作程序,则编号将重置为0。此外,我不会设计仅在将处理请求的进程数强制为1时才起作用的代码。决定多个进程应处理对任务的请求,然后事情中断。(代码中注释中的粗大警告只能起到很大作用。)

最终,这种状态应该在缓存(例如Redis)或用作缓存的数据库中共享,这将适用于您问题中的代码。

但是,您在评论中写道:

让我们看看我想使用任务发送一些东西。我不想共享每次任务,而是共享一个全局连接。

将连接存储在缓存中将不起作用。我强烈建议让Celery开始的每个进程都使用其自己的连接,而不是尝试在各个进程之间共享它。
不需要随每个新任务请求重新打开连接。 每个进程将其打开一次,然后该进程处理的每个任务请求将重用连接。

在许多情况下,尝试在进程之间共享相同的连接(例如,通过通过共享虚拟内存fork)将无法正常工作。连接通常带有状态(例如,数据库连接是否处于自动提交模式)。如果代码的两部分期望连接处于不同的状态,则代码将运行不一致。



 类似资料:
  • 问题内容: 我在其中动态添加了许多内容。我面临的问题是,每当我单独将onTouch侦听器应用于其时,它都会检测到触摸,但是当我向相对布局中添加触摸时,它永远不会响应。 此代码可以很好地检测触摸事件: 但是,当我在myRelativeLayout中添加所有这些TextViews时: 现在,永远不会调用onTouchListener。为什么呢? 问题答案: 导致您的布局,而不是触发触摸事件。尝试删除它

  • 我试图填充一个相对的布局与4卡视图在它。每个cardview由一个图像和一个文本视图组成。我将所有卡片视图包装在一个相对布局中,将相对布局包装在一个滚动视图中。不管用。如果我移除scrollview,它可以正常工作。尝试将scrollview放入相对布局中。但没有工作代码:

  • 我正在用Beam Python构建管道。我有一个来自PubSub的事件流,其中包含userId和buttonId。我有一个全局窗口,用于维护所有用户单击按钮的次数。 如果一段时间后服务器重新开始运行Direct Runner/Flink Runner,全局windows状态是否会恢复到管道? Beam中的容错是如何工作的? 如何跟踪PubSub的偏移量/检查点? 光束留档指出: 状态的存储和容错:

  • 如果你要多于一个函数共用一个简单的变量,简单的处理方法就是把这个变量在所有函数中定义为global全局变量。在命令行做同样的事情,如果你要工作空间访问上述变量。这个全局变量的定义必须出现在变量被应用于一个函数之前。虽然不是要求,但全局变量也最好以大写字母开头,这样可以同其他变量区别出来。举个例子,做一个以falling.m命名的M-文件。 function h = falling(t) globa

  • ThinkCMF封装了前台模板开发时常用的一些变量,这些变量是全局的,你在前台模板任何时候都能直接调用: {$site_name} /站点名称 {$site_host} /站点域名 {$site_root} /安装目录 {$site_icp} /

  • swoole内置了几个全局变量供程序内使用。一般不要自行创建全局变量。 SwooleG 超全局本地内存变量,此变量在swoole_init时就初始化好了。存储了一些全局的信息。但不是共享内存的。当创建子进程后再修改其中的字段,其他进程是感知不到的 SwooleG.main_reactor,全局事件循环 SwooleG.lock,全局锁 SwooleG.memory_pool,全局共享内存池 Swo