在Centos7.X(宝塔环境)下实现Flask项目的部署和运行监控
  • 分类:Python
  • 发表:2019-10-14
  • 围观(13,234)
  • 评论(0)

总的来说学习Flask也有一年多了,学的都是Flask的开发,到现在也有能力开发出中小型的后端项目了。但是所有的教程都没有告诉我到底如何在服务器上部署我们的Flask项目,我总不可能在服务器上用Flask自带的web服务器部署项目吧?这是极其不理智的,所以我查阅了很多资料,试图能够掌握Flask项目在服务器部署的具体方法。

本文章主要分文三个章节,即:①.宝塔环境的搭建②.Python环境的搭建③.项目的部署和配置。文章会尽量详细的介绍每个过程的步骤,不光是让大家看懂,同样也是方便以后自己查阅。为了方便教程的进行,我用Flask完成了一个简单的项目-fitstflask,项目只有一个简单的页面,是我写的一首英文小诗,看到的朋友可以点评一下

项目展示

项目目录结构:
    /firstflask:
        app.py(项目启动文件,主文件目录)
        requirements.txt(项目依赖的软件包)
        /static(静态文件目录)
        /templates(页面模板目录)
        /firstflask_venv(项目的虚拟环境)

本文章主要实现的是基于Centos7.x的环境,实现基于Pyenv+Gunicorn+Gevent+Nginx+Supervisor的Flask项目部署。包括服务器环境的安装,Python环境的配置,Gunicorn的简单配置,Nginx的反向代理配置,Supervisor实现Flask项目的自动启动和项目监控。

宝塔环境搭建

项目是在宝塔环境下搭建的,因为毕竟Linux并不是很熟练,宝塔提供的面板环境可以帮助我们很好的搭建相应的项目环境,例如:Nginx的安装,MySQL的安装,Supervisor的安装...使用宝塔可以简化我们的安装步骤,而且可视化的监控后台也极大的方便了文件配置。并且宝塔提供了Python项目管理器这个软件,可以快速方便的帮助我们部署Flask项目,但是这个软件只支持Centos7.x所以本教程并没有选择用软件部署,而是手动部署。所以本教程同样适用于Debian,Ubuntu...等一系列的系统。

安装宝塔可以参照宝塔官网的文章:宝塔Linux面板安装教程。选择对应的Linux版本的一键安装脚本,全程自动化安装,只需要根据提示操作即可。安装成功之后还需要登录宝塔进行一系列的初始化配置,方便我们下次登录。(PS:阿里云的用户需要进实例安全组把所有的端口打开,把端口权限控制交给宝塔,否则服务会有莫名的错误,其他云服务商同理)。

安装宝塔之后我们要安装相应的服务支持,方便我们后期项目的部署,下面简单介绍一下需要安装的软件:

部份运行环境展示

