阿里云ESC网站部署Flask+gunicorn+nginx+supervisor

历时12天的审核,网站终于成功上线了! www.jiyuankai.top
源码托管在GitHub。
整个部署时间花了两天左右,过程中坑比较多,大部分时间都在网上找资料和试错。
本项目采用Flask + gunicorn + gevent + nginx + supervisor的组合形式。


1. 服务器

本项目部署在阿里云,服务器操作系统为Ubuntu 16.04。不用纠结Ubuntu 16.04和14.04区别,随意选择,操作都差不多。
云服务器可以先去网上找找免费试用的(京东云免费一个月,腾讯云7天。。阿里云免费的没抢到,于是9.9租了一台半年的。。。)

另外,关于虚拟主机和云服务器的差别,我的理解就是集体宿舍大通铺和廉租小公寓的区别,总之是都能用就差钱,但是试问谁不想拥有自己的房呢?重点是只差了几块钱- -b,果断小公寓!


2. 控制云服务器传输文件

现在假定你已经有了一台安装了Ubuntu系统的服务器。你可以通过云服务供应商提供的远程连接(阿里云是这个,应该都大同小异)控制云服务器,进入linuxshell环境,就可以通过linux命令来操作服务器了~

但是!!敲命令行忒麻烦了,不如像windows可视化来的直观容易。那么就要祭出神器了!介绍两款好用的软件:
a.控制云服务器软件:Xshell
通过它你可以用密匙和连接密码直连云服务器。(毕竟该敲的命令行还得敲)

b.能和电脑传输的软件:Xftp
和Xshell配套,用来传输文件,能在windows界面下访问不同系统的服务器!
软件下载地址和详细使用教程,请参考这篇文章。
注意:软件安装在自己开发的电脑上。


3. 配置服务器环境

装好了软件,就要开始对服务器动手了!先将服务器环境和开发环境同步,项目才能在服务器跑得起来。

3.1 创建需求文件

打开自己的电脑,在window cmd命令行执行:

pip freeze > \path\requirements.txt

此命令用于复制本电脑中python安装的所有包,写入requirements.txt文件里。
path填入想要这个文件放的目录,项目根目录即可。

3.2 安装virtualenv虚拟环境

一台服务器上可能运行好几个项目,而不同项目所用的需求文件版本不一定一样,甚至python的版本都不同。我们的项目是用python3运行的,而像之后要用到的supervisor就是运行在python2中的。

打开Xshell连上服务器,安装基本的软件:

sudo apt-get install python3.5
sudo apt-get install python3-pip

创建一个项目文件夹一般放在home下,如home/myblog,可以敲命令行,我用Xftp直接操作的。
安装虚拟环境包:

pip install virtualenv

(也可以用sudo apt-get install virtualenv,不过我这样装的虚拟环境是python2的,而且还发生了未知错误)

然后切到项目根目录:

cd /home/myblog

在项目根目录创建虚拟环境:

virtualenv venv   

此时可以看到项目根目录出现了一个venv文件夹。
进入虚拟环境的方法是,在切到项目根目录的情况下:

激活虚拟环境:

source venv/bin/activate 

激活后会发现命令行的左边有标识,显示已经进入虚拟环境的shell

退出虚拟环境的方法:

deactivate

现在,把代码文件拷贝进项目目录。在虚拟环境shell中输入:

pip install -r requirements.txt

pip会自动读取项目根目录下的需求文件,并且安装里面记录的包。这样,开发环境就复制到服务器了。而且环境只在你创建的虚拟环境中,不会和外部环境冲突。


4. 安装MySQL数据库

安装mysql-server

sudo apt-get install mysql-server

用户名默认是root,密码自己设,完了记得修改项目的config文件。导入表前,还有一步要做,在linux环境下安装的MySQLdatabase默认编码不是utf-8,之后进行数据库存取操作会报错。
解决方案,参考:修改MySQL数据库默认编码
最后,创建database


试运行

