部署 Flask 应用

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介: 部署 Flask 应用

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 Blueprintfrom 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_appimport os
env_dist = os.environconfig = 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.ini


uWSGI 功能强大,配置丰富,这里只展示了基本的配置参数,想要了解更多可以参考文后 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 应用绑定到生产服务器上,以及一些前置服务器的基本知识,希望对您发布自己的应用有一些帮助。


最后,示例代码中提供了较为完整的例子,特别是通过 config 配置日志的部分,请您参考。

相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
目录
相关文章
|
21天前
|
监控 安全 测试技术
正确配置Flask以提高应用的安全性
正确配置Flask以提高应用的安全性
107 65
|
4月前
|
监控 测试技术 Docker
【步步惊心】Flask应用云端之旅:从本地调试到一键上线的终极秘籍!
【8月更文挑战第31天】本文详细介绍了将基于Flask框架的Web应用从本地开发环境部署到云平台的全过程。首先,通过示例代码展示了如何搭建本地环境并测试应用。接着,讲解了如何使用Docker构建生产环境镜像。最后,以Heroku为例,说明了如何将应用部署到云平台,并介绍了监控与维护的方法。通过本文的最佳实践,你可以轻松完成Flask应用的部署。
57 0
|
6月前
|
关系型数据库 MySQL 数据库
如何使用Python的Flask框架来构建一个简单的Web应用
如何使用Python的Flask框架来构建一个简单的Web应用
103 0
|
4月前
|
数据可视化 前端开发 数据挖掘
【优秀python大屏】基于python flask的广州历史天气数据应用与可视化大屏
本文介绍了一个基于Python Flask框架的广州历史天气数据应用与可视化大屏系统,该系统通过数据采集、处理、分析和可视化技术,提供了丰富的气象数据展示和决策支持,帮助用户快速了解和应对气象变化。
113 3
【优秀python大屏】基于python flask的广州历史天气数据应用与可视化大屏
|
4月前
|
存储 Linux 开发工具
【Azure App Service】本地Git部署Python Flask应用上云(Azure App Service For Linux)关键错误
【Azure App Service】本地Git部署Python Flask应用上云(Azure App Service For Linux)关键错误
|
4月前
|
Ubuntu Apache Python
如何在 Ubuntu VPS 上部署 Flask 应用程序
如何在 Ubuntu VPS 上部署 Flask 应用程序
48 1
|
4月前
|
存储 SQL 安全
【绝密攻略】Flask应用如何抵御黑客入侵?七大安全技巧助你构建固若金汤的Web防线!
【8月更文挑战第31天】安全性是Web应用开发中的关键部分。Flask作为一款轻量级且高度可定制的框架,虽灵活但需开发者确保应用安全。本文介绍如何通过具体措施加固Flask应用,包括更新依赖项、启用CSRF保护、使用HTTPS、安全存储密码、防止SQL注入及清理用户输入等。通过示例代码展示如何在实际开发中应用这些策略,帮助提升应用安全性,为用户提供更可靠的服务。
140 0
|
4月前
|
Python Windows 内存技术
【Azure 应用服务】Azure App Service (Windows) 使用Flask框架部署Python应用,如何在代码中访问静态文件呢?如何设置文件路径?是相对路径还是绝对路径呢?
【Azure 应用服务】Azure App Service (Windows) 使用Flask框架部署Python应用,如何在代码中访问静态文件呢?如何设置文件路径?是相对路径还是绝对路径呢?
|
5月前
|
存储 数据库 开发者
Flask中的蓝图与插件应用:构建模块化Web应用的利器
【7月更文挑战第19天】Flask蓝图和插件是构建模块化、可扩展和可维护Web应用的强大工具。蓝图允许你将应用分割成多个独立的部分,提高了代码的组织性和可重用性;而插件则为Flask应用提供了丰富的功能和社区支持,简化了开发过程。通过合理地使用蓝图和插件,你可以更加高效地开发出高质量的Web应用。
|
5月前
|
安全 开发者 Python
告别迷茫,Django/Flask深入应用指南,让你的Web梦想照进现实!
【7月更文挑战第13天】在Python Web开发中,Django和Flask框架各具特色。Django适合快速构建企业级应用,提供ORM、模板引擎等全面功能;而Flask轻量灵活,适用于小项目和原型开发。通过实例,了解如何启动Django和Flask的基本应用,从创建项目到运行服务器。选择框架应考虑项目需求和个人偏好,不断学习与实践将助你实现Web梦想。
55 1