sma*_*ili 10 python flask uwsgi python-2.7
我一直在试着想出这个,希望其他人已经遇到过这个并且知道如何解决它:)
我正在尝试构建一个非常简单的Flask端点,只需要调用一个长时间运行的阻塞php
脚本(想想while true {...}
).我尝试了几种不同的方法来异步启动脚本,但问题是我的浏览器实际上从未收到响应,即使执行了运行脚本后生成响应的代码.
我同时使用尝试multiprocessing
和threading
,既不似乎工作:
# multiprocessing attempt
@app.route('/endpoint')
def endpoint():
def worker():
subprocess.Popen('nohup php script.php &', shell=True, preexec_fn=os.setpgrp)
p = multiprocessing.Process(target=worker)
print '111111'
p.start()
print '222222'
return json.dumps({
'success': True
})
# threading attempt
@app.route('/endpoint')
def endpoint():
def thread_func():
subprocess.Popen('nohup php script.php &', shell=True, preexec_fn=os.setpgrp)
t = threading.Thread(target=thread_func)
print '111111'
t.start()
print '222222'
return json.dumps({
'success': True
})
Run Code Online (Sandbox Code Playgroud)
在这两种情况下我看到的111111
和222222
,但我的浏览器仍然挂在从端点的响应.我已尝试p.daemon = True
过这个过程,p.terminate()
但没有运气.我曾希望在不同的shell中使用nohup启动一个脚本,并且单独的进程/线程可以正常工作,但不知何故Flask或uWSGI受其影响.
由于这在我的Mac上本地工作,当我直接启动我的Flask应用程序并直接python app.py
点击它而不通过我的Nginx代理和uWSGI时,我开始相信它可能不是代码本身存在问题.而且因为我的Nginx只是将请求转发给uWSGI,我相信它可能是导致它的东西.
这是uWSGI域的ini配置,我在emperor模式下运行:
[uwsgi]
protocol = uwsgi
max-requests = 5000
chmod-socket = 660
master = True
vacuum = True
enable-threads = True
auto-procname = True
procname-prefix = michael-
chdir = /srv/www/mysite.com
module = app
callable = app
socket = /tmp/mysite.com.sock
Run Code Online (Sandbox Code Playgroud)
这种东西是Python Celery
(https://docs.celeryproject.org/)的实际且可能是主要用例。作为一般规则,不要运行wsgi
进程中受 CPU 限制的长时间运行的作业。这很棘手,效率低下,最重要的是,它比在 celery Worker 中设置异步任务更复杂。如果您只想进行原型设计,可以将代理设置为不使用外部服务器,或者在同一台计算机上memory
运行单线程。redis
通过这种方式,您可以启动任务,调用task.result()
正在阻塞的任务,但它以IO 绑定方式阻塞,或者更好的是,您可以通过检索立即返回task_id
并构建第二个端点 /result?task_id=<task_id>
来检查结果是否可用:
result = AsyncResult(task_id, app=app)
if result.state == "SUCCESS":
return result.get()
else:
return result.state # or do something else depending on the state
Run Code Online (Sandbox Code Playgroud)
这样,您就拥有了一个非阻塞wsgi
应用程序,它可以执行最适合的操作:短时间的 CPU 无限制调用,最多具有操作系统级调度的 IO 调用,然后您可以直接依赖服务器wsgi
或workers|processes|threads
任何您需要扩展的应用程序。任何 wsgi 服务器(如 uwsgi、gunicorn 等)中的 API,可处理 99% 的工作负载,因为 celery 通过增加工作进程数量来水平扩展。
这种方法对我有用,它在命令行中调用超时命令(睡眠10秒)并让它在后台工作。它立即返回响应。
@app.route('/endpoint1')
def endpoint1():
subprocess.Popen('timeout 10', shell=True)
return 'success1'
Run Code Online (Sandbox Code Playgroud)
但是,没有在 WSGI 服务器上进行测试,而只是在本地进行测试。
归档时间: |
|
查看次数: |
977 次 |
最近记录: |