前言:
在现代软件开发过程中,将应用组件容器化并确保各组件能够高效协同工作,是提高项目可维护性和可扩展性的关键策略之一。Celery结合FastAPI作为Python开发者的首选框架组合,允许开发者构建高效的异步任务处理机制,同时保持API的轻量和高效特性。本文将详细介绍如何将使用Celery和FastAPI创建的定时任务分离出来,并通过Docker进行部署。这种方式不仅可以提高应用的可靠性,同时也使得部署过程更加灵活和模块化。
下面的Redis和RabbitMQ服务可以不需要Docker化,自己有替代的也是可以的,替换掉对应的ip或者端口即可
Redis-Docker化
docker run -v /opt/redis:/usr/local/etc/redis -d --name rd -p 6379:6379 redis redis-server /usr/local/etc/redis/redis.conf
上面的命令将会将/opt/redis的目录挂载到/usr/local/etc/redis容器中,如果你不挂载,将会自动读取默认的配置文件。
RabbitMQ-Docker化
docker run -d --name rq -p 5462:5462 rabbitmq
将会启动一个Rabbitmq的容器,其中配置需要自己配置下,如允许其他ip访问,设置用户名密码等。
Celery定时任务容器配置
docker run --name celery -v /tmp/celery_data:/tmp/celery_data -dit python:3.11-slim
注意,python的版本会对你的Celery启动产生影响。目前Celery最新版本为5开头,所以需要3.11的python版本才可以正常启动这个Celery。
Celery定时任务文件配置
我们在/tmp/celery_data目录下建立一个tasks.py文件,此外我们可以将所有需要Celery的任务放到这个文件中,并且用@app.task去装饰
from celery import Celery
app = Celery('tasks', backend='redis://localhost', broker='pyamqp://localhost')
@app.task
def add(x, y):
return x + y
Celery启动
输入下面的命令将会启动Celery的消费端。
docker exec -w /tmp/celery_data/ -it celery bash -c "celery -A tasks worker --loglevel=info"
Celery-FastApi生产端配置
注意生产端和消费端目前都是同一个容器或者同一个Redis/Rabiitmq
from celery import Celery
app = Celery('tasks', backend='redis://localhost', broker='pyamqp://localhost')
@app.get("/")
async def root():
"""
接收两个整数参数x和y,通过Celery在后台服务计算它们的和。
"""
task = celery_app.signature('tasks.add', args=(10, 10))
result = task.apply_async()
# 等待并获取结果
data = {'result': result.get()}
return {"message": "Hello world"}
- celery_app.signature(‘tasks.add’, args=(10, 10)) 这行代码创建了一个Celery任务的签名。这里的签名是对将要执行的任务的一种预配置,定义了任务的执行方式但不立即执行它。
- ‘tasks.add’ 表示在Celery中注册的任务名称,这个名称对应于实际定义并装饰了@app.task()的函数。
- args=(10, 10) 提供了执行任务时需要的参数,根据示例,这里的add任务应该是一个加法操作,把两个数字10和10相加。
- task.apply_async() 将任务以异步的方式发送到Celery的工作队列中去。该函数返回一个AsyncResult对象,允许你监控或获取任务执行的结果。
- 这一行代码的执行不会阻塞程序的运行,允许主程序继续执行其它操作。apply_async()方法可确保应用在等待任务完成期间可以继续响应用户请求或执行其他任务。
结尾
通过本文的介绍,您应该已经掌握了如何将Celery和FastAPI组合使用的定时任务抽离,并利用Docker进行部署的方法。这种技术的运用可以使得您的开发工作更加高效,应用部署更加稳定。容器化的策略不仅优化了资源的使用,还增强了应用的安全性和可移植性。希望您能将这些技巧应用到实际的项目开发中,以解决具体问题并优化您的工作流程。
评论区