js等待异步执行完再执行_Django实战011:celery异步执行任务

前言

项目中经常会遇到一些任务执行时间比较长,比如我司希望通过Web请求调用UG程式进行自动换算并出图的功能,而UG本身应用就比较大,启动耗时较长,再加上每次会发送多条任务,所以每次调用时都需要等待段时间,这样用户体验就不怎么友好,为了加快用户的响应时间,因此决定采用异步方式在后台执行这些任务,celery就是用于处理异步任务的框架。

0e0d20d84e24f8c0689d101fc674df03.png

什么是同步、异步

同步:一定要等任务执行完了,得到结果,才执行下一个任务。

异步:不等任务执行完,直接执行下一个任务,所以程序的执行顺序与任务的排列顺序是不一致的、异步的。

什么是Celery

Celery是基于Python开发的简单、灵活且可靠的,能处理大量消息的一个分布式任务队列框架,支持使用任务队列的方式在分布的机器、进程、线程上执行任务调度,同时还支持定时任务。

735a38aacb55771ac44e7b153a0b82df.png

安装celery

我司项目将redis作为broker,所以需要将redis一起安装,注意我这用的不是django-celery。

pip install celerypip indatll redis

创建celery应用

在ettings同级目录创建一个celery.py文件,引入Celery,然后配置环境变量并创建应用,这里我司将redis作为broker使用了,所以在运行任务前必须先启动redis哦(broker消息队列用于发送和接收消息)。

from celery import Celeryfrom django.conf import settingsimport os# 为celery设置环境变量os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'AIMilling.settings.dev')CELERYD_MAX_TASKS_PER_CHILD = 10# 创建应用app = Celery("demo")# 配置应用app.conf.update( # 配置broker, 这里我们用redis作为broker broker_url='redis://@127.0.0.1:6379/1',)# 设置app自动加载任务# 从已经安装的app中查找任务app.autodiscover_tasks(settings.INSTALLED_APPS)

创建tasks.py文件

在需要使用异步任务的app中创建tasks.py,写入具体的异步任务的方法,这是我司用于调用UG自动生成NC程式的接口方法,使用celery自带的装饰器@task标记函数,这样Celery就知道这一个task方法。

import ctypesfrom AIMilling.celery import app# 创建任务函数from AIMilling.settings.dev import api_path, ug_computer_ipfrom case_manage.models import Program_Path@app.taskdef winfile(prt_file, txt_file, savePath, id): '''向windows發送文件''' lib = ctypes.CDLL('EditCAMParameter.dll') prt_file = bytes(prt_file, encoding='utf-8') txt_file = bytes(txt_file, encoding='utf-8') ip = bytes(ug_computer_ip, encoding='utf-8') b_avePath = bytes(savePath, encoding='utf-8') res = lib.create_ncprg(prt_file, txt_file, b_avePath, ip) if res == 200: Program_Path.objects.filter(id=id).update(status=1) return {ug_computer_ip: 200} return {ug_computer_ip: 400}

触发task任务

在对应的视图中导入tasks中的任务函数调用,然后在调用时加入delay方法来异步处理函数将任务送入broker队列,这样当我们在前端访问该接口时,后台会立即放回response, 从而不阻塞该request, 但任务依旧在后台继续执行中。因为启动时设置了solo模式,所以winfile没有执行完前,即使再次发送执行winfile的任务,celery worker也会等到前一个任务执行完才去执行下一个的。

from case_manage.tasks import winfile # 导入函数res=winfile.delay(prt_path, txt_path, datetime_path, obj.id) # 调用UG程式处理数据

启动redis

下载redis,我直接官方下了一个免安装版的redis,然后解压即可,运行直接进入redis目录打开cmd执行命令:redis-server redis.windows.conf

4e301aed8b50b903a0fce07e3ae69c36.png

启动Celery服务

先启动redis,然后在项目根目录下执行命令:celery -A AIMilling worker --loglevel=info --pool=solo

celery命令解释(查看完整的命令行参数列表 :celery worker --help):

'-A' 是一个全局配置,定义了APP的位置

'--pool' 是POOL的配置,默认是prefork(并发),选择solo之后,发送的任务不会被并发执行,在worker执行任务过程中,再次发送给worker的任务会排队,执行完一个再执行另一个。

欢迎关注本人的公众号:编程手札,文章也会在公众号更新

81edccc612d8a8b9ddfefeb71a0bf5b5.gif
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值