至此,我们可以进入虚拟环境试跑一下,看看有没有报错或者仍却少运行环境。
跑起来后,访问云服务器的公网IP,可以看到自己的网站啦~
PS1:程序运行配置的端口必须是开放外网的,这个要到云服务器安全组配置里去设置。
PS2:有些服务器里已经装了Nginx,但因为还未进行配置。所以程序跑起来后访问服务器公网IP,只能看到Nginx的欢迎信息。


5. 配置Gunicorn服务器

不论是Flask还是aiohttp,它们自带的WSGI服务器用于开发功能尚可,但用于生产环境就稍显不足了。所以生产环境中我们使用gunicorn服务器处理动态请求,搭配gevent库实现异步响应。(因为Flask是同步阻塞框架,需要搭配gevent做异步响应,且gunicorngevent有良好的支持。用异步开发模型的可以无视。)

进入虚拟环境shell后,输入:

pip install gunicorn
pip install gevent 

然后写一个符合自己要求的gunicorn配置文件:
参考:gunicorn配置文档

from gevent import monkey
monkey.patch_all()

import multiprocessing

debug = True
loglevel = 'debug'
bind = '127.0.0.1:5000'
pidfile = 'log/gunicorn.pid' //需要在项目目录手动建好文件夹log,否则报错
logfile = 'log/debug.log'  

workers = multiprocessing.cpu_count() * 2 + 1
worker_class = 'gevent' //gunicorn默认是阻塞的,要选择模式。

通过gunicorn运行Flask实例:

gunicorn -c /path/config.py manage:app   

-c 表示应用配置文件的命令。/path/config.py是配置文件路径。
manage:app 前者表示启动文件,比如我的是manage.py。后者表示启动文件里的程序实例(我的就叫app),用冒号隔开。

同样再试运行一下,没问题就进入下一步~


6. 配置Nginx服务器

Nginx,一个高性能的web服务器。通常用来做前端反向代理服务器
至于为啥使用Nginx,以及什么是反向代理,专业严谨的解释还请百度一下~
我的通俗理解就是,我们的gunicorn服务器能高效处理动态请求,但是HTTP请求进入会有快慢,大量并发时,可以先由Nginx缓存请求,完毕后再交给gunicorn,这样能提升gunicorn的运行效率。并且鉴于Nginx在网站的最前端,所有访问我们网站的请求都要经过它的过滤,一定程度上提升网站稳定性。

6.1 安装

安装Nginx

sudo apt-get install nginx

启动

sudo service nginx start 

重启

sudo service nginx start  

重新加载配置

/etc/init.d/nginx reload    

6.2 配置

首先,我们用Xftp进入路径/etc/nginx/sites-available//etc/nginx/sites-enable/,可以看到两个default文件,这就是Nginx的配置文件。
不过,前者sites-available中的才是源文件,后者是它的软链接(理解为Windows中的快捷方式)。

