Python 芹菜:防止在太多任务排队时添加更多任务
我有一个Python 芹菜:防止在太多任务排队时添加更多任务,python,asynchronous,flask,celery,amqp,Python,Asynchronous,Flask,Celery,Amqp,我有一个Flaskrestapi,它利用芹菜来运行异步请求 其思想是,async=1query参数指示应该异步处理请求(立即返回任务ID,客户机稍后将使用该ID) 同时,我想防止在等待处理的任务太多时接受新任务 下面的代码可以工作,但接受新任务()需要2秒钟左右,这太慢了 芹菜中是否有允许限制等待任务数量的配置(或其他配置);还是更快地获得等待任务数量的方法 import math from celery import Celery from flask import abort, Flask
Flask
restapi,它利用芹菜
来运行异步请求
其思想是,async=1
query参数指示应该异步处理请求(立即返回任务ID,客户机稍后将使用该ID)
同时,我想防止在等待处理的任务太多时接受新任务
下面的代码可以工作,但接受新任务()需要2秒钟左右,这太慢了
芹菜中是否有允许限制等待任务数量的配置(或其他配置);还是更快地获得等待任务数量的方法
import math
from celery import Celery
from flask import abort, Flask, jsonify, request
flask_app = Flask(__name__)
celery_app = Celery("tasks", broker="rabbit...")
@flask_app.route("/")
def home():
async_ = request.args.get("async")
settings = request.args.get("settings")
if async_:
if not accepting_new_tasks(celery_app):
return abort(503)
task = celery_app.send_task(name="my-task", kwargs={"settings": settings})
return jsonify({"taskId": task.id})
return jsonify({})
def accepting_new_tasks(celery_app):
inspector = celery_app.control.inspect()
nodes_stats = inspector.stats()
nodes_reserved = inspector.reserved()
workers = 0
for stats in nodes_stats.values():
workers += stats["pool"]["max-concurrency"]
waiting_tasks = 0
for reserved in nodes_reserved.values():
waiting_tasks += len(reserved)
return waiting_tasks < math.ceil(workers / 3)
导入数学
从芹菜进口芹菜
从烧瓶导入中止、烧瓶、jsonify、请求
烧瓶\应用=烧瓶(\名称\名称)
芹菜应用程序=芹菜(“任务”,broker=“兔子…”)
@烧瓶/应用程序路线(“/”)
def home():
async=请求.args.get(“异步”)
设置=request.args.get(“设置”)
如果异步:
如果不接受新任务(芹菜应用程序):
返回中止(503)
task=celery\u app.send\u task(name=“my task”,kwargs={“settings”:settings})
返回jsonify({“taskId”:task.id})
返回jsonify({})
def接受新任务(芹菜应用程序):
inspector=芹菜\应用程序控制.inspect()
nodes\u stats=inspector.stats()
节点\u reserved=inspector.reserved()
工人=0
对于节点中的统计信息\u stats.values():
workers+=stats[“池”][“最大并发”]
正在等待的任务=0
对于在节点中保留的\u reserved.values():
等待任务+=len(保留)
返回等待任务
最后我通过查询RabbitMQ管理API解决了这个问题,正如前面指出的那样
import math
from celery import Celery
from flask import abort, Flask, jsonify, request
from requests import get
from requests.auth import HTTPBasicAuth
flask_app = Flask(__name__)
celery_app = Celery("tasks", broker="rabbit...")
def get_workers_count():
inspector = celery_app.control.inspect()
nodes_stats = inspector.stats()
nodes_reserved = inspector.reserved()
workers = 0
for stats in nodes_stats.values():
workers += stats["pool"]["max-concurrency"]
return workers
WORKERS_COUNT = get_workers_count()
@flask_app.route("/")
def home():
async_ = request.args.get("async")
settings = request.args.get("settings")
if async_:
if not accepting_new_tasks(celery_app):
return abort(503)
task = celery_app.send_task(name="my-task", kwargs={"settings": settings})
return jsonify({"taskId": task.id})
return jsonify({})
def accepting_new_tasks(celery_app):WORKERS_COUNT
auth = HTTPBasicAuth("guest", "guest")
response = get(
"http://localhost:15672/api/queues/my_vhost/celery",
auth=auth
)
waiting_tasks = response.json()["messages"]
return waiting_tasks < math.ceil(WORKERS_COUNT / 3)
导入数学
从芹菜进口芹菜
从烧瓶导入中止、烧瓶、jsonify、请求
从请求导入获取
从requests.auth导入HTTPBasicAuth
烧瓶\应用=烧瓶(\名称\名称)
芹菜应用程序=芹菜(“任务”,broker=“兔子…”)
def get_workers_count():
inspector=芹菜\应用程序控制.inspect()
nodes\u stats=inspector.stats()
节点\u reserved=inspector.reserved()
工人=0
对于节点中的统计信息\u stats.values():
workers+=stats[“池”][“最大并发”]
返乡工人
工人计数=获取工人计数()
@烧瓶/应用程序路线(“/”)
def home():
async=请求.args.get(“异步”)
设置=request.args.get(“设置”)
如果异步:
如果不接受新任务(芹菜应用程序):
返回中止(503)
task=celery\u app.send\u task(name=“my task”,kwargs={“settings”:settings})
返回jsonify({“taskId”:task.id})
返回jsonify({})
def接受新任务(芹菜应用程序):工人计数
auth=HTTPBasicAuth(“来宾”、“来宾”)
响应=获取(
"http://localhost:15672/api/queues/my_vhost/celery",
auth=auth
)
waiting_tasks=response.json()[“messages”]
返回等待任务
您可以添加一些详细信息吗?为什么呢?我的意思是,你想解决什么问题?@DanilaGanchar我想处理大量数据,根据通过的设置
,这些数据可能需要数小时。好的。现在让我们想象一下所有工人都在工作(现在12:12:12.52….
)。您返回了abort(503)
,但在12:12:12.53….
中,一些工作人员可用。这是正确的行为吗?我的意思是你有等待的时间范围吗?@DanilaGanchar没有,没有等待的时间范围。想法是在每次请求之前检查。无论如何,我已经通过使用RabbitMQ管理API解决了这个问题:。