flask项目快速搭建部署gunicorn+supervisor

一、安装flask

一般将需要的包以及版本写入文本批量安装,方便环境迁移
生成命令

pip freeze > requirement.txt

eg:

flask==1.1.2
requests==2.25.1

安装命令

pip install -r requirement.txt

二、创建项目

1. 创建项目ToolTest

flask是个轻量级框架,没有后台管理系统,也无默认配置sql连接设置等
需要用啥,再额外安装,说好听点就是, 更加自由、灵活,可扩展性强,第三方库的选择面广,开发时可以结合自己最喜欢用的轮子,也能结合最流行最强大的Python库 。所以这个框架的代码架构需要自己设计。可以直接新建git代码项目ToolTest。
flask项目快速搭建部署gunicorn+supervisor_第1张图片
刚开始创建完成的项目结构树:
flask项目快速搭建部署gunicorn+supervisor_第2张图片
app.py: 项⽬管理⽂件,通过它管理项⽬。

static: 存放静态文件

templates文件夹:用于放置html模板文件

2. 简单配置app.py

# -*- coding: utf-8 -*-
from flask import Flask, abort, request, jsonify

app = Flask(__name__)

@app.route('/')
def hello_world():
    return 'This is index!'
 
@app.route('/get_task/', methods=['GET'])
def get_task():
    tasks = [{'id': 1, 'info': "test1"}]
    if not request.args or 'id' not in request.args:
        # 没有指定id则返回全部
        return jsonify(tasks)
    else:
        task_id = request.args['id']
        task = filter(lambda t: t['id'] == int(task_id), tasks)
        res = list(task)
        return jsonify(res) if res else jsonify({'result': 'not found', 'status': False})

@app.route('/post_task/', methods=['POST'])
def add_task():
    if not request.json or 'id' not in request.json or 'info' not in request.json:
        abort(400)
    data = request.json
    return jsonify(dict(status=True, msg='请求成功...', result=data))
    
if  __name__ == '__main__':
    # setup_log(logging.DEBUG)
    # 将host设置为0.0.0.0,则外网用户也可以访问到这个服务
    app.run(host="0.0.0.0", port=8899, debug=True)
  

三、项目完善和启动

1. 日志配置

import logging
from logging.handlers import RotatingFileHandler

def setup_log(level):
    """
    :param level: 传入日志等级
    :return:
    """
    # 设置日志的的登记
    logging.basicConfig(level=level)
    # 创建日志记录器,设置日志的保存路径和每个日志的大小和日志的总大小
    file_log_handler = RotatingFileHandler("app.log", maxBytes=1024*1024*100, backupCount=100)
    # 创建日志记录格式,时间 日志等级 输出日志的文件名 行数 日志信息
    formatter = logging.Formatter("%(asctime)s %(levelname)s %(filename)s: %(lineno)d %(message)s")
    # 为日志记录器设置记录格式
    file_log_handler.setFormatter(formatter)
    # 为全局的日志工具对象(flaks app使用的)加载日志记录器
    logging.getLogger().addHandler(file_log_handler)

2. gunicorn启动命令以及supervisor配置

(1),gunicorn启动命令
gunicorn -w 2 -b 0.0.0.0:9090 app:app --preload
(2),supervisor安装(CentOS)
yum / pip install  supervisor

会和mysql一样有,守护进程 supervisord,和客户端 supervisorctl

(3),supervisor服务启动

生成启动配置

echo_supervisord_conf > /etc/supervisord.conf

增加include

