2
我有一个运行我的Flask应用程序和Celery工作者的多个服务器的设置。 Flask路由在本地处理文件上载,并将Celery任务排队以将该文件上传到CDN。在处理Flask请求的服务器上运行Celery任务
Celery任务可以由集群中的任何节点处理。如果Celery任务由不同于处理Flask路由的节点处理,则不会找到该文件,并且任务将失败。
如何确保Celery任务在处理Flask路由的同一节点上运行?
我有一个运行我的Flask应用程序和Celery工作者的多个服务器的设置。 Flask路由在本地处理文件上载,并将Celery任务排队以将该文件上传到CDN。在处理Flask请求的服务器上运行Celery任务
Celery任务可以由集群中的任何节点处理。如果Celery任务由不同于处理Flask路由的节点处理,则不会找到该文件,并且任务将失败。
如何确保Celery任务在处理Flask路由的同一节点上运行?
如果您希望处理上载的服务器处理后台作业,则根本不需要Celery。当你需要分配和排队任务时,Celery是很好的,但是你所描述的是本地的,并且在上传之后。
而不是一个芹菜任务,只是在本地产生一个进程来处理后台作业。
from multiprocessing import Process
from flask import Flask, render_template, request, redirect
app = Flask(__name__)
@app.route('/', methods=['GET', 'POST'])
def upload():
if request.method == 'POST':
f = request.files['file']
Process(target=handle_file, args=(f,)).start()
return redirect(request.path)
return render_template('upload.html')
def handle_file(f):
print(f.read())
if __name__ == '__main__':
app.run('localhost')
如果你想坚持芹菜,你可以forgoe文件保存在本地,并通过文件数据作为参数传递给了任务,所以无论什么服务器处理上载,即处理的一个任务总会有数据。如果文件很大,可能会有性能问题。
@celery.task
def upload(data):
...
upload.delay(file.read())
没有专用的上传框。任何应用程序服务器实例都可以是向客户端公开POST API的上传框。 – lang2
@ lang2我已经更新了我的答案,现在我明白你的意思了。 – davidism
@davidsm w.r.t第二种方法:文件上传将在一个HTML格式的文件中提交,我不认为它可以被另一个节点访问。 – lang2