Flask学习笔记(2)应用部署

  本文将介绍如何部署Flask应用。
  部署Flask应用,主要是要运用多线程与多进程,提高接口的并发能力。我们以下面的Python代码(server.py)为例进行演示:

# -*- coding: utf-8 -*-
import time
import datetime
from flask import Flask, jsonifyapp = Flask(__name__)@app.route('/')
def hello_world():time.sleep(15)return 'Hello World!'@app.route('/index')
def beijing():return 'Shanghai'@app.route('/tell_time')
def tell_time():start_time_desc = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')time.sleep(5)end_time_desc = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')return jsonify({"start_time_desc": start_time_desc, "end_time_desc": end_time_desc})@app.route('/tell_time/<int:_id>', methods=['GET'])
def hello_index(_id):start_time_desc = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')time.sleep(5)end_time_desc = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')return jsonify({"id": _id, "start_time_desc": start_time_desc, "end_time_desc": end_time_desc})if __name__ == '__main__':app.run(host="0.0.0.0", port=5000, threaded=False)

在上述程序中,一共有四个API接口,描述如下:

  • 接口1:/, 功能为睡眠15s,然后输出Hello World!
  • 接口2:/index,功能为输出Shanghai
  • 接口3:/tell_time,功能为睡眠5s,输出开始、结束时间字典
  • 接口4:/tell_time/<int: _id>,以后缀_id区分url,功能同上一个接口。

  如果我们使用python3 server.py,那么该应用部署场景为单线程,即接口之间存在阻塞,也就是说,当我们访问一个耗时的接口的同时,再调用其它接口会被阻塞住,影响这些接口的正常调用。在这个例子中,当我们访问接口1的同时访问接口2,会存在阻塞,如下图:
接口阻塞
  接下来,我们将介绍三种Flask的部署方式,避免上述的接口阻塞问题,提高接口的并发能力。
  本文使用的Flask版本为2.3.2。

设置多线程或多进程

  在Flask的应用运行时,app.run()中可以接受两个参数,分别是threaded和processes,用于开启线程支持和进程支持。

  1. threaded : 多线程支持,默认为True,即开启多线程;
  2. processes:进程数量,默认为1.

在Flask版本2.3.2中,threaded默认值为True,但在较早的版本中默认值为False。
  我们在app.run()中将threaded=True或者不写,则该应用采用多线程部署,代码调整如下:

	app.run(host="0.0.0.0", port=5000, threaded=True)

此时,当我们访问接口1的同时访问接口2,不会存在阻塞,如下图:
多线程部署
  注意,这里千万不要用浏览器来做实验,两次请求都是相同的url,浏览器可能会进行优化导致两次请求使用相同的socket连接。
  我们以接口3为例,在Chrome浏览器中同时访问http://127.0.0.1:5000/tell_time,结果如下:
使用Chrome浏览器,接口仍存在阻塞
但当我们换成接口4时,接口就不存在阻塞了,如下图:
Chrome浏览器,接口不存在阻塞

使用gevent模块

  gevent是一种协程的Python网络库,基于greenlet封装了libevent事件循环的高层同步API。它让我们在不改变编程习惯的同时,用同步的方式写异步I/O的代码。使用gevent编程性能确实要比用传统的线程高。后续我们有机会再单独介绍gevent模块。
  在Flask的部署场景中,在引入gevent 前,可以在程序最开始执行的位置引入猴子补丁gevent.monkey,这能修改 python默认的 IO 行为,让标准库变成协作式的 API。示例代码如下:

from gevent import pywsgi
from gevent import monkey
monkey.patch_all()  # 打上猴子补丁from flask import flask
...if __name__ == '__main__':app.debug = Trueserver = pywsgi.WSGIServer(('127.0.0.1', 5000), app)server.serve_forever()

使用gunicorn模块

  Gunicorn是一个Python的 WSGI HTTP 服务器。它所在的位置通常是在反向代理(如 Nginx)或者负载均衡(如 AWS ELB)和一个 web 应用(比如 Django或者Flask)之间。它是一个移植自Ruby的Unicorn项目的pre-fork worker模型,既支持eventlet也支持greenlet。
  通常,我们在使用gunicorn模块部署Flask应用时,会结合配置文件一起使用,比如下面的gunicorn配置文件(gunicorn_config.py):

# -*- coding: utf-8 -*-
# gunicorn + gevent 的配置文件
import multiprocessingtimeout = 600
debug = False# 预加载资源
preload_app = True
# 绑定 ip + 端口
bind = "0.0.0.0:5000"
# 进程数 = cup数量 * 2 + 1
# workers = multiprocessing.cpu_count() * 2 + 1
workers = 2# 线程数 = cup数量 * 2
# threads = multiprocessing.cpu_count() * 2
threads = 5# 等待队列最大长度,超过这个长度的链接将被拒绝连接
backlog = 2048# 工作模式--协程
worker_class = "gevent"# 最大客户客户端并发数量,对使用线程和协程的worker的工作有影响
# 服务器配置设置的值  1200:中小型项目  上万并发: 中大型
# 服务器硬件:宽带+数据库+内存
# 服务器的架构:集群 主从
worker_connections = 1200# 进程名称
proc_name = 'gunicorn.pid'
# 进程pid记录文件
pidfile = 'app_run.log'
# 日志等级
loglevel = 'debug'
# 日志文件名
logfile = 'debug.log'
# 访问记录
accesslog = 'access.log'
# 访问记录格式
access_log_format = '%(h)s %(t)s %(U)s %(q)s'

部署的命令为:gunicorn -c gunicorn_config.py server:app。该部署方式采用了多线程+多进程的方式,同时配置可调节,适用于高并发的场景。

压力测试

  我们对接口/tell_time的两种部署方式:采用多线程部署(方式一)和采用gunicorn部署(方式三)进行压力测试,使用工具为jmeter。
  在jmeter中,我们设置1秒钟发送5000个用户请求/tell_time接口,轮次为1,如下图:
Jmeter设置
  使用第一种部署方式(在app.run()中设置threaded为True),测试结果如下:

  使用第三种部署方式(使用gunicorn,CPU核数为4,设置workers=9, threads=8),测试结果如下:

可以看到,HTTP请求的成功数量是第三种部署方式较多,吞吐量也较多,由此可见,第三种部署方式的高并发性能优于第一种部署方式。

总结

  本文主要介绍了三种常见的高并发部署Flask应用的方式,希望读者能在实际工作中多多实践,提升工作技能~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/13101.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

密码学学习笔记(五):Hash Functions - 哈希函数1

简介 什么是密码学中的哈希函数&#xff1f; 哈希函数是一种快速算法&#xff0c;它接受任何长度的输入&#xff0c;并产生一个固定长度的随机输出&#xff0c;称为摘要(digest)&#xff0c;比如&#xff1a; MD4, MD5: 128-bit output (broken) •SHA-1: 160-bit output (b…

基于redhat发行版mysql8.0的卸载与重装mysql5.7

文章目录 一、软件的选择与下载二、卸载mysql8.01.查看my.cnf中的部署信息2.卸载mysql8.03.卸载完毕安装包后删除相关数据 三、mysql5.7的安装1.解压安装包2.初始化mysql数据库3.修改root密码 四、安装mysql5.7客户端附&#xff1a;创建数据库以及用户 本次案例是卸载mysql8.0然…

2个好用的ftp和ssh工具推介

为什么不用xshell和xftp,是不好用吗&#xff1f;xshell和xftp虽然好用&#xff0c;而且也有免费版&#xff0c;但是&#xff0c;一个方面使用有限制&#xff0c;再就是你看见这个报错的弹窗烦不烦&#xff1f; 一、ssh工具-WindTerm WindTerm[1] 是一个基于 C 开发的开源终端模…

使用大型语言模(LLM)构建系统(七):评估1

今天我学习了DeepLearning.AI的 Building Systems with LLM 的在线课程&#xff0c;我想和大家一起分享一下该门课程的一些主要内容。之前我们已经学习了下面这些知识&#xff1a; 使用大型语言模(LLM)构建系统(一)&#xff1a;分类使用大型语言模(LLM)构建系统(二):内容审核、…

3d渲染画面变形怎么办?

在用3dmax渲染图片时有时会遇到画面变形的情况&#xff0c;这个是什么原因呢&#xff1f;今天我们就来看看吧。 首先我们来看下变形的具体情况&#xff0c;再分析原因。可以看到整个画面都畸变了&#xff0c;呈现出上下拉伸的情况&#xff0c;能造成这个效果的&#xff0c;只有…

error: exportArchive: No signing certificate \“Mac Development\“ found

error: exportArchive: No signing certificate “Mac Development” found UNIAPP打包又遇到这个问题了, 证书过期续期的时候又遇到这个问题了(之前遇到过解决了,时间长忘了),记录一下,报错信息 error: exportArchive: No signing certificate \"Mac Development\"…

【毕业设计】爱琴海——基于HTML5的婚庆用品商城网页设计

一、内容简介 (一)背景与意义 “婚俗”是指结婚的风俗&#xff0c;各国各族人民按照自己的习俗&#xff0c;举行各具特色的婚礼&#xff0c;具有各自浓厚的民族独特风采。婚俗元素在是中国婚俗文化的媒介&#xff0c;承载了中华儿女对幸福和吉祥的追求。在中国婚俗文化的发展过…

基于CTFTraining在CTFd部署Web题目

下面要讲的东西是基于你已经使用CTFd搭建好了这样一个简易靶场 因为misc、crypto这些题目一般都是放附件&#xff0c;这个比较简单&#xff0c;直接做好在前端放上去就行 而部署web的题&#xff0c;我们需要在终端进行&#xff0c;这里我们使用docker-compose来进行部署 至于…

[MMDetection]COCO数据集可视化验证

在使用MMDetection训练之前&#xff0c;需要对图像进行可视化验证&#xff0c;验证数据和标签是否对齐。 # 数据集可视化 import os import matplotlib.pyplot as plt from PIL import Imageoriginal_images [] images [] texts [] plt.figure(figsize(16,12))image_paths …

惊艳!全网首份“架构师成长笔记”GitHub狂澜9000星

其实架构师是需要一个相对而言对架构师友善的环境。第一&#xff0c;架构师到底需要什么&#xff1f;一个架构师要成长&#xff0c;首先他需要信任&#xff0c;第二他需要授权&#xff0c;第三他需要时间&#xff0c;第四他需要资源&#xff0c;少一样都很难开展工作。如果一个…

SpringBoot 配置文件:什么时配置文件?配置文件能干什么?

文章目录 &#x1f387;前言1.配置文件的格式2. properties配置文件说明2.1 properties基本语法2.2 读取配置文件 3. yml 配置文件说明3.1 yml 基本语法 4.properties与yml 对比 &#x1f387;前言 学习一个东西&#xff0c;我们先要知道它有什么用处。整个项目中所有重要的数…

落地 DevOps,探索高效研发运营一体化解决方案

前言与概述 伴随着企业业务的快速发展&#xff0c;为了支撑业务发展&#xff0c;提高 IT 对业务的支撑能力建设。在研发工程协同方面&#xff0c;希望加强代码管理&#xff0c;实现持续构建、自动化测试、自动化部署、自动化运维&#xff0c;同时加强产品的安全和质量管理&…