python web中的并发请求

python web可以选择django,也可以选择flask,它们的原理差不多。flask比较轻量,下面写一段flask程序来说明python web对并发请求的处理。
app.py

import time

app = Flask()

@app.route('/')
def index():
    time.sleep(5) # 单位秒
    return render_temple('index.html')

如果使用python app.py命令启动此程序,则相当于单进程启动。两个人访问此web程序必然导致一个人会等待很久。也就是说,python app.py启动的是开发时的服务器,这个服务器是单进程的,这种启动方式只能用于开发时,不能用于部署。
如果部署,推荐使用gunicorn(green unicorn,绿色的独角兽)。使用gunicorn app -w 2 -b :8000命令,-w参数表示worker数,也就是此WEB程序开启的进程数,gunicorn会维护一个进程池来响应用户请求,开几个进程就表示并发量是多少。因为Python线程垃圾,只能使用进程了。

下面举一个更完整的例子来证明开发服务器无法处理并发请求。

from flask import Flask
import time
import requests
import multiprocessing

app = Flask("haha")


@app.route("/")
def haha():
    time.sleep(10)
    return "haha"


def go():
    time.sleep(3)  # 等待3秒钟,等服务器启动
    print(multiprocessing.current_process().name, "start request", time.time())
    resp = requests.get("http://localhost:5000/")
    print(resp.text)
    print(multiprocessing.current_process().name, "end request", time.time())


if __name__ == '__main__':
    multiprocessing.Process(target=go).start()
    multiprocessing.Process(target=go).start()
    app.run(debug=False)  # debug=True会导致程序启动两次

程序输出为

 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
Process-2 start request 1513270644.646835
Process-1 start request 1513270644.646835
127.0.0.1 - - [15/Dec/2017 00:57:35] "GET / HTTP/1.1" 200 -
haha
Process-2 end request 1513270655.6805644
haha
127.0.0.1 - - [15/Dec/2017 00:57:45] "GET / HTTP/1.1" 200 -
Process-1 end request 1513270665.6937685

显然,两个同时启动的进程,等待回复的时间却不一样,表明服务器只有一个worker在运行。如果把上述python文件中的多进程请求改为多线程请求,也能够看到类似的效果。

使用python app.py命令进行部署,只会造成并发性低,造成加载等待时间长、ajax请求时间长等问题,并不会发生错误。

参考资料

https://segmentfault.com/q/1010000004532745

原文地址:https://www.cnblogs.com/weiyinfu/p/8040718.html