Python3 Flask+nginx+Gunicorn部署(上)

这次主要是记录flask在python3 环境结合nginx +gunicorn在服务器上进行项目的部署

(一)运行环境

  • 虚拟机centos7
  • python3 环境
  • nginx
  • gunicorn
  • virtualenv

难点:nginx gunicorn的安装配置

(二)nginx、gunicorn简介

Nginx是一款轻量级的Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,并在一个BSD-like 协议下发行。其特点是占有内存少,并发能力强,事实上nginx的并发能力确实在同类型的网页服务器中表现较好,中国大陆使用nginx网站用户有:百度、京东、新浪、网易、腾讯、淘宝等

gunicorn是一个python Wsgi http server,只支持在Unix系统上运行,来源于Ruby的unicorn项目。Gunicorn使用prefork master-worker模型(在gunicorn中,master被称为arbiter),能够与各种wsgi web框架协作。

(三)软件安装

(1)首先安装gunicorn

直接使用命令:pip install gunicorn

(2) 将gunicorn 加入到app.run()中,

这里我在路径为:/home/flaskproject/flaskweb 下新建一个myweb.py 作为入口函数
代码为:

from flask import Flask
app = Flask(__name__)
@app.route('/')
def index():
    return 'hello world'
if __name__ == '__main__':
    from werkzeug.contrib.fixers import ProxyFix
    app.wsgi_app = ProxyFix(app.wsgi_app)
    app.run(

未分类

(3)用命令启动gunicorn

在myweb.py路径下,一定要记住是当前路径下!!
方式一:

gunicorn myweb:app

未分类

python 虚拟环境的安装:

pip install virtualenv 

然后一顿骚操作:

mkdir flaskproject

cd flaskproject

virtualenv flaskprojectenv

然后进行激活:

source flaskprojectenv/bin/activate

正如下图一样的骚操作,之前我也是很少用虚拟环境的,现在感觉虚拟环境并没有那么神秘,因为以前是很拒绝,不会用,不过这次是会用了,

退出虚拟环境的命令是:deactivate(这里我只是说一下)

未分类

这时候我们本地服务器看一下是否运行起来(已经有hello world):

[root@localhost flaskproject]# curl http://127.0.0.1:8000
hello world[root@localhost flaskproject]# 

ctrl + c 停掉当前环境,我们使用第二种方式试一下
专门为处理高并发则要开多个进程和修改监听端口方式:

gunicorn -w 4 -b 127.0.0.1:8000 入口文件名:app

如下代码:

(flaskprojectenv) [admin@localhost flaskweb]$ gunicorn -w 4 -b 127.0.0.1:8000 myweb:app
[2018-05-28 10:57:11 -0400] [1813] [INFO] Starting gunicorn 19.8.1
[2018-05-28 10:57:11 -0400] [1813] [INFO] Listening at: http://127.0.0.1:8000 (1813)
[2018-05-28 10:57:11 -0400] [1813] [INFO] Using worker: sync
[2018-05-28 10:57:11 -0400] [1816] [INFO] Booting worker with pid: 1816
[2018-05-28 10:57:11 -0400] [1817] [INFO] Booting worker with pid: 1817
[2018-05-28 10:57:11 -0400] [1819] [INFO] Booting worker with pid: 1819
[2018-05-28 10:57:11 -0400] [1821] [INFO] Booting worker with pid: 1821

本地服务器已经运行了,但是我们远程并不能进行访问(win10访问虚拟机)

未分类

说明端口号没有打开,这时候我们需要把防火墙,端口号什么的都进行设置一下,可以看一下这篇博客:linux下nginx首次安装远程无法访问

主要是两个命令:

[root@localhost nginx-1.12.1] systemctl stop firewalld
[root@localhost nginx-1.12.1] systemctl stop iptalbes

接下来:我们进行nginx的配置安装与gunicorn的相结合并进行部署。

python3 flask中SQLAlchemy创建表的简单介绍

在flask的SQLAlchemy中创建表,也是存在 ForeignKey(一对多) 与 ManyToMany(多对多) 的存在,以下是在models中单表、一对多、多对多的创建方式。

models.py代码如下:

import datetime
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column,Integer,String,Text,ForeignKey,DateTime,UniqueConstraint,Index
from sqlalchemy.orm import relationship

Base = declarative_base()

# 【单表创建的示例】
class Users(Base):
    __tablename__ = 'users'
    id = Column(Integer,primary_key=True)
    name = Column(String(32),index=True)
    age = Column(Integer,default=18)
    email = Column(String(32),unique=True)  # unique = True 表示该字段中的值唯一
    ctime = Column(DateTime,default=datetime.datetime.now())
    extra = Column(Text,nullable=True)

    __table_args__ = (
        UniqueConstraint('id','name',name='unique_id_name'),  # 创建表中id和name字段的唯一索引,最后一个参数是索引名,注意前面要写name=
        Index('ix_name_email','name','email')   # 创建表中多个字段的普通索引
    )


# 【一对多示例】
# 表1
class Hobby(Base):
    __tablename__ = 'hobby'
    id = Column(Integer,primary_key=True)
    caption = Column(String(10),nullable=False,default='台球')

# 表2
class Person(Base):
    __tablename__ = 'person'
    nid = Column(Integer,primary_key=True)
    name = Column(String(32),index=True,nullable=True)
    # 创建一对多的关系
    hobby_id = Column(Integer,ForeignKey('hobby.id'))

    #   此字段不在表中生成,只是为了方便调用Hooby表;
    # 正向查找时可以直接用“hobby.”调用“Hobby”表中的字段。
    # 在hobby表中反向查找时可以用“pers”调用“Person”表中的字段。
    hobby = relationship('Hobby',backref='pers')


# 【多对多示例】
# 两表的关系表
class Server2Group(Base):
    __tablename__ = 'server2group'
    id = Column(Integer,primary_key=True,autoincrement=True)
    server_id = Column(Integer,ForeignKey('server.id'))
    group_id = Column(Integer,ForeignKey('group.id'))



# 表1
class Server(Base):
    __tablename__ = 'server'
    id = Column(Integer,primary_key=True,autoincrement=True)
    hostname = Column(String(15),nullable=True,unique=True)

    # 用于方便查找的标识
    groups = relationship('Group',secondary='server2group',backref='servers')

# 表2
class Group(Base):
    __tablename__ = 'group'
    id = Column(Integer,primary_key=True,autoincrement=True)
    name = Column(String(32),nullable=True,unique=True)


def create_all():
    """
        根据类创建数据库表
        :return:
        """
    engine = create_engine(
        "mysql+pymysql://root:[email protected]:3306/test0621?charset=utf8",
        max_overflow=0,  # 超过连接池大小外最多创建的连接
        pool_size=5,  # 连接池大小
        pool_timeout=30,  # 池中没有线程最多等待的时间,否则报错
        pool_recycle=-1  # 多久之后对线程池中的线程进行一次连接的回收(重置)
    )

    Base.metadata.create_all(engine)


def drop_db():
    """
    根据类删除数据库表
    :return:
    """
    engine = create_engine(
        "mysql+pymysql://root:[email protected]:3306/test0621?charset=utf8",
        max_overflow=0,  # 超过连接池大小外最多创建的连接
        pool_size=5,  # 连接池大小
        pool_timeout=30,  # 池中没有线程最多等待的时间,否则报错
        pool_recycle=-1  # 多久之后对线程池中的线程进行一次连接的回收(重置)
    )

    Base.metadata.drop_all(engine)


if __name__ == '__main__':
    drop_db()
    create_all()

Ubuntu部署python3-flask-nginx-uwsgi-supervisor完美

安装虚拟环境

$ pip install virtualenv
$ pip install virtualenvwrapper

把虚拟机环境添加环境变量中

这个最好find / -name virtualenvwrapper.sh 看下位置

$ vi .bashrc
if [ -f /usr/local/bin/virtualenvwrapper.sh ]; then
    export WORKON_HOME=$HOME/.virtualenvs
    source /usr/local/bin/virtualenvwrapper.sh
fi

为flask项目创建一个虚拟环境

$ mkvirtualenv --python=python3 flask  #flask这个名字可以按自己需求修改,我项目是需要python3。所以选择 --python=python3,如果需要python2可以不加这个。
$ deactivate  #安装完虚拟环境后,先退出这个虚拟环境。

安装mysql数据库,安装数据这个没什么好提的网上有很多详细教程

$ apt install mysql-server mysql-client
$ apt install libmysqld-dev

安装nginx

$ apt install nginx   #这个安装也比较简单

安装supervisor

需要是python2 暂时不支持python3,这里有时候会遇到坑。pip install –upgrade pip 看看现在pip是什么版本。

$ vi /usr/local/bin/pip #如果发现pip是python3,不要慌用这个命令把第一行的python3修改python2 即可,如果是python2就无视这步
$ pip install supervisor #安装supervisor

安装uwsgi

需要注意flask项目需要的环境 选择python3 还是python2.

这个我的项目是python3,如果是python2创建虚拟环境就用python2。具体可以看上面的为项目创建虚拟环境

$ workon flask  #进入虚拟环境
$ pip install uwsgi  #这个之前装到虚拟环境里面

如果出现Failed building wheel for uwsgi执行下面语句

apt-get install python3-dev

项目文件创建

这个按自己需要创建,也可以按我这个创建

$ mkdir /www  #根目录下创建一个www
$ mkdir /www/wwwroot  #这个项目文件全部放这个理
$ mkdir /www/log #日志文件

uwsgi配置

uwsgi配置好后,可以测试下

uwsgi配置路径:/www/wwwroot/uwsgi.ini

$ cd /www/wwwroot #可以放到项目,按自己需求都可以
$ vi uwsgi.ini   #创建一个uwsgi配置文件

[uwsgi]
# 当前这个项目的路径
chdir           = /www/wwwroot
# 模块
module          = manage   #启动文件名 个人理解
# python的虚拟环境
home            = /root/.virtualenvs/python3
# 是否启用mater模式
master          = true
# 进程数
processes       = 2
# socket文件地址
socket          = /www/wwwroot/uwsgi.sock
# wsgi文件
wsgi-file       = /www/wwwroot/manage.py  #启动文件
# wsgi文件中的app变量
callable        = app
# socket文件的权限
chmod-socket    = 666

配置好后可以运行起来测试是否成功

$ workon python3 #进入虚拟环境
$ uwsgi --uid www --gid www --ini /www/wwwroot/uwsgi.ini #这个可以指定用户和用户组权限,也可以不指定。测试没能正常打开项目就往下面步骤继续配置

nginx配置

$ cd /etc/nginx/sites-enabled/   #切换到nginx默认配置目录
$ mv default default.bak #修改配置前先备份下配置
$ vi default
server {
        listen 80;
        server_name www.xxoo.com;
        charset utf-8;
        client_max_body_size 75M;
        access_log /www/log/xxoo.access.log;
        error_log /www/log/xxoo.error.log;

        location / {
                include uwsgi_params;
                uwsgi_pass unix:/www/wwwroot/uwsgi.sock; #这个.sock文件一定要和uwsgi配置中一样
        }
}

修改nginx配置/etc/nginx/nginx.conf ,第一行user www www ; Nginx用户及组:用户 组 按自己需求配置。详细配置参数网上自己找

supervisor配置

supervisor配置路径:/www/wwwroot/supervisor.conf

$ vi supervisor.conf
[program:python]  #这个python可以按自己需求写
# supervisor执行的命令
command=/root/.virtualenvs/py3-zqcms/bin/uwsgi --uid www --gid www --ini /www/wwwroot/uwsgi.ini
# 项目的目录
directory = /www/wwwroot
# 开始的时候等待多少秒
startsecs= 5   #按自己需求写
# 停止的时候等待多少秒
stopwaitsecs= 5 #按自己需求写
# 自动开始
autostart=true
# 程序挂了后自动重启
autorestart=true
# 输出的log文件
stdout_logfile=/www/log/supervisord.log
# 输出的错误文件
stderr_logfile=/www/log/supervisorderr.log

[supervisord]
# log的级别
loglevel=info

配置好后就运行

$ supervisord -c /www/wwwroot/supervisor.conf  #执行的时候注意是在python2环境

如何终止多余 Supervisor 进程?

$ ps -ef | grep supervisor  #查看
$ kill 4012 #结束进程

注意:uwsgi nginx supervisor我只是简单配置了下,各位可以按需求配置。详细配置参数网上有很多资料。哪里写错,可以留言告诉我。