Flask 线上高并发部署方案实现

目录

1、Flask默认多线程执行

2、使用gevent.pywsgi实现

3、是用uWSGI服务器实现

1、Flask默认多线程执行

前言:在Flask的较早版本中,默认并不支持多线程模式。然而,从Flask 0.9版本开始,引入了多线程模式的支持,并且在后续版本中逐渐成为默认设置。到了Flask 1.0版本,多线程模式已经被明确设定为默认行为。也就是说现在的Flask版本都是默认支持多线程的。

1、我们可以测试一下现在的Flask是不是以多线程的方式执行的。

【测试环境】

  • Flask:2.3.2
  • python:3.9.10

示例代码:

from flask import Flask

app = Flask(__name__)

@app.route('/')
def index():
    time.sleep(3)
    return "hello world"

if __name__ == '__main__':
    app.run(debug=True)
  • 我们进入到app.run()函数的源码查看,它的参数描述是怎么样的:

所以通过上面源码我们可以知道,现在是支持多线程的,且参数threaded默认True,也就是我们无法通过app.run()这个入口通过设置threaded为False来使用单线程,但是我们可以改源码。

1、现在我们通过JMeter来发起请求,看看是不是并发的。

  • 1、线程数设置为2

  • 2、HTTP请求配置如下:
  • 3、再添加一个结果查看树,来查看运行结果

  • 4、发送请求,查看结果

从上面结果可以看出两个线程的响应时间是3秒左右,可以得出确实是并发执行的。

2、那我们再看看把threaded参数改为False的情况

  • 1、同样的发送请求,查看结果

从上面结果可以看出线程1的响应时间是3秒左右,而线程2的响应时间是5.5左右,可见线程2是等待线程1执行完了再执行的,得出结论两个线程是串行的。

总结:对于比较小型的项目在生产环境中部署没有问题,实际应用中还是应该根据实际的项目,进行压力测试找到对应的系统容量;但是对于一些大型的项目,并发量比较高的场景,继续使用默认的配置就不合适了,这时候需要使用专门的Web服务器,如使用uWSgi,Nginx,Docker容器等部署方式解决高并发的问题。下面介绍一些常用的手段。

2、使用gevent.pywsgi实现

gevent.pywsgi.WSGIServer: 是 Gevent 库中的一个 WSGI 服务器实现,主要用于提供异步、协程支持的 Web 服务器功能。它与传统的 WSGI 服务器(如 werkzeug.serving.WSGIRequestHandler)不同,具有以下几个优势和适用场景:

作用与优势

1、异步处理请求:

  • Gevent 使用绿色线程(协程)来处理 I/O 操作,这使得它在处理大量并发请求时表现得更加高效。
  • 由于使用了事件驱动和协程模型,Gevent 可以在等待 I/O 操作完成时继续处理其他任务,从而减少了阻塞和等待时间。

2、高并发处理能力:

  • WSGIServer 可以处理大量的并发连接,而不会因为线程或进程的上下文切换而导致性能下降。这对于需要处理大量并发请求的应用非常有用,例如实时聊天应用或高流量的 API 端点。

3、轻量级

  • Gevent 的绿色线程比传统的操作系统线程要轻量,内存开销小,创建和销毁速度快。这使得它能够支持更多的并发任务而不消耗过多的资源。

4、简化协程编程:

  • Gevent 提供了简单的协程编程接口,可以很容易地使用 gevent.sleep() 等方法来编写异步代码,而不需要深入了解底层的异步 I/O 细节。

5、与现有代码兼容:

  • Gevent 可以与现有的同步代码兼容,通过猴子补丁(monkey patching)来让标准库的同步操作支持异步执行。这样,你可以在不完全重写代码的情况下引入异步特性。

使用场景
1、高并发 Web 应用:

  • 适用于需要处理大量并发请求的 Web 应用,如大型 API 服务或高流量的 Web 服务器。

2、实时应用:

  • 例如聊天应用、实时数据推送服务、在线游戏等,这些应用需要处理大量并发连接和实时通信。

3、长连接服务:

  • 对于需要保持长时间连接的服务,如 WebSocket 服务器,Gevent 的异步处理特性能够提供更好的性能和扩展性。

4、I/O 密集型任务:

  • 适用于那些主要由 I/O 操作(如网络请求、文件读取等)组成的应用,这类任务通常会受益于 Gevent 的异步处理能力。

代码示例:

from flask import Flask
from gevent import monkey
from gevent.pywsgi import WSGIServer

app = Flask(__name__)

@app.route('/')
def index():
    time.sleep(1)
    return "hello world"

monkey.patch_all()
if __name__ == '__main__':
    # app.run(debug=True)
    http_server = WSGIServer(('0.0.0.0', 5000), app)
    http_server.serve_forever()

做个简单压力测试看看相比于上面默认情况的性能情况:

  • 1、从下图可以看出使用了WSGIServer的明显QPS要比默认情况的要高;
  • 2、默认情况下的错误率达到了17.3%,使用了WSGIServer的错误率为0

综上所述:使用了WSGIServer的性能明显优于默认使用多线程的情况

3、是用uWSGI服务器实现

注意:uwsgi 主要是为 Unix/Linux 系统设计的,并不直接在 Windows 上支持。

1、安装uWSGI【注意:这里是在Linux环境下】:

pip install uwsgi

2、创建uWSGI配置文件:

你可以创建一个INI格式的配置文件,比如uwsgi.ini,并在其中指定Flask应用的设置。一个基本的配置文件示例如下:

[uwsgi]  
module = your_flask_app:app  
master = true  
processes = 4  
socket = 0.0.0.0:8000  
chmod-socket = 660  
vacuum = true  
die-on-term = true

在这个配置文件中:

  • module 指定了你的Flask应用的模块和变量名(通常是app)。
  • master 启用了主进程管理。
  • processes 设置了工作进程的数量。
  • socket 定义了uWSGI服务器监听的地址和端口。
  • chmod-socket 更改了socket的权限。
  • vacuum 在服务器关闭时清理socket和PID文件。
  • die-on-term 在接收到SIGTERM时立即退出。

3、启动uWSGI服务器:

使用uWSGI的配置文件启动服务器:

uwsgi --ini uwsgi.ini

这将根据uwsgi.ini文件中的设置启动uWSGI服务器,并运行你的Flask应用。

4、访问应用:
打开浏览器,访问http://localhost:8000(或者你在配置文件中指定的其他地址和端口),你应该能够看到你的Flask应用正在运行。

5、停止uWSGI服务器:

要停止uWSGI服务器,你可以使用以下命令(假设你知道uWSGI主进程的PID):

kill -SIGTERM <uwsgi_pid>

或者,如果你使用的是uwsgi --ini方式启动的,并且想要优雅地停止服务器,你可以发送SIGINT信号(通常是Ctrl+C)到你启动uWSGI的终端会话。

  • 19
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值