1.Nginx:轻量级Web服务器,占有内存少,并发能力强,用来处理web请求和反向代理(必装)
2.MySQL:开源免费的关系型数据库,根据自己服务器配置选择版本安装(必装)
3.PureFTPd:是一款专注于程序健壮和软件安全的免费FTP服务器软件(选装)
4.Supervisor:一个Python开发的通用的进程管理程序,用于启动和监控Flask程序(必装)
5.Redis:Redis 是一个高性能的key-value数据库,可以用来处理Flask缓存(选装

宝塔安装运行环境的速度有点慢,因为是编译安装。不同的Linux环境可能也会有奇形怪状的错误,一般卸载重装都能解决,实在不能解决可以好好利用下手上的搜索引擎或者去论坛发帖提问。

Python环境的搭建

每一个项目都要有属于自己相对隔离的虚拟环境,在之前的文章我们介绍过用Pyenv实现虚拟环境的搭建:在Centos中安装并使用Pyenv,一个强大的Python版本管理工具。同样的本文的Flask项目的搭建环境也是基于Pyenv。这里不懂得同学可以倒回之前的文章再熟悉一下。

下面介绍如何使用Pyenv安装虚拟环境,我的习惯是把虚拟环境安装到各个项目的根路径下,用xxx_venv作为虚拟环境的目录,这里同样也是基于这个。不懂的朋友看着会有点麻烦,可以直接使用pyenv virtualenv工具安装虚拟环境,这里介绍的是我的方法,进行前需要将项目源码上传至项目根目录。

# 项目基于Python 3.7.4,先安装相应的Python
root@raspberrypi:~# pyenv install 3.7.4
# 将全局Python版本改为3.7.4
root@raspberrypi:~# pyenv global 3.7.4
# 安装virtulenv支持
root@raspberrypi:~# pip install virtulenv


# 进入项目根目录
root@raspberrypi:~# cd /home/pi/python/firstflask
# 创建项目的虚拟环境
root@raspberrypi:/home/pi/python/firstflask# virtulenv firstflask_venv
# 通过创建软连接将虚拟环境交给pyenv管理
root@raspberrypi:/home/pi/python/firstflask# ln -s /home/pi/python/firstflask/firstflask_venv /root/.pyenv/versions/firstflask_venv
# 更改当前目录的虚拟为firstflask_venv,这一步执行完之后可以使用pip list查看环境是否安装成功
root@raspberrypi:/home/pi/python/firstflask# pyenv local firstflask_venv

# 使用pip安装requirements.txt的支持库
root@raspberrypi:/home/pi/python/firstflask# pip install -r requirements.txt

requirements.txt

除了基础的Flask需要安装,gevent,gevent-websocket,gunicorn都是必须安装的。他们的作用是提供WSGI容器,同时给项目添加websocket支持。进行到这里我们在控制台执行flask run之后就可以看到熟悉的flask运行命令行啦。

可以直观的看到Flask项目已经成功运行,但是我们现在仍然无法直接访问站点,因为我们只完成了Flask的配置还没有完成Nginx的配置,所以请求无法成功的被转发给Flask处理。同时Flask给了一个warning,提示说项目是在生产环境运行,但是使用的是Flask自带的开发服务器。我们要把服务器换成Gunicorn就可以解决这个警告。这些都是我们在下一部分需要解决的问题。

项目的部署和配置

首先我们要进心Nginx的配置,下面的步骤将全部在宝塔面板内进行。首先我们要在宝塔内创建一个网站,这个网站服务于我们的Flask项目。由于我是在本地环境做的配置所以用的是局域网IP作为网站域名,如果是外网环境请输入正确的域名。

创建好网站之后我们需要配置一下Nginx代理,将流入的请求转发给Flask处理。同时对于静态文件可以交给Nginx直接处理,这样可以降低Flask的负载,避免Flask压力过大导致的请求过慢等问题。首先声明我对Nginx之后简单的了解,所有的配置我都是通过搜索引擎和查阅书籍得出的。基于不同场景的项目Nginx应该有不同的配置,如果有能力可以仔细研究一下Nginx的配置。


首先要删除Nginx默认的静态文件配置,然后添加相应的三条规则。三条规则分别作用是代理Flask的静态文件的文件夹,使访问静态文件的请求由Nginx代理;代理favcion.ico的请求;转发动态秦请求,让Flask处理来自页面的动态请求。这样配置完成我们在服务器运行Flask服务之后就可以通过访问域名查看到相应的页面效果了。

location /static {
    alias /home/pi/python/firstflask/app/static;
    expires 30d;
    error_log off;
}
    
location /favicon.ico {
    root /www/wwwroot/192.168.123.191;
}
    
location / {
    proxy_pass http://localhost:5000;
    proxy_redirect   off;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    client_max_body_size 5M;
}

接下来我们需要使用Supervisor启动并监控我们的Flask项目,在此之前需要了解一下Gunicorn的配置。Gunicorn 实现了一个 UNIX 的预分发 web 服务端。

  • Gunicorn 启动了被分发到的一个主线程,然后因此产生的子线程就是对应的 worker。
  • 主进程的作用是确保 worker 数量与设置中定义的数量相同。因此如果任何一个 worker 挂掉,主线程都可以通过分发它自身而另行启动。
  • worker 的角色是处理 HTTP 请求。
  • 这个 in 预分发 就意味着主线程在处理 HTTP 请求之前就创建了 worker。
  • 操作系统的内核就负责处理 worker 进程之间的负载均衡。

详细内容可以转到文章:[译] 通过优化 Gunicorn 配置提高性能。文章讲解了Gunicorn的工作模式,以及如何正确的配置Gunicorn来达到服务器的最佳运行状态。这里不做过多的阐述,只讲解如何配置。

workers = 2
threads = 2
bind = "127.0.0.1:5000"
demon = False
backlog = 1024
debug = False
chdir = '/www/wwwroot/192.168.123.191'
access_log_format = '%(t)s %(p)s %(h)s "%(r)s" %(s)s %(L)s %(b)s %(f)s" "%(a)s"'
loglevel = 'info'
worker_class = 'geventwebsocket.gunicorn.workers.GeventWebSocketWorker'
errorlog = chdir + '/logs/error.log'
accesslog = chdir + '/logs/access.log'
pidfile = chdir + '/logs/firstflask.pid'

每个配置项的具体作用可以查阅文章:python之gunicorn的配置,需要把这个配置文件放在项目的根目录下面方便我们通过Supervisor启动项目。值得注意的是我们配置了log文件目录,但是启动Gunicorn的时候并不会自动创建相应的目录和文件,所以需要我们手动创建相应的文件夹和文件,否则启动的时候会报错。

# 第一个app指的是app.py文件,第二个指的是flask应用的名字;
gunicorn -c gunicorn.conf app:app

由于我们之前已经通过pip成功安装好了Gunicorn的一系列支持库,接下来需要在Supervisor里面配置项目启动,通过Supervisor可以实现项目的开机启动,自动重启,项目监控。这里是通过宝塔提供的可视化Supervisor面板配置相应的配置项,熟悉Supervisor的同学可以直接在shell配置,忽略宝塔的存在。

配置项解释:①.名称就是监控项目的名称,可以随意填写。②.启动用户默认root用户不需要管它。③.运行目录是项目的根目录。④.启动文件是虚拟环境bin文件夹下的gunicorn文件,这个必须要有,否则项目不能正确启动。④.启动参数如同上面介绍的一样,通过配置文件启动需要带上配置文件名称。

保存之后项目会自动启动,可以通过可视化面板对项目进行重启等配置。此时WSGI容器改为了Gunicorn启动,所以就不会有之前的警告信息。访问相应的域名也可以得到正确的返回,至此本教程结束!!!

总结

本文章逻辑有点混乱,因为涉及的方面太多啦我也不是太好组织,其中肯定有错误还请各位指正,同时有不懂的地方欢迎评论我肯定会竭尽所能。朋友说这些事情都是运维工程师做的,但是技多不压身不是么?这也是一个全栈工程师的专业素养的体现,虽然都很菜啊!

本文引用了很多网上作者的文章,没有他们的帮助我也绝对学不到这些技术,把他们文章罗列一下方便大家查阅学习。


共有 0 条评论

Top