804 字
4 分钟
Flask 的架构升级
渐进式搭建大型 Flask 应用
hello world
- 第一个 flask 应用(这个示例程序还需要
templates文件夹存放模板)
#!/usr/bin/python# -*- coding:utf-8 -*-from flask import Flaskapp = Flask(__name__)
@app.route('/')def index(): return render_template('index.html')
@app.route('/hello_world')def hello_world(): return 'Hello World!'
if __name__ == '__main__': app.run(host='0.0.0.0', port=80)使用python manage.py可以快速启动服务,但这种服务启动方式只适合开发环境测试,因为存在以下几个问题。
- flask 的自带服务器不支持多线程,用于多人的环境时很容易发生阻塞
- 服务因意外崩溃时不会自动重启
- 一旦你的 shell 关闭,你的服务将被停止。可以使用
nohup python manage.py &让服务在后台运行,或者挂一个 screenscreen -S pythonServer``python manage.py(这些方案只适用于快速搭建服务,生产环境应该使用服务器)
扩展
随着功能的增加,必须根据不同功能把程序拆分成文件,使用manage.py作为入口,在views.py处理路由,在errors.py中处理错误。项目结构修改为这样:
proj│ manage.py # 应用入口│├─app│ errors.py # 错误处理│ utils.py # 工具类│ views.py # 视图/路由│ __init__.py│├─templates # 模板文件夹│ about.html│ index.html│ login.html│└─static # 静态资源 app.js app.css查缺补漏
- 服务器 在生产环境使用 web 服务器。如 Nginx, Gunicorn, Tornado
- 管理服务 使用
supervisor,systemd等方式保证服务可靠运行 - 日志 为了快速定位 bug 以及溯源异常信息,需要使用日志模块输出日志而不是简单地使用
print('errorInfo')这种方式 debug, 常用的日志模块有log4j等 - 配置文件 方便切换开发环境和生产环境配置
- 测试
- 版本控制 开发必备,不多说,使用
Git吧,还建议使用贴近项目的工作流Git 工作流程
更大、更复杂
利用蓝图和 flask 强大的扩展能力,创建更大的项目
proj │-app/ │-templates/ │-static/ │-main/ │-__init__.py │-errors.py │-forms.py │-views.py │-auth/ │-__init__.py │-forms.py │-views.py │-__init__.py │-email.py │-models.py │-migrations/ │-tests/ │-__init__.py │-test*.py │-venv/ │-requirements.txt │-config.py │-manage.py应用细节
manage.py主入口
#!/usr/bin/python# -*- coding:utf-8 -*-import osfrom app import create_app
# 配置config_name = os.getenv('FLASK_CONFIG') or 'default'app = create_app(config_name)
# gunicorn -k gevent -w 8 -b 127.0.0.1:5000 manage:appif __name__ == '__main__': app.run(host='127.0.0.1', port=5000, debug=True)config.py配置文件
# -*- coding:utf-8 -*-
class Config(object): DEBUG = False TESTING = False DATABASE_URI = 'sqlite://:memory:'
@staticmethod def init_app(app): pass
class ProductionConfig(Config): DATABASE_URI = 'mysql://user@localhost/foo'
class DevelopmentConfig(Config): DEBUG = True
class TestingConfig(Config): TESTING = True
config={ 'dev':DevelopmentConfig, 'test':TestingConfig, 'prod':ProductionConfig, 'default':DevelopmentConfig }app/__init__.pyapp 工厂函数,根据不同环境配置初始化 app
#!/usr/bin/python# -*- coding:utf-8 -*-from flask import Flaskfrom config import config
def create_app(config_name): app=Flask(__name__)
# 加载配置 app.config.from_object(config[config_name]) config[config_name].init_app(app)
# 注册蓝图 from .main import main as main_blueprint app.register_blueprint(main_blueprint)
app.logger.debug('应用初始化完成') # DEBUG return appapp/main/__init__.py蓝图
# -*- coding:utf-8 -*-from flask import Blueprint
main = Blueprint('main', __name__)app/main/views.py蓝图的视图
# -*- coding:utf-8 -*-from flask import current_app as appfrom . import main
# 测试接口@main.route('/')def index(): app.logger.debug('SUCCESS') # DEBUG return 'Hello'其他
- 前后端分离
- 缓存
- 权限管理
- 访客分析
- 服务器监控
- 负载均衡
- CDN
- 分布式
- CICD
- Python venv 虚拟环境
- ……
最后
在搭建项目的时候根据自己项目实际情况,选择合适的架构才是正确的选择。