历时12天的审核,网站终于成功上线了! www.jiyuankai.top
源码托管在GitHub。
整个部署时间花了两天左右,过程中坑比较多,大部分时间都在网上找资料和试错。
本项目采用Flas
k + gunicorn
+ gevent
+ nginx
+ supervisor
的组合形式。
本项目部署在阿里云,服务器操作系统为Ubuntu 16.04
。不用纠结Ubuntu 16.04和14.04区别,随意选择,操作都差不多。
云服务器可以先去网上找找免费试用的(京东云免费一个月,腾讯云7天。。阿里云免费的没抢到,于是9.9租了一台半年的。。。)
另外,关于虚拟主机和云服务器的差别,我的理解就是集体宿舍大通铺和廉租小公寓的区别,总之是都能用就差钱,但是试问谁不想拥有自己的房呢?重点是只差了几块钱- -b,果断小公寓!
现在假定你已经有了一台安装了Ubuntu
系统的服务器。你可以通过云服务供应商提供的远程连接(阿里云是这个,应该都大同小异)控制云服务器,进入linux
的shell
环境,就可以通过linux
命令来操作服务器了~
但是!!敲命令行忒麻烦了,不如像windows
可视化来的直观容易。那么就要祭出神器了!介绍两款好用的软件:
a.控制云服务器软件:Xshell
通过它你可以用密匙和连接密码直连云服务器。(毕竟该敲的命令行还得敲)
b.能和电脑传输的软件:Xftp
和Xshell配套,用来传输文件,能在windows
界面下访问不同系统的服务器!
软件下载地址和详细使用教程,请参考这篇文章。
注意:软件安装在自己开发的电脑上。
装好了软件,就要开始对服务器动手了!先将服务器环境和开发环境同步,项目才能在服务器跑得起来。
打开自己的电脑,在window cmd命令行执行:
pip freeze > \path\requirements.txt
此命令用于复制本电脑中python
安装的所有包,写入requirements.txt
文件里。
path
填入想要这个文件放的目录,项目根目录即可。
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会自动读取项目根目录下的需求文件,并且安装里面记录的包。这样,开发环境就复制到服务器了。而且环境只在你创建的虚拟环境中,不会和外部环境冲突。
MySQL
数据库安装mysql-server
:
sudo apt-get install mysql-server
用户名默认是root
,密码自己设,完了记得修改项目的config
文件。导入表前,还有一步要做,在linux环境下安装的MySQL
,database默认编码不是utf-8
,之后进行数据库存取操作会报错。
解决方案,参考:修改MySQL数据库默认编码
最后,创建database
。
至此,我们可以进入虚拟环境试跑一下,看看有没有报错或者仍却少运行环境。
跑起来后,访问云服务器的公网IP,可以看到自己的网站啦~
PS1:程序运行配置的端口必须是开放外网的,这个要到云服务器安全组配置里去设置。
PS2:有些服务器里已经装了Nginx
,但因为还未进行配置。所以程序跑起来后访问服务器公网IP
,只能看到Nginx
的欢迎信息。
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),用冒号:
隔开。
同样再试运行一下,没问题就进入下一步~
Nginx
服务器Nginx
,一个高性能的web
服务器。通常用来做前端反向代理服务器。
至于为啥使用Nginx
,以及什么是反向代理,专业严谨的解释还请百度一下~
我的通俗理解就是,我们的gunicorn
服务器能高效处理动态请求,但是HTTP
请求进入会有快慢,大量并发时,可以先由Nginx
缓存请求,完毕后再交给gunicorn
,这样能提升gunicorn
的运行效率。并且鉴于Nginx
在网站的最前端,所有访问我们网站的请求都要经过它的过滤,一定程度上提升网站稳定性。
安装Nginx
sudo apt-get install nginx
启动
sudo service nginx start
重启
sudo service nginx start
重新加载配置
/etc/init.d/nginx reload
首先,我们用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
配置有没有的问题。
supervisor
是一个用于监控保护程序运行的库。他会自动重启程序,并且可以随时通过status
命令查看运行情况。
首先,安装supervisor
坑就不少,不同的安装方式,会导致后续发生不同的未知错误。
该库支持python2.7
不支持python3
,经历N次失败后,我把它安装在全局环境,再把全局默认的python
版本改为了2.7
。
supervior
库有两个命令,服务端supervisord
供启动配置,客户端supervisorctl
提供监控。
有两种安装方式:
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
的错误。
修改好了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] //停止项目
有反馈,无报错,恭喜恭喜啦~