84669인 학습
152542인 학습
20005인 학습
5487인 학습
7821인 학습
359900인 학습
3350인 학습
180660인 학습
48569인 학습
18603인 학습
40936인 학습
1549인 학습
1183인 학습
32909인 학습
小伙看你根骨奇佳,潜力无限,来学PHP伐。
Flask 自带的服务器显然不能用在生产环境,我个人建议跑在 gunicorn 或者 uwsgi 上,外层还应该有 nginx,通过一些精心设计的参数(没有万能公式,需要在实践基础上调整)能够在服务器资源占用并发能力上取得较好的平衡。总之就是绝对不能单进程也不使用任何并发技术就放在生产环境,那绝对不耐操啊!
我之前的经验使用 gevent 效果并不是那么理想(那时候还没有 1.0)并且 monkey patch 会导致一些额外的问题。所以不是特别推荐。
回到 OAuth 这个问题上,既然提到问题是出在获取 access_token 这一步,那么就是说采用的是 OAuth 的 Authorization Code Grant 流程,并且进入了最后一步。我们回顾一下这个流程(摘自 OAuth 2 规范):
+----------+ | Resource | | Owner | | | +----------+ ^ | (B) +----|-----+ Client Identifier +---------------+ | -+----(A)-- & Redirection URI ---->| | | User- | | Authorization | | Agent -+----(B)-- User authenticates --->| Server | | | | | | -+----(C)-- Authorization Code ---<| | +-|----|---+ +---------------+ | | ^ v (A) (C) | | | | | | ^ v | | +---------+ | | | |>---(D)-- Authorization Code ---------' | | Client | & Redirection URI | | | | | |<---(E)----- Access Token -------------------' +---------+ (w/ Optional Refresh Token) Note: The lines illustrating steps (A), (B), and (C) are broken into two parts as they pass through the user-agent.
理论上,浏览器通过步骤 (C) 将请求发给 Flask 之后,就没浏览器什么事了(后续的事情不在流程里了),Flask 可以简单给一个 200 OK,并设计让浏览器通过 AJAX 稍后再从 Flask 请求数据,不必再苦苦等待 Flask 去执行步骤 (D) 并等待 (E) 了((E) 就是出现问题的步骤)。
Flask 当然可以直接去请求,如果做好了前面的并发处理和负载均衡,且用户数不是非常多的话。当然,如果请求规模足够大,Flask 可以发起一个异步任务,让专门的任务执行部件去执行操作。
之前,我开发的一个项目使用了 celery 通过 RabbitMQ 发送任务,由专门的程序处理这些需要一定时间才能完成的工作,任务结果存储在 Redis 中,每天处理数千万次类似的接口调用。
具体的,当 (C) 的请求到达 Flask 之后,Flask 向 RabbitMQ 发一个任务,就返回 200 OK 了。相应的任务执行部件执行步骤 (D) 并得到响应 (E),结果写入 Redis。浏览器过一段时间再次请求 Flask 要后续的信息,这时候 Flask 去 Redis 查询任务执行成功了没有,并做出对应的响应。
希望对题主有所帮助。
你可以使用gevent将 Flask 异步化。
Flask
在程序最开始处加入:
from gevent import monkey monkey.patch_all()
参考:
http://sergray.me/asynchony-in-the-flask.html
http://xlambda.com/gevent-tutorial/#monkey-patching
flask本来就是单线程的,可以通过它的wsgi,在前面加个nginx或者gunicorn之类的服务器实现多线程。tornado是单线程异步的,好像无法与flask兼容吧。
我来看看大家如何解决这个问题。囧。。。
ps:题主既然使用了DEBUG模式,可以把日志贴出来。
DEBUG
我在视图中用urllib2试了一下访问谷歌,还是有反应的,只不过最终会报错:
urllib2
在测试的时候,Flask响应的时间的确很慢。处理这种异步任务,建议使用Celery,目前也在学习使用Celery中
Celery
自答一下,Flask可以开启多线程,不过生产环境还是要用Nginx才行:
if __name__ == '__main__': app.run(host='*.*.*.*', port=80,threaded=True)
Flask自带的server是werkzeug,默认的werkzeug是单线程,对外请求就block了。可以入 @柳易寒 那样开启多线程即可。
server
werkzeug
Flask本身不是单进程单线程的,生产环境下,通过uwsgi或者gunicorn实现多线程方式。flask的用法没错,flask部署方式得结合uwsgi,gunicron甚至是gevent。
uwsgi
gunicorn
flask
gunicron
gevent
如果不用关心异步请求的结果,可以使用 Redis实现简单消息队列或celery实现异步请求
Flask 自带的服务器显然不能用在生产环境,我个人建议跑在 gunicorn 或者 uwsgi 上,外层还应该有 nginx,通过一些精心设计的参数(没有万能公式,需要在实践基础上调整)能够在服务器资源占用并发能力上取得较好的平衡。总之就是绝对不能单进程也不使用任何并发技术就放在生产环境,那绝对不耐操啊!
我之前的经验使用 gevent 效果并不是那么理想(那时候还没有 1.0)并且 monkey patch 会导致一些额外的问题。所以不是特别推荐。
回到 OAuth 这个问题上,既然提到问题是出在获取 access_token 这一步,那么就是说采用的是 OAuth 的 Authorization Code Grant 流程,并且进入了最后一步。我们回顾一下这个流程(摘自 OAuth 2 规范):
理论上,浏览器通过步骤 (C) 将请求发给 Flask 之后,就没浏览器什么事了(后续的事情不在流程里了),Flask 可以简单给一个 200 OK,并设计让浏览器通过 AJAX 稍后再从 Flask 请求数据,不必再苦苦等待 Flask 去执行步骤 (D) 并等待 (E) 了((E) 就是出现问题的步骤)。
Flask 当然可以直接去请求,如果做好了前面的并发处理和负载均衡,且用户数不是非常多的话。当然,如果请求规模足够大,Flask 可以发起一个异步任务,让专门的任务执行部件去执行操作。
之前,我开发的一个项目使用了 celery 通过 RabbitMQ 发送任务,由专门的程序处理这些需要一定时间才能完成的工作,任务结果存储在 Redis 中,每天处理数千万次类似的接口调用。
具体的,当 (C) 的请求到达 Flask 之后,Flask 向 RabbitMQ 发一个任务,就返回 200 OK 了。相应的任务执行部件执行步骤 (D) 并得到响应 (E),结果写入 Redis。浏览器过一段时间再次请求 Flask 要后续的信息,这时候 Flask 去 Redis 查询任务执行成功了没有,并做出对应的响应。
希望对题主有所帮助。
你可以使用gevent将
Flask
异步化。在程序最开始处加入:
参考:
http://sergray.me/asynchony-in-the-flask.html
http://xlambda.com/gevent-tutorial/#monkey-patching
flask本来就是单线程的,可以通过它的wsgi,在前面加个nginx或者gunicorn之类的服务器实现多线程。tornado是单线程异步的,好像无法与flask兼容吧。
我来看看大家如何解决这个问题。囧。。。
ps:题主既然使用了
DEBUG
模式,可以把日志贴出来。我在视图中用
urllib2
试了一下访问谷歌,还是有反应的,只不过最终会报错:在测试的时候,
Flask
响应的时间的确很慢。处理这种异步任务,建议使用Celery
,目前也在学习使用Celery
中自答一下,Flask可以开启多线程,不过生产环境还是要用Nginx才行:
Flask
自带的server
是werkzeug
,默认的werkzeug
是单线程,对外请求就block了。可以入 @柳易寒 那样开启多线程即可。Flask
本身不是单进程单线程的,生产环境下,通过uwsgi
或者gunicorn
实现多线程方式。flask
的用法没错,flask部署方式得结合uwsgi
,gunicron
甚至是gevent
。如果不用关心异步请求的结果,可以使用 Redis实现简单消息队列或celery实现异步请求