fastapi项目如何使用celery-避坑指南,不只是fastapi也适用于其它项目,解决celery报错不执行任务的问题,并且讲解如何轻松的使用docker来部署项目

最近抽时间做了个小项目是个抢座网站,同时用到了FastAPI作为后端,Celery来处理定时任务

核心部分是用户通过FastAPI的后端接口来提交任务到Redis,Celery每天定时从Redis里面获取任务信息然后运行内部的抢座脚本

踩坑的第一个点是,高版本的celery不支持windows!

踩坑的第二个点我为了图省事,开发的时候把Celery和我的抢座程序单独放在一起部署到了linux服务器上,然后我在本地用FastAPI调试接口去发布任务,导致服务器里的celery程序和本地fastapi程序里的代码不一致,celery报错不给我执行任务。

出问题的点就是:使用celery发布任务的后端程序代码,执行任务的celery程序里也要有一份

避坑指南就是:整个项目的代码我们一式两份,后端程序一份,celery程序一份!

下面我们配合docker来详细说一下这件事情

示例代码

假设我的项目主目录下有三个文件

-main.py  #fastAPI后端
-script.py #耗时任务
-celery.py #celery
-requirements.txt 
-DockerFile
-docker-compose.yml

script.py

#模拟一个耗时任务
import time

def get_seats(num):
	time.sleep(5)
	print(num)
	return num

my_celery.py

#Celery
import celery
from script import get_seats

backend = 'redis://redis:6379/1'
broker = 'redis://redis:6379/0'

cel = celery.Celery('task',backend=backend,broker=broker)

@cel.task
def add_task(num):
    result =  get_seats(num)
    return result

main.py

#fastAPI服务
import uvicorn
from fastapi import FastAPI
from my_celery import add_task
import datetime

app = FastAPI()

# 获取当前eta时间计算出10分钟后eta时间交给celery
#也就是任务提交10分钟后将会被定时执行
current_time = datetime.datetime.now()
set_time = current_time + datetime.timedelta(minutes=10)

@router.get('/add_task/{num}',summary='添加任务')
async def add_task(num:int):
	data = add_task.apply_async(args=[num], eta=set_time)
    print('- 任务已添加:', data.id)
    return data.id

if __name__ == "__main__":
    uvicorn.run('main:app', host='0.0.0.0', port=8000, reload=True, workers=1)

如何部署?

我们现在想用docker来部署这个程序,我们来想想我们需要多少个容器?

答案是3个,fastapi后端一个、celery一个、redis作为消息中间件一个

redis的部署就不用说了直接拉官方镜像就行啥也不用管

fastapi和celery怎么部署?我们需要自己写DockerFile来构建我们需要的python环境镜像

我们需要几个Dockerfile?答案是一个我们只需要一个python环境镜像,用同一个镜像来构建fastapi和clery项目就行

Dockerfile

FROM python:3.10.4
ENV PYTHONNUNBUFFERED = 1
WORKDIR /app
COPY requirements.txt requirements.txt
RUN pip3 install --upgrade pip
RUN pip3 config set global.index-url https://mirrors.aliyun.com/pypi/simple/
RUN pip3 config set install.trusted-host mirrors.aliyun.com
RUN pip3 install -r requirements.txt
COPY . /app
EXPOSE 8000

这里面最关键的点就是这一句

COPY . /app

我把所有的文件都copy到了容器的/app目录下

而我们fastapi容器和celery容器都是用这个镜像构建出来的,这就意味着,celery容器和fastapi容器里的所有文件都是一摸一样的,它们是同一份,这就保证了celery不会给我们报错

celery容器里有些文件可以不用但不能没有,所以我们直接全部的代码一式两份,两个容器一人一份,两个容器里的代码文件都一摸一样,不仅省事而且不会报错!

我们来看看docker-compose文件,你能清晰的看到这一点

version: '3.8'

services:
  redis:
    container_name: redis
    image: redis:6.2-alpine

  fastapi:
    container_name: fastapi
    build: . #都是从当前目录里去找DockerFile而目录里只有一份,所以用的是同一份
    command: bash -c "python3 main.py"
    volumes:
      - .:/app
    ports:
      - "8000:8000"
    depends_on:
      - redis

  
  celery:
    container_name: celery
    build: . #都是从当前目录里去找DockerFile而目录里只有一份,所以用的是同一份
    command: bash -c "celery -A my_celery worker -l INFO"
    volumes:
      - .:/app
    depends_on:
      - redis
      - backend
      

最后我们运行,就完事了

docker compose up

总结

上面的代码可能跑不起来,我写博客的时候也没去真实的测试,但是足够简洁足够说明问题

我们总结一下,这篇博客里面最重要的内容就是说明:我们部署celery程序和后端程序的时候,尽量要保证两者的代码是同一份,不然可能导致celery报错拒绝执行我们的任务!

  • 5
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
FastAPICelery 都是 Python 语言中常用的 Web 应用框架和异步任务队列框架。它们可以很好地结合使用,实现高性能的 Web 应用和异步任务处理。下面是一个简单的 FastAPICelery 结合的示例。 首先,我们需要安装 FastAPICelery,可以使用 pip 命令进行安装: ``` pip install fastapi celery ``` 接下来,我们需要创建一个 FastAPI 应用程序,并将 Celery 配置为其异步任务队列。为此,我们可以创建一个名为 `main.py` 的文件,添加以下代码: ```python from fastapi import FastAPI from celery import Celery app = FastAPI() # Celery 配置 celery = Celery('tasks', broker='pyamqp://guest@localhost//') # 异步任务 @celery.task def add(x, y): return x + y # FastAPI 路由 @app.get('/') async def root(): result = add.delay(4, 4) return {'result': result.id} ``` 在上面的代码中,我们首先创建了一个名为 `app` 的 FastAPI 应用程序,然后使用 Celery 创建了一个名为 `celery` 的异步任务队列。接下来,我们定义了一个名为 `add` 的异步任务,该任务接受两个参数 `x` 和 `y`,并返回它们的和。最后,我们创建了一个 FastAPI 路由,该路由调用了 `add` 异步任务,并返回任务 ID。 现在,我们可以使用以下命令启动 Celery worker 和 FastAPI 应用程序: ``` celery -A main.celery worker --loglevel=info uvicorn main:app --reload ``` 这将启动 Celery worker 和 FastAPI 应用程序,并在访问 `http://localhost:8000/` 时调用异步任务,并返回任务 ID。 总之,FastAPICelery 可以很好地结合使用,实现高性能的 Web 应用和异步任务处理。通过使用异步任务队列,可以将耗时的任务转移到后台处理,从而提高 Web 应用程序的响应速度和性能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值