flask多进程多线程配置

8 篇文章 0 订阅
6 篇文章 0 订阅

flask.Flask.run接受**options转发给它的其他关键字参数()werkzeug.serving.run_simple-其中两个参数是threaded(布尔值)和processes(您可以将其设置为大于1的数字以使werkzeug产生多个进程来处理请求)。

threaded默认True版本自Flask 1.0起,因此对于最新版本的Flask,默认情况下默认开发服务器将能够同时为多个客户端提供服务。对于较旧版本的Flask,您可以显式传递threaded=True以启用此行为。

例如,您可以

if name == ‘main’:
app.run(threaded=True)
以与旧Flask版本兼容的方式使用线程处理多个客户端,或者

if name == ‘main’:
app.run(threaded=False, processes=3)
告诉Werkzeug生成三个进程来处理传入的请求,或者只是

if name == ‘main’:
app.run()
如果您知道将使用Flask 1.0或更高版本,则可以使用线程来处理多个客户端。

话虽如此,Werkzeug的serving.run_simple包装了标准库的wsgiref软件包-该软件包包含WSGI的参考实现,而不是可用于生产的Web服务器。如果您要在生产环境中使用Flask(假设“生产环境”不是低流量的内部应用程序,并发用户不超过10个),请确保将其支撑在真实的Web服务器后面(请参阅Flask文档标题为“ 一些建议方法的部署选项)。

0x02 Flask开启自带的多线程或多进程
开启多线程:

app.run(debug=debug, host='0.0.0.0', port=8082, threaded=True)
1
app.run(debug=debug, host='0.0.0.0', port=8082, threaded=True)
开启多进程

app.run(debug=debug, host='0.0.0.0', port=8082, processes=10)
1
app.run(debug=debug, host='0.0.0.0', port=8082, processes=10)
需要注意的是,多进程和多线程不可以同时开启,且需要关闭debug。下面再来看下请求结果

[Process 91295] [Thread 123145513381888] 2020-09-29 14:29:01 _internal.py _log[line:122]
[Process 91295] [Thread 123145509175296] 2020-09-29 14:29:01 _internal.py _log[line:122]
1
2
[Process 91295] [Thread 123145513381888] 2020-09-29 14:29:01 _internal.py _log[line:122]
[Process 91295] [Thread 123145509175296] 2020-09-29 14:29:01 _internal.py _log[line:122]
可以看到,已经可以并发处理了。

关于多进程方式,processes参数是指定进程数量,当并发度大于请求数量的时候仍然会阻塞。

0x03 使用gunicorn多进程启动Flask
安装gunicorn

pip install gunicorn
1
pip install gunicorn
安装完成后可以使用下面的命令来启动

gunicorn 入口文件名:app
1
gunicorn 入口文件名:app
这里的app是Flask(__name__)返回值得接收变量

gunicorn支持配置文件启动,如下例子:

# gunicorn.conf

bind = "0.0.0.0:5000"
workers = 4
backlog = 2048
pidfile = "log/gunicorn.pid"
accesslog = "log/access.log"
errorlog = "log/debug.log"
timeout = 600
debug=False
capture_output = True

# gunicorn.conf
 
bind = "0.0.0.0:5000"
workers = 4
backlog = 2048
pidfile = "log/gunicorn.pid"
accesslog = "log/access.log"
errorlog = "log/debug.log"
timeout = 600
debug=False
capture_output = True
启动命令

gunicorn --config gunicorn.conf main:app
1
gunicorn --config gunicorn.conf main:app
 
前言:
使用flask做服务时,可以使用python run.py的方式运行,但是这样不能用于生产环境,可能会出现连接无响应的情况。后来通过查找资料,发现flask服务处理多线程、高并发的一下方法,主要有一下几个方面:

1.通过设置app.run()的参数,来达到多线程的效果,具体参数:

# 1.threaded : 多线程支持,默认为False,即不开启多线程;
app.run(threaded=True)
# 2.processes:进程数量,默认为1.
app.run(processes=True)
ps:多进程或多线程只能选择一个,不能同时开启
2.使用genvent做协程,解决高并发:

from genvent.wsgi import  WSGIServer
from genvent import monkey

monkey.patch_all()
app = Flask(__name__)
app.config.from_object(config)
api = Api(app)

db = DBInfo()
# db_old = DBInfo_old()
然后通过这种方式包装WSGIServer((address,port), app).serve_forever()
通过python code.py 的方法,来启动服务

3.通过Guicorn(with genvent)的形式来对app进行包装,来启动服务;
通过一下代码,来启动项目

# 启动命令
gunicorn -c gun.py thread_explore:app
其中gun.py是gunicorn的配置文件
thread_explore是服务的主程序
app是flask的app
gun.py的具体内容:


import os 
import gevent.monkey
gevent.monkey.patch_all()
import multiprocessing

# 服务地址(adderes:port) 
bind = 127.0.0.1;5000 
# 启动进程数量
workers = multiprocessing.cpu_count() * 2 +1
worker_class = 'gevent'
threads = 20
preload_app = True
reload = True
x_forwarded_for_header = 'X_FORWARDED-FOR'
ps:这里启动进程数量应该是根据CPU个数来确定的,最好是2 * CPU数 + 1
参考资料:
https://www.jianshu.com/p/a90775e33b52
https://www.cnblogs.com/lesliexong/p/9396850.html

对于一个网站而言,必须要有一定的承受并发的能力,request只是一个变量名,真正的实例对象是Request()。同一时刻会有多个请求,而每一个请求的请求信息极有可能是不同的。这就会造成我们实际发送过来的请求信息是不相同的。那么用一个变量request怎么代表不同用户的请求信息呢?

在这里插入图片描述
在这里插入图片描述
由于单线程是顺序执行的,只有处理完一个请求才能处理另一个请求,对于单线程来说,请求就像排队一样,请求进来之后,flask会实例化一个Request对象,然后用request来装载我们的请求信息,这个时候我们只有一个实例化的Request,所以啊,用request变量名是可以拿到我们要的请求信息的,所以request变量名总是会指向当前的请求,request就不会出现混乱。

多线程的请求,(对象是保存状态的地方)

但是我们并不知道到底有多少个请求会发生,那么有没有一种用一个变量来表示的所有的请求信息呢,有,字典

image.png
线程里有什么可以唯一确定一个线程呢,那就是线程的id号,可以作为key,在flask中就是采用的这种原理来解决的,这种用不同id号作为键,其实就是线程隔离,线程隔离只是一种思想,并不一定都是用字典实现,还可以用其他的方式实现。

  • 5
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值