接下来我们要编写自己的Nginx配置文件:

 server{
    listen      80;


    root        /home/myblog;
    access_log  /home/myblog/log/acess_log;
    error_log   /home/myblog/log/error_log;

    location / {
        proxy_pass       http://127.0.0.1:5000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
    location ~ ^\/static\/.*$ {
        root    /home/myblog/app/;
    }
}

创建Nginx的配置文件,要放到/etc/nginx/sites-available/中去,再在/etc/nginx/sites-enable/中设置一个指向它的软链接:

sudo ln-s /etc/nginx/sites-available/文件名 空格  /etc/nginx/sites-enable/文件名  

PS:文件名自定义,命令行两个地址之间有空格!

就会发现/etc/nginx/sites-enable中有一个同名的文件了。
重载一下配置文件 :

/etc/init.d/nginx reload  

PS:建议将原来的default配置文件删除,或移到其他地方保存。因为一旦你的配置文件定义的端口和default有冲突,Nginx会无视你的配置,即使你的配置无误,还是只能访问到Nginx欢迎界面。

至此,可以放心运行程序了,在虚拟环境用gunicorn来启动。
如果访问一直显示Nginx欢迎界面,还是主要找一下Nginx配置有没有的问题。


7. supervisor

supervisor是一个用于监控保护程序运行的库。他会自动重启程序,并且可以随时通过status命令查看运行情况。
首先,安装supervisor坑就不少,不同的安装方式,会导致后续发生不同的未知错误。
该库支持python2.7不支持python3,经历N次失败后,我把它安装在全局环境,再把全局默认的python版本改为了2.7
supervior库有两个命令,服务端supervisord供启动配置,客户端supervisorctl提供监控。

7.1 安装

有两种安装方式:
1、通过pip安装:

pip install supervisor     

我无法用pip安装,每次安装都不成功。
2、linux命令安装:

sudo apt-get install supervisor    

用命令行可以安装。
出现以上两种安装方式的原因是,后续启动supervisord服务端,会出现找不到supervisor.socket文件错误。而这两种安装方式会导致安装该文件出现的目录不同。
Xftp5进入/etc/supervisor/文件夹找到supervisord.conf配置,忽略其他所有,重点关注两个地方:

...
[supervisorctl] //line 18
serverurl=unix:///tmp/supervisor.sock ; use a unix:// URL  for a unix socket
...
[include]  //line 27
files = /home/myblog/*.conf

line 18处的serverurl这是我已经设置过的。
它的默认值是:serverurl=unix:///var/run/supervisor.sock
Xftp5进两个地址确定它在哪,两种安装方式会在两个地方。如果在serverurl路径的目录中没有这个文件夹,会导致后续报找不到supervisor.socket的错误。

7.2 编写配置文件

修改好了serverurl,我们加入自己的配置。可以直接复制在[include]下面(不建议),也可以自己编写单独文件,自定义line27的路径。

[program:myblog] //自定义项目名称

command      = /home/myblog/venv/bin/gunicorn -c /home/myblog/gunicorn_config.py manage:app
//command是你在命令行启动gunicorn输入的命令,按自己的修改
directory    = /home/myblog  //项目目录
autorestart  = true //自动重启
autostart    = true //随supervisor启动自动启动
startsecs    = 3  //开始3秒无异常表示成功
startretires = 3  //重启失败3次

redirect_stderr         = true
stdout_logfile_maxbytes = 50MB
stdout_logfile_backups  = 10
stdout_logfile          = /home/myblog/log/myblog.log

[supervisord]
logfile  = /home/myblog/log/myblog.log
pidfile  = /home/myblog/pid/myblog.pid  //手动建好pid文件夹  

完成以上配置,启动服务端superviord,它会自动根据command参数运行gunicorn:

supervisord -c /etc/supervisor/supervisord.conf  

接下来启动客户端superviorctl

supervisorctl -c /etc/supervisor/supervisord.conf     

理论上,应该能进入supervisorshell界面,供输入参数查看进程状态。(无论客户端superviorctl是否配置成功,都会进入supervisorshell界面,并说明不了什么,该报错还是报错)

但是,实践当中很有可能出现情况情况:
a、superviord已经运行了,但是supervisorctl找不到它。
(确认是否运行,可以访问网站,看能否打开。或者命令行ps -ef,查看有没有/home/项目目录/python开头的进程)
导致a情况的原因有:
1、找不到supervisor.soket文件,请根据上文修改serverurl
2、直接运行了supervisorctl,后面没有加-c /etc/supervisor/supervisord.conf 配置文件。如果supervisordsupervisorctl的配置不同,也会导致supervisord已经运行,但是supervisorctl却找不到它的情况。确定supervisordsupervisorctl加载了配置文件且配置文件相同。
3、发生关不掉supervisor的情况(重启服务器没用),因为我们的之前的配置文件中设置了autorestartautostarttrue。此时要关掉它须先在配置文件中的两项设为false,再用命令行 kill 进程ID 来关闭。
b、superviord没有运行。
导致b情况的原因:
在正确安装的情况下,一般都是配置文件有问题,请根据上文重新确认配置文件是否无误。


最后,一切OK的话,进入superviorctlshell命令行:

status          //查看进程状态
start [name]    //启动项目
stop [name]     //停止项目

有反馈,无报错,恭喜恭喜啦~

你可能感兴趣的:(Python,实战,Python,Web,Flask,Linux)