使用Celery可否实现不同代码库的Project A与Project B跨项目任务调用
Celery跨独立项目调用任务实现方案
该需求完全可实现。Celery的任务调度基于生产者-消费者模型:Project B作为生产者只负责将任务元数据(任务名、参数、调用配置)推到公共Broker队列,Project A的worker作为消费者从队列拉取任务后匹配本地注册的任务代码执行,因此不需要Project B持有任务的实际实现逻辑。
以下是两种常用实现方案:
方案1:直接调用send_task方法(无冗余代码,适合低频调用场景)
无需在Project B中定义任务,直接通过Celery实例的send_task方法指定目标任务的完整注册名发送任务即可。
Project B调用示例代码:
from celery import Celery # 保持和现有配置完全一致即可 app = Celery('task', broker='redis://localhost:6379/1', backend='rpc://') # 第一个参数为Project A中add任务的完整注册名,args为任务入参 result = app.send_task('project_a.tasks.add', args=(2, 3)) # 同步等待获取执行结果 print(result.get())
注意事项:
- 必须确认Project A中add任务的完整注册名,可在Project A的运行环境中执行命令
celery inspect registered查看所有已注册的任务全名,默认命名规则为「定义任务的模块路径.函数名」,比如add定义在project_a/tasks.py中则默认名为project_a.tasks.add。
方案2:Project B中定义占位任务签名(代码更友好,适合高频调用场景)
如果需要频繁调用该任务,可在Project B中定义一个同名占位任务,不需要写实现逻辑,调用方式和本地任务完全一致。
Project B示例代码:
from celery import Celery, shared_task app = Celery('task', broker='redis://localhost:6379/1', backend='rpc://') # 手动指定name和Project A中任务的全名一致,即可不受当前模块路径影响 @shared_task(name='project_a.tasks.add') def add(x, y): # 不需要写任何实现逻辑,仅作为任务签名使用 pass # 调用方式和本地任务完全一致 result = add.delay(2, 3) print(result.get())
通用注意事项
- 确保两个项目连接的是同一个Redis Broker实例,你当前配置中两个项目都连接
redis://localhost:6379/1符合要求。 - 确保Project A的Celery worker正常启动,且启动时加载了add任务所在的模块(启动命令示例:
celery -A project_a worker --loglevel=info)。 - 若任务参数使用自定义类型,需保证两个项目的序列化/反序列化规则一致,默认json序列化对字符串、数字、列表、字典等基础类型无兼容问题。
内容的提问来源于stack exchange,提问作者madrias
相关产品推荐
相关产品推荐

