简介
uwsgi是中间件,用于连接Flask与nginx,nginx会监听服务器接口,接收用户的请求,然后将该请求反向代理给uwsgi,uwsgi再将请求发送给与之连接的Flask服务器实例。
环境搭建的简单流程。
Flask相关
1.创建目录 /home/flaskcode
2.将flask项目放入该目录
3.构建python环境,这里使用virtualenv来构建环境,如下:
virtualenv venv (创建名为venv的虚拟环境)
>> New python executable in venv/bin/python
>> Installing setuptools, pip...done.
source venv/bin/activate (进入虚拟环境)
pip install uwsgi
pip install flask
pip install requests
pip install pymysql
尝试运行flask项目
python agent.py
nginx相关
1.安装nginx,ubuntu使用apt-get
apt-get install nginx
2.测试使用一下
/etc/init.d/nginx start #启动
访问127.0.0.1
nginx配置
ubuntu下通过apt-get安装的nginx配置文件为 /etc/nginx/sites-enabled/default
,一个软连接
vim /etc/nginx/sites-enabled/default
该文件最总会被include进入nginx的主配置文件中。
将配置文件中server的内容进行如下替换:
server {
listen 80; # 服务器监听端口
server_name 127.0.0.1; # 这里写你的域名或者公网IP,测试时可使用127.0.0.1本地询回地址
charset utf-8; # 编码
client_max_body_size 75M; # 之前写的关于GET和POST的区别,这里应该是原因之一吧
location / {
include uwsgi_params; # 导入uwsgi配置
uwsgi_pass 127.0.0.1:8000; # 转发端口,需要和uwsgi配置当中的监听端口一致
uwsgi_param UWSGI_PYTHON /home/自己创建的目录/venv; # Python解释器所在的路径(这里为虚拟环境)
uwsgi_param UWSGI_CHDIR /home/自己创建的目录; # 项目根目录
uwsgi_param UWSGI_SCRIPT agent:app; #比如你测试用test.py文件,文件中app = Flask(__name__),那么这里就填 test:app
}
}
重启nginx
/etc/init.d/nginx restart
nginx中通过参数uwsgi_pass设置的地址进行请求转发,将UWSGI也设置为该地址则可
centos7通过yum安装的nginx,其配置文件为nginx.conf,这次我们直接修改主配置文件,之所以折腾完ubuntu又折腾centos7是因为公司需要……
因为centos7的yum默认是没有nginx的,所以要添加相应的源,如下:
将Nginx添加到yum
sudo yum install epel-release
安装Nginx
sudo yum install nginx
启动Nginx
sudo systemctl start nginx
如果您正在运行防火墙,请运行以下命令以允许HTTP和HTTPS通信
sudo firewall-cmd --permanent --zone=public --add-service=http
sudo firewall-cmd --permanent --zone=public --add-service=https
sudo firewall-cmd --reload
需要在系统启动时启用Nginx,即开机自启,命令如下:
sudo systemctl enable nginx
其主配置文件如下:
/etc/nginx/nginx.conf
配置内容跟ubuntu一样,需要注意的一个坑是,使用yum安装的nginx要想成功链接uwsgi还需要配置一下,因为yum安装后,nginx的权限不是root,而我们后面创建uwsgi时,因为使用的root用户再操作,所以创建文件的权限也会是root,此时nginx就无法直接把其调起。
这里讲centos7系统中的selinux(安全模式)关闭则可(不知道会不会造成线上安全的等问题),修改selinux相关配置,如下
vi /etc/selinux/config
#SELINUX=enforcing #注释掉
#SELINUXTYPE=targeted #注释掉
SELINUX=disabled #增加
:wq! #保存退出
setenforce 0 #使配置立即生效
这样selinux就不会阻止nginx调用uwsgi。自己遇到这个问题时,查看了nginx的报错日志,发现nginx被权限拒绝,查了nginx会被权限拒绝的资料得到的解决方案,亲测可行。
如果不知系统中nginx被安装在哪或nginx相关的配置文件被放置在哪?可以使用find命令,如下
find / -name nginx
这样find就可以搜索全局与nginx相关的文件目录,之所以是全局是配置时,使用的范围是 /
UWSGI配置
在Flask项目的根目录下创建 uwsgi.ini
文件
uwsgi.ini
内容如下:
[uwsgi]
socket = 127.0.0.1:8000 # uwsgi的监听端口,与Nginx中配置相同
plugins = python # 这行一定要加上,不然请求时会出现-- unavailable modifier requested: 0 --错误提示
chdir = /home/flaskcode # 项目根目录
wsgi-file = agent.py # flask程序的启动文件,即app.run()所在文件
callable = app # 程序变量名
使用uwsgi启动一下该文件,其实就是配置文件,以文件的形式存储uwsgi的参数,方便使用
uwsgi --ini uwsgi.ini
Flask+uwsgi+nginx配置完成
nginx配置修改
因为公司需求,需要对多个不同域名请求都做相应,具体而言,公司服务器A具有唯一的IP,但有多个域名与该IP有对应关系,如 m1.test.com
、 m2.test.com
...等多个域名都对应着服务器A,要做的是,用户范围不同连接时,该服务器根据不同的链接URL请求不同的资源服务器,即服务器A简单而言就是做个中转。一开始考虑时自己想复杂了,往分布式架构那么想了,即nginx配置多个虚拟主机,具体而言就是nginx.conf中配置多个server主体,每个主体映射不同的主机,但其实这种需求并不需要使用分布式。
简单而言,配置一下nginx,让它可以响应多个域名的请求,再将请求发送给uwsgi则可,即uwsgi实例与Flask实例都是唯一的,其实只需要修改nginx的server_name字段,该字段表明要响应的请求,一开始我们设置为127.0.0.1,这里修改成相应的域名,该字段是支持正则的,具体如下:
server_name m*.test.com localhost;
这里加个localhost是为了方便测试,当然要测 m*.test.com
怎么测?因为需求时要更加这个地址让服务器请求不同的资源,那么服务器代码中的逻辑当然有处理 m*.test.com
的逻辑,如果报错这部分逻辑没问题。
两个简单的办法,一是假设法,即设置一个url变量,该变量的值为 m1.test.com
,将其看成是Flask从请求中获得的链接,从而验证自己的逻辑。
如果想连nginx这样配置是否可以行都验证一下,那就修改一下本地的hosts文件,本地的hosts其实就是本地的DNS,修改它,将m1.test.com对应的IP改为服务器的IP,如下:
192.168.146.129 m1.test.com
192.168.146.129 m2.test.com
需要注意的是,hosts中的配置时不允许有端口的,即 192.168.146.129:5000
这样配置hosts是无法生效的,我这里的服务器A是我本地VMWare安装的centos7虚拟机,所以地址是私网地址,windows中要让修改后的hosts立即生效,命令如下:
ipconfig /displaydns
ipconfig /flushdns
windows开发各种坑还是比较心累的,有条件的就赶紧弃了吧╮(╯▽╰)╭
这样你就可以直接通过浏览器访问m1.test.com了,实质上依旧是访问192.168.146.129,ping一下这个域名就知道。
debug
配置过程中报错解决思路,使用排除法。
如果配置了没有效果,看本地机子与服务器A直接能否ping通,不可,则要关闭一下两边的服务器。
Flask配置了host=0.0.0.0,依旧不可外网访问,最有可能的原因就是你的代码在其他地方同样导入的配置,因为我配置的Flask代码是组长写的,所以被坑了,因为将其配置一行注释掉就好了,没想到其他地方还导入了相关的配置。
进程监控
单独一个uwsgi程序运行长时间可能面临崩溃,所以配合使用supervisor对uwsgi进程简单控制。
Supervisor:python编写的进程管理工具,可以很方面的启动、重启、关闭进程,可以使用与任意进程,不仅是python进程
1.安装,pip或apt-get均可安装
apt-get install supervisor
或
pip install supervisor
2.配置supervisor
下面内容使用的supervisor是通过apt-get安装的
supervisor有默认的全局配置文件,通常不修改它,而是生成新的配置文件进行配置
echo_supervisord_config > /Flask项目根目录/supervisord.conf
生成在Flask项目根目录方便管理
vim编辑该文件
vim supervisord.conf
vim进入文件末尾,命令为:
:$
添加如下内容:
[program:flaskcode] # project_name这里写上你的项目名称,即项目根目录名
command = uwsgi --ini /Flask项目路径/uwsgi.ini # 跟手动启动的命令一样
stopsignal=QUIT
autostart=true
autorestart=true
stdout_logfile=/Flask项目目录/log/supervisor_out.log # 运行日志
stderr_logfile=/Flask项目目录/log/supervisor_err.log # 错误日志
在Flask项目下使用mkdir创建log目录,用于存放supervisor生成的日志文件
3.使用
重启supervisor
sudo supervisord -c supervisord.conf
ubuntu虚拟机开启supervisord效果如下,通过killall uwsgi关闭uwsgi程序,就会立刻被supervisord重启开启
4.supervisor相关命令
手动启动:
supervisord -c supervisord.conf
手动关闭supervisord启动的所有服务:
supervisordctl stop all
结尾
在公司使用自己熟悉的环境工作效率会提升很多,必须吐槽一下,一开始不想装虚拟机,因为centos7的镜像4GB多,下载也要挺久的,而在公司做了网络限制,超量会被限速,这就更蛋疼了,叫组长给我弄了台公司的测试服,不料,不怎么会用上古系统redhat4,各种配置坑,我已经不年轻了,不想折腾了,所以才屈服下载centos7与ubuntu 16.04的镜像进行上述的配置。