干货 | 一步步部署 Flask 应用
off999 2024-11-25 15:54 26 浏览 0 评论
Web 应用只有部署到服务器上才能被真正的使用,前面我们了解了用 Flask 开发 Web 应用,今天就来了解下,如何部署 Flask 应用。
与开发应用相比,部署应用,多些工作,如处理日志,服务器状态报告,项目打包等,接下来我们逐个了解下。
日志简介
在练习 Web 应用时,对日志的需求不高,程序问题可以在调试时看到。对于发布后的应用,没法实时查看运行信息,为了方便查错,需要将运行信息记录在日志里。
logging 模块是 Python 中 常用的日志处理模块,可以支持多种日志输出形式,如文本、邮件、日志服务器等,日志被分为 5 个等级,用于不同的情况,等级从低到高依次是:
- debug: 用于开发时调试
- info: 用于记录必要信息,以便了解程序运行状态
- warning:警告,适用于轻微的不影响系统运行的错误提示
- error: 错误,用于不能忽略的异常情况,计算错误,处理流程出错等
- critical: 严重错误,能会使应用挂掉或者不可恢复的严重问题
调用与等级名称相同的方法,就可以记录相应等级的日志,例如:
logger.debug('我是一个调试信息')
logger.warning('我是一个警告')等级除了用于日志分类外,还可以作为输出的过滤条件,例如只记录 warning 级以上的日志:
logger.setLevel(level = logging.WARNING)另外,还可以定义出入内容和样式,例如:
logging.basicConfig(format = '%(asctime)s - %(name)s - %(levelname)s - %(message)s')Flask 应用实例,带有日志实例 logger,使用很方便,例如:
from flask import Flask
app = Flask(__name__)
app.logger.info("Hello logger!") # 记录一个等级为 info 的日志在 blueprint 中,可以通过引入 current_app,即当前环境中的应用实例来得到 logger,如:
from flask import Blueprint
from flask import current_app
home_bp = Blueprint('home_bp', __name__)
@home_bp.route('/', methods=['GET', 'POST'])
def index():
current_app.logger.debug("进入首页视图函数处理")日志配置
应用需要部署在不同的环境中,一般后开发环境,测试环境,生成环境,不同的环境对日志记录的需求不同,例如开发环境,需要详细的日志,生产环境需要简洁的日志,且能将严重错误通知管理员等等。
在 《Flask 项目结构》一节中,我们使用 config 类为不同环境设置不同数据库连接,也可以为不同环境配置日志,例如,测试环境中,将等级为 info 及以上的日志输出到文件;生产环境中,将等级为 error 及以上的日志发送邮件:
# 测试环境
class TestingConfig(Config):
...
@classmethod
def init_app(cls, app):
super().init_app(app)
# 定义普通日志文件处理器
file_handler = logging.FileHandler(cls.LOG_FILENAME, mode='a', encoding='utf-8', delay=False)
# 设置记录等级
file_handler.setLevel(logging.INFOINFO)
app.logger.addHandler(file_handler)
# 生产环境
class ProductionConfig(Config):
...
@classmethod
def init_app(cls, app):
super().init_app(app)
# 定义邮件日志处理器
from logging.handlers import SMTPHandler
credentials = None
secure = None
# 邮件各种参数和配置来自基类 config
if getattr(cls, 'MAIL_USERNAME', None):
credentials = (cls.MAIL_USERNAME, cls.MAIL_PASSWORD)
if getattr(cls, 'MAIL_USE_TLS', None):
secure = ()
mail_handler = SMTPHandler(
mailhost=(cls.MAIL_SERVER, cls.MAIL_PORT),
fromaddr=cls.FLASKY_MAIL_SENDER,
toaddrs=[cls.FLASKY_ADMIN],
subject=cls.FLASKY_MAIL_SUBJECT_PREFIX + ' APPLICATION ERROR',
credentials=credentials,
secure=secure
)
# 设置发送等级
mail_handler.setLevel(logging.ERROR)
app.logger.addHandler(mail_handler)这样在代码中用调用日志记录方法,根据不同环境,日志就能被恰当的处理了。
项目打包
一般我们会为一个项目创建一个文件夹,由于 Python 项目不需要编译,开发完成后,将项目文件夹拷贝到服务上就可以完成了部署。
在应用开发过程中,我们会陆续安装一些依赖库或模块,部署后,必须安装这些被依赖,应用才能运行,要记住安装了哪些依赖不是件轻松的事
幸好 pip 提供了导出依赖模块名录的功能,可以一并导出依赖名录:
将环境中依赖的外部模块名录导入到 requirements.txt 中
pip frerze > requirements.txt在服务器上依据 requirements.txt 安装应用依赖
pip install -r requirements.txt我们要将 requirements.txt 作为项目代码的一部分。
值得注意的是 pip freeze 命令并不是针对特定项目的,即,导出的是所在 Python 环境中的 所有外部模块。
如果一个 Python 环境中,创建了两个不同的项目,各自有不同的依赖,那么导出来的依赖会时两个项目以来的合集,虽然对部署来说没有有问题,但安装没必要的依赖不算是好事。
因此创建项目时,为其创建一个独立的 Python 虚拟环境是个好编程习惯。
Web 服务器
虽然 Flask 提供了内置 Web 服务器,但是那种服务器是为开发打造的,达不到生产环境中需要的安全和效率,细心的同学会注意到,用 app.run() 或者 flask run 启动应用时,都会得到一句警告:Do not use the development server in a production environment.
那么在生产环境中,需要用生产专用 Web 服务器,比如 uWSGI、Gunicorn、Gevent 等等,
注意: 多数 Web 服务器只支持 Linux 操作系统,如果在 Windows 上部署,可以用 Apache + mod_wsgi 的方式
我们以 uWSGI 为例,了解下如何将 Flask 项目同 uWSGI 服务器关联。
安装 uWSGI
pip install uwsgi指定启动脚本
启动脚本就是创建应用实例所在的代码文件。
如果没有明确的应用实例定义,例如用了工厂方法,就需要单独创建一个应用实例,例如,创建一个 run.py 脚本:
from myflask import create_app
import os
env_dist = os.environ
config = env_dist.get('MY_FLASK_ENV', 'default')
app = create_app(config)- 从 myflask 项目中引入工厂方法 create_app
- 引入系统模块 os,为了读取环境变量
- 从环境变量 MY_FLASK_ENV 中读取 Flask 应用环境参数(环境变量名可随意),如果没有配置,默认值为 default,即为开发环境(具体配置参考: Flask 项目结构)
- 将 Flask 应用参数作为参数创建 Flask 应用实例
注意:在启动脚本中不要调用 run 方法,如果有需要放在 if __name__ == '__main__' 判断之下,否则 Web 服务器启动时,没创建一个应用实例(即运行一次启动脚本),就要启动一个 Flask 内置服务器,不仅浪费资源,还会出现端口冲突的错误
启动 uWSGI
uwsgi --http :9090 --wsgi-file run.py- –http: 通过 http 可访问,绑定端口为 9090
- –wsgi-file:指定启动脚本
一般我们会将启动设置写在配置文件中,一是有方便加入更多配置,二是方便管理,uWSGI 支持 ini、xml、yaml、json 格式的配置文件
以 ini 格式为例,创建uwsgi.ini:
[uwsgi]
# 开启主进程
master = true
# 使用 http 协议,绑定 5000 端口
http=:5000
# 应用主目录
chdir = /home/alisx/justdopython/flaskapps
# 应用启动脚本
wsgi-file=/home/alisx/justdopython/flaskapps/run.py
# 启动脚本中定义的 Flask 实例 变量名
callable=app
# 应用使用 Python 虚拟环境路径
home=/home/alisx/justdopython/flaskapps/.venv
# Web 服务器工作进程数
processes=4
# 每个进程中线程数
threads=2
# uWSGI 进程号存放文件,用户停止和关闭
pidfile =/home/alisx/justdopython/flaskapps/uwsgi.pid请注意 home 配置项,用来指定 Python 虚拟环境
启动 uWSGI :
uwsgi uwsgi.iniuWSGI 功能强大,配置丰富,这里只展示了基本的配置参数,想要了解更多可以参考文后 uWSGI 参考链接。
前置服务器
如果只是在服务器上部署一个 Flask 应用,可以跳过这里,用时再看不迟
尽管 uWSGI 功能强,性能高,完全可以胜任 Web 服务器,在实际部署中,我们还是想将其放在功能更全性能更好的专职前置 Web 服务器之后
这样做的好处是:
- 可以部署多个 Web 应用
- 不必争夺 80 端口
- 方便配置高并发和负载均衡
我们以现在流行从前置(反向代理)服务器 nginx 为例作
如果服务器上没有 nginx 需要先安装,以 ubuntu 为例:
sudo apt-get install nginx在 nginx 的虚拟服务器的 location 中指定后端服务器:
...
location / {
include uwsgi_params;
uwsgi_pass 127.0.0.1:9090;
}
...- include: 让 nginx 加载 uwsgi 功能模块
- uwsgi_pass: 指定用 uwsgi 协议的后端应用的地址和端口,此时 uWSGI 启动参数 http 要换位 socket: uwsgi --socket 127.0.0.1:9090
最后重启 nginx 就可以了向外提供我们的 Web 服务了。
关于 uWSGI 通信协议
前面 nginx 配置中,使用了 uwsgi_pass 指定后端服务器和通信协议
对于 uWSGI 而言,既可以指 Web 服务器,也可以指 uwsgi 通信协议(类似于 http 协议),是uWSGI 服务器其的默认通信协议,具有更好的性能和安全性,启动 uWSGI 服务器时,可以指定所使用的协议:
- --http: 会启动一个 http 进程,来接受 http 请求,该进程地位等同于 nginx,相当于前置服务器,http 进程使用 uwsgi 协议与 后端服务器通信
- --http-socket: 不启动 http 进程,需要前置服务器,且前置服务器不支持 uwsgi 协议的情况下使用
- --socket: 前置服务器支持 uwsgi 协议情况使用,例如用 nginx 作为前置服务器时
总结
今天介绍了如何部署一个 Flask 应用,从部署前的准备,一直到前置服务器的配置,其中以 uWSGI Web 服务器为例,介绍了如何将 Flask 应用绑定到生产服务器上,以及一些前置服务器的基本知识,希望对您发布自己的应用有一些帮助。
- 上一篇:用PyTorch部署模型
- 下一篇:害怕部署机器学习模型?这里有一篇手把手教程
相关推荐
- 苹果手机怎么设置定时关机(苹果手机怎么设置定时关机重启)
-
苹果手机可以设置定时关机,但无法设置定时开机。具体操作步骤如下:进入苹果手机自带的时钟。点击屏幕有下角的计时器。点击画面中间的计时结束启用选项。选择画面最下方的“停止播放”。之后再点击画面右上角的设定...
- 无线网wifi密码忘记了怎么办
-
忘记wifi密码后,可以在路由器后台查看。1.在浏览器的地址栏中,输入路由器上的管理地址,进入后台界面;2.在后台界面里,找到“无线设置”选项,点击它;3.在新界面里,点击wifi密码右侧的小眼睛图标...
-
- win7系统无法正常开机怎么办
-
解决方法如下1,出现无法启动的原因,要注意是开机启动不了,还是在进度条那里缓冲,过不去.如果是开机启动不了,那就要看一下内存条、电源等有没有问题?如果是在进度条那里,那就看下方的三种方法。2,第一种方法:1,开机按F8键.2,选择最近一次的...
-
2025-11-16 07:51 off999
- 现在装win7还需要激活吗(现在安装win7旗舰版还需密钥吗)
-
要激活 Windows7如果是预装在计算机中的,买来之后便不用激活,这里预装指的是在厂商那里。正版的Windows7安装到计算机中,有三十天的试用期,若要永久使用,就要使...
- 2025显卡性能排行榜天梯图(2020年显卡性能天梯图)
-
MacBookPro的显卡水平处于笔记本独立显卡Nvidia920M和940M之间。属于低端显卡级,玩玩LOL啥的还可以,其他的大型游戏就算了,MAC不适合打游戏。MacBookPro搭载的8代...
- 网络对时服务器(对时服务器端口)
-
对等网是指在网络中所有计算机的地位都是平等的,既是服务器也是客户机,所有计算机中安装的都是相同的单机操作系统如Windows98/XP/Vista/7等,它可以设置共享资源,但受连接数限制,一般是只允...
- 如何强制删除u盘文件(强制删除u盘内容)
-
1、电脑上下载安装安全杀毒类软件。2、使用强力卸载。3、找到U盘上需要卸载的文件,右击强力卸载可以卸载顽固型文件。4、被暂用的文件也删除不了可以退出U盘重启电脑重新开机插入U盘进行删除。5、不能删除的...
- directx官方下载win7(directx download)
-
点开始-----运行,输入dxdiag,回车后打开“DirectX诊断工具”窗口,进入“显示”选项卡,看一下是否启用了加速,没有的话,单击下面的“DirectX功能”项中的“启用”按钮,这样便打开了D...
- u盘视频无法播放怎么办(u盘上视频没办法播放)
-
解决办法:1.检查U盘存储格式是否为FAT32,如果不是,请将其格式化为FAT32; 2.检查U盘中视频文件是否损坏,如果有损坏文件,请尝试重新复制一份; 3.检查U盘中存储...
-
- 笔记本电脑无法正常启动怎么修复
-
1.可以解决。2.Windows未能启动可能是由于系统文件损坏、硬件故障或病毒感染等原因引起的。解决方法可以尝试使用Windows安全模式启动、修复启动、还原系统、重装系统等方法。3.如果以上方法都无法解决问题,可以考虑联系专业的电脑...
-
2025-11-16 04:03 off999
- 联想设置u盘为第一启动项(联想怎么设置u盘启动为第一启动项)
-
联想电脑设置u盘为第一启动项方法如下一、将电脑开机,开机瞬间按F2键进入bios设置界面二、在上面5个选项里找到boot选项,这里按键盘上左右键来移动三、这里利用键盘上下键选到USB选项,然后按F5/...
-
- 家用路由器哪个牌子最好信号最稳定
-
TP-LINK最好,信号最稳定。路由器是连接两个或多个网络的硬件设备,在网络间起网关的作用,是读取每一个数据包中的地址然后决定如何传送的专用智能性的网络设备。它能够理解不同的协议,例如某个局域网使用的以太网协议,因特网使用的TCP/IP协议...
-
2025-11-16 03:03 off999
- 安卓纯净版系统(安卓的纯净模式)
-
安卓系统有纯净模式的,安卓系统必须有纯净模式的,刷入纯净版系统可以去除一些预装的应用和系统自带软件,提高手机的运行速度和使用体验。但需要注意的是刷机有一定风险,请确保你已经备份好手机数据并了解安装风险...
- deepin系统怎么安装软件(deepin操作系统怎么安装软件)
-
deepin是一个基于Linux的操作系统,它默认不支持APK应用。要在deepin上安装APK应用,需要先安装一个Android模拟器,例如Anbox,然后从GooglePlayStore或其他...
-
- 下载app安装包(下载app安装包损坏)
-
1,没有刷机过的,可以在手机里面,找到系统自带的文件管理-(如图),2,点开后,可以直接看到文件分类,找到,安装包,点开,(如下图)3,即可看到手机里面的未安装APP;操作方法01如果是直接在浏览器上下载的软件,那就直接点开浏览器,然后点击...
-
2025-11-16 01:51 off999
欢迎 你 发表评论:
- 一周热门
-
-
抖音上好看的小姐姐,Python给你都下载了
-
全网最简单易懂!495页Python漫画教程,高清PDF版免费下载
-
Python 3.14 的 UUIDv6/v7/v8 上新,别再用 uuid4 () 啦!
-
python入门到脱坑 输入与输出—str()函数
-
飞牛NAS部署TVGate Docker项目,实现内网一键转发、代理、jx
-
宝塔面板如何添加免费waf防火墙?(宝塔面板开启https)
-
Python三目运算基础与进阶_python三目运算符判断三个变量
-
(新版)Python 分布式爬虫与 JS 逆向进阶实战吾爱分享
-
慕ke 前端工程师2024「完整」
-
失业程序员复习python笔记——条件与循环
-
- 最近发表
- 标签列表
-
- python计时 (73)
- python安装路径 (56)
- python类型转换 (93)
- python进度条 (67)
- python吧 (67)
- python的for循环 (65)
- python格式化字符串 (61)
- python静态方法 (57)
- python列表切片 (59)
- python面向对象编程 (60)
- python 代码加密 (65)
- python串口编程 (77)
- python封装 (57)
- python写入txt (66)
- python读取文件夹下所有文件 (59)
- python操作mysql数据库 (66)
- python获取列表的长度 (64)
- python接口 (63)
- python调用函数 (57)
- python多态 (60)
- python匿名函数 (59)
- python打印九九乘法表 (65)
- python赋值 (62)
- python异常 (69)
- python元祖 (57)