[include]
files = /etc/supervisord.d/*.ini

启动命令

supervisord -c  /etc/supervisord.conf
(4),gunicorn启动配置/etc/supervisord.d/tool.ini
[program:tool_gunicorn]
command=/data/hy/ToolTest/venv/bin/gunicorn -w 2 -b 0.0.0.0:9090 app:app --preload
directory=/data/hy/ToolTest
user=root
startsecs=3
killasgroup=true
autostart=true
autorestart=true
stopasgroup=true
redirect_stderr=true
stdout_logfile_maxbytes=50MB
stdout_logfile_backups=10
stdout_logfile=/data/hy/ToolTest/gunicorn.log
(5),nginx服务器代理配置/etc/nginx/conf.d/tool.conf

(前端分离,编译结果的静态文件放在static路径就行,不做展开)

server {
    listen 80;
    server_name tool.cloudpivot.cn;
    server_name_in_redirect off;
    lingering_timeout 30s;
    # access_log /home/webserver/web/nginx.access.log;
    # error_log /home/webserver/web/nginx.error.log;

    location /static {
        alias /data/hy/ToolTest/static;
    }

    location ~ ^/favicon\.ico$ {
        root /data/hy/ToolTest/static/;
    }

    location / {
        proxy_pass http://127.0.0.1:9090;
        proxy_pass_header       Authorization;
        proxy_pass_header       WWW-Authenticate;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}
3. 常用命令
supervisorctl status     // 查看当前任务状态
supervisorctl restart  all / tool_gunicorn(program名称)    // 重启任务
supervisorctl   stop   all / tool_gunicorn(program名称)    // 停止任务

四、flash项目增强 ORM

1. db配置SQLAlchemy

(1) mysql连接配置db_config.py
# -*- coding: utf-8 -*-
# 单独创建配置文件

USERNAME = 'test'
PASSWORD = 'testuser'
HOSTNAME = '127.0.0.1'
PORT = '3306'
DATABASE = 'mock'

DB_URL = 'mysql+pymysql://{}:{}@{}:{}/{}'.format(USERNAME, PASSWORD, HOSTNAME, PORT, DATABASE)
SQLALCHEMY_DATABASE_URI = DB_URL
SQLALCHEMY_TRACK_MODIFICATIONS = False
(2) app加载配置
def create_app():
    app = Flask(__name__)
    setup_log(logging.DEBUG)
    app.config.from_object(db_config)
    # db.init_app(app)
    logging.info('Task is starting.....')
    return app

2. 安装依赖flask-migrate,flask-script

(1) db模型models.py
# -*- coding: utf-8 -*-
from flask_sqlalchemy import SQLAlchemy

db = SQLAlchemy()

# 定义用户
class User(db.Model):
    __talbe__ = 'users'
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(64), unique=True, index=True)
    #设置外键
    # role_id = db.Column(db.Integer, db.ForeignKey('roles.id'))

    def keys(self):
        return ['id', 'username']

    def __getitem__(self, item):
        return getattr(self, item)

    def __repr__(self):
        return 'User:'.format(self.username)

if __name__ == '__main__':
    print('This is db file')
(2) app加载配置
# -*- coding: utf-8 -*-
from conf import db_config
from models import User, db
from flask.json import JSONEncoder as _JSONEncoder
from datetime import date

# sql序列化
class JSONEncoder(_JSONEncoder):
    def default(self, o):
        if hasattr(o, 'keys') and hasattr(o, '__getitem__'):
            return dict(o)
        if isinstance(o, date):
            return o.strftime('%Y-%m-%d %H:%M:%S')
        return json.JSONEncoder.default(self, o)

class FlaskMy(Flask):
    json_encoder = JSONEncoder

# 配置初始化
def create_app():
    app = FlaskMy(__name__)
    setup_log(logging.DEBUG)
    app.config.from_object(db_config)
    db.init_app(app)
    logging.info('Task is starting.....')
    return app

app = create_app()

@app.route('/get_task_users/')
def hello_world():
    users = User.query.all()
    logging.info(users)
    # data_json = json.loads(json.dumps(users, cls=JSONEncoder))
    if not request.args or 'id' not in request.args:
        # 没有指定id则返回全部
        return jsonify(users)
    else:
        task_id = request.args['id']
        user = User.query.get(int(task_id))
    return jsonify(user) if user else jsonify({'result': 'not found', 'status': False})

if __name__ == '__main__':
    # 将host设置为0.0.0.0,则外网用户也可以访问到这个服务
    app.run(host="0.0.0.0", port=8899, debug=True)

具体增删查改可以找baidu(eg:https://blog.csdn.net/weixin_39537397/article/details/113895921)

3. manage管理配置

(1) migrate配置manage.py
# -*- coding: utf-8 -*-

from flask_migrate import Migrate, MigrateCommand
from flask_script import Manager
from app import app
from models import db

manage = Manager(app)
Migrate(app, db)
manage.add_command('db', MigrateCommand)

if __name__ == '__main__':
    manage.run()
(2) migrate常用同步命令
python manage.py db init      // 初始化  生成migrations文件夹 第一次执行就可以
python manage.py db migrate    // 生成迁移文件
python manage.py db upgrade    // 更新推送到sql
python manage.py db history    //  查询迁移版本
python manage.py db downgrade  // 回退版本

你可能感兴趣的:(flask,flask,python)