您的位置:首页 > 运维架构 > Nginx

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

2017-11-02 02:11 411 查看
历时12天的审核,网站终于成功上线了! www.jiyuankai.top

源码托管在GitHub

整个部署时间花了两天左右,过程中坑比较多,大部分时间都在网上找资料和试错。

本项目采用
Flas
k +
gunicorn
+
gevent
+
nginx
+
supervisor
的组合形式。

1. 服务器

本项目部署在阿里云,服务器操作系统为
Ubuntu 16.04
。不用纠结Ubuntu 16.04和14.04区别,随意选择,操作都差不多。

云服务器可以先去网上找找免费试用的(京东云免费一个月,腾讯云7天。。阿里云免费的没抢到,于是9.9租了一台半年的。。。)

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

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

现在假定你已经有了一台安装了
Ubuntu
系统的服务器。你可以通过云服务供应商提供的远程连接(阿里云是这个,应该都大同小异)控制云服务器,进入
linux
shell
环境,就可以通过
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


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


退出虚拟环境的方法:

deactivate


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

pip install -r requirements.txt


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

4. 安装
MySQL
数据库

安装
mysql-server


sudo apt-get install mysql-server


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

解决方案,参考:修改MySQL数据库默认编码

最后,创建
database


试运行

至此,我们可以进入虚拟环境试跑一下,看看有没有报错或者仍却少运行环境。

跑起来后,访问云服务器的公网IP,可以看到自己的网站啦~

PS1:程序运行配置的端口必须是开放外网的,这个要到云服务器安全组配置里去设置。

PS2:有些服务器里已经装了
Nginx
,但因为还未进行配置。所以程序跑起来后访问服务器公网
IP
,只能看到
Nginx
的欢迎信息。

5. 配置
Gunicorn
服务器

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

进入虚拟环境
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


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

但是,实践当中很有可能出现情况情况:

a、
superviord
已经运行了,但是
supervisorctl
找不到它。


(确认是否运行,可以访问网站,看能否打开。或者命令行ps -ef,查看有没有
/home/项目目录/python
开头的进程)

导致a情况的原因有:

1、找不到
supervisor.soket
文件,请根据上文修改
serverurl


2、直接运行了
supervisorctl
,后面没有加
-c /etc/supervisor/supervisord.conf
配置文件。如果
supervisord
supervisorctl
的配置不同,也会导致
supervisord
已经运行,但是
supervisorctl
却找不到它的情况。确定
supervisord
supervisorctl
加载了配置文件且配置文件相同。


3、发生关不掉
supervisor
的情况(重启服务器没用),因为我们的之前的配置文件中设置了
autorestart
autostart
true
。此时要关掉它须先在配置文件中的两项设为
false
,再用命令行 kill 进程ID 来关闭。

b、
superviord
没有运行。


导致b情况的原因:

在正确安装的情况下,一般都是配置文件有问题,请根据上文重新确认配置文件是否无误。

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

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


有反馈,无报错,恭喜恭喜啦~
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: