python web 部署
一、目标
通过本章章节学习,你需要掌握flask项目在linux服务器上的uwsgi结合nginx实现单站点部署、多站点部署以及开机自启动脚本的配置。通过阅读需求文档 和 思维导图,来完成整体步骤
二、环境搭建
2.1环境说明
操作系统centos7
python版本 3.5.1版本(下面会说明安装步骤)
2.2项目保存路径
项目保存在/root/pyproject下,在pyproject的flaskconfig文件下保存uwsgi配置文件(这个文件会在后面进行编写)
2.3安装python3
安装python3在centos7下比较麻烦,需要安装zlib、openssl-devel才可以安装python3
如果没有wget先安装wget
- yum -y install wget
2.3.1安装zlib
- wget http://www.zlib.net/zlib-1.2.11.tar.gz
- tar -zxvf zlib-1.2.11.tar.gz
- cd zlib-1.2.11
- ./configure
- make
- make install
如果没有make,安装make
- yum install make
默认在会安装在/usr/local/lib 下,这个在安装过程中,有显示的
2.3.2安装openssl-devel
- yum install openssl-devel;
yum install sqlite-devel
#以下要是安装报错可以忽略
yum install sqlite2
yum install tcl-devel
yum install tk_devel
2.3.3安装python3
进入到/usr/bin目录下
- cd /usr/bin
备份原来python
- mv python python.back
下载python3.5.1
- wget https://www.python.org/ftp/python/3.5.1/Python-3.5.1.tgz
解压缩
- tar -zxvf Python-3.5.1.tgz
删除安装包
- rm -rf Python-3.5.1.tgz
进入安装包目录
- cd Python-3.5.1
运行配置脚本,指定zlib位置(重要)有可能也不需要加zlib
- ./configure --with-zlib=/usr/local/lib
编译
- make
安装
- make install
查看python版本
- python3.5 -V
2.3.4建立软连接(不建议使用,不影响后续使用)
建立软连接
- ln -s /usr/local/bin/python3.5 /usr/bin/python
#修改yum配置文件
- vim /usr/bin/yum
把头文件#!/usr/bin/python改为#!/usr/bin/python2.7 #因为yum需要依赖2.7版本
- vim /usr/libexec/urlgrabber-ext-down
把头文件#!/usr/bin/python改为#!/usr/bin/python2.7 #因为yum需要依赖2.7版本
2.4创建虚拟环境
2.4.1安装virtualenv
- pip install virtualenv
创建python环境目录,默认是python2
- virtualenv venv
2.4.2指定python环境(这步如果没安装zlib会出现错误)
- virtualenv -p /usr/bin/python3.5
2.4.3激活虚拟环境
- source venv/bin/activate
2.4.4退出虚拟环境(前面那个点不能少)
- .venv/bin/deactivate
2.5安装flask(在虚拟环境中安装)
- pip install flask
准备2个flask工程,这里的flask程序可以是你已经开发完成的
这里我的工程一个叫做在线编译,其中flask的程序在在线编译文件夹下的在线编译.py,一个叫做flaskdemo1文件夹下的flaskdemo1.py,这2个程序我放在/root/pyproject下
分别运行2个程序,测试是否能够在服务器上正常运行,测试的方法是直接运行flask的那个文件
- python3.5 在线编译.py
就可以访问相关地址了
停止测试通过ctrl+c来进行停止
三、并发处理
flask本身自带wsgi本身不支持并发,也就是在一个接口访问的时候,没有处理完成,下一个接口访问会卡住无法处理,所以我们需要有合适的并发来使用
1、uwsgi
2、gunicorn
3.1 uwsgi单站点布置说明
uwsgi官方中文文档 http://uwsgi-docs-zh.readthedocs.io/zh_CN/latest/WSGIquickstart.html
安装uwsgi
- pip install uwsgi
如果报错you need a C compiler to build uWSGI,说明没有c的编译环境
- yum install -y gcc gcc-c++
执行uwsgi有2种方式
1、命令行方式
2、配置文件方式
使用命令行
进入到和这个文件夹同级下,比如进入到/root/pyproject/在线编译文件夹下,输入以下命令启动uwsgi
- uwsgi --http 0.0.0.0:5000 --wsgi-file 在线编译.py --callable app --processes 4 --threads 2 --stats 0.0.0.0:9191
这样就启动起来了,可以访问服务器ip地址:5000下的对应的flask提供的服务,这里启动了4个进程 2个线程的方式
如果不想进入项目文件夹下,需要添加参数命令 /root/pyproject/在线编译/ 具体命令如下
- uwsgi --http 0.0.0.0:5000 --chdir /root/pyproject/在线编译/ --wsgi-file 在线编译.py --callable app --processes 4 --threads 2
这样访问服务器ip地址:5000下的对应flask提供的服务,这里启动了4个进程 2个线程的方式
使用配置文件方式启动
在 /root/pyproject/flaskconfig下创建文件uwsgi.ini
- vim uwsgi.ini
输入以下内容([uwsgi]一定不能少)
- [uwsgi]
- #启动程序所使用的地址和端口
- http=0.0.0.0:5000
- #记录pid,方便停止和重启服务
- pidfile=/tmp/uwsgi.pid
- #项目所在路径
- chdir=/root/pyproject/在线编译/
- #flask程序启动文件
- wsgi-file=在线编译.py
- #使用主进程
- master=true
- #多站点(这个可以不配置)
- vhost=true
- #flask里面启动Application变量名
- callable=app
- #进程数
- processes=4
- #线程数
- threads=2
- manage-script-name = true
配置完成后使用如下命令进行启动
- uwsgi --ini uwsgi.ini -d uwsgi.log
3.2停止uwsgi的2种办法
1、查pid直接杀,编写循环杀
2、通过uwsgi的stop,但是需要主进程pid
3.2.1方法1 查找uwsgi的对应pid,通过kiil -9 uwsgi的pid进行删除
- ps aux| grep uwsgi
3.2.2可以编写脚本来方便删除,通过vim stop.sh
- #!/bin/sh
- NAME="uwsgi"
- if [ ! -n "$NAME" ];then
- echo "no arguments"
- exit;
- fi
- echo $NAME
- ID=`ps -ef | grep "$NAME" | grep -v "$0" | grep -v "grep" | awk '{print $2}'`
- echo $ID
- echo "################################################"
- for id in $ID
- do
- kill -9 $id
- echo "kill $id"
- done
- echo "################################################"
编写后记得赋值权限后才能使用,通过chmod 777 stop.sh,使用的时候./stop.sh即可全部停止
3.2.3方法2(不好用,限制多,还未必能停)
进行关闭
- uwsgi --stop /tmp/uwsgi.pid
这步操作需要依赖配置文件ini中要配置主进程以及记录pid存储在哪里,也就是在上面的ini文件中pidfile=/tmp/uwsgi.pid是一定要有,并且master = true也同时需要,否则执行stop时候,只会杀掉一个进程,因为在uwsgi.pid中只会记录第一个进程
3.3多站点共用一个uwsgi服务
以上介绍的是单个站点的启动与停止,一台服务器上,可能需要启动多个站点,这里就需要启动emperor帝王模式
emperor翻译为中文的意思其实就是皇帝的意思,那么既然有皇帝,那就肯定有“臣子”(vassals),其中“臣子”就是指实际运行的一个app实例,在这里就是uwsgi.ini和uwsgi1.ini这2个配置文件
如何启动帝王模式
为2个应用在线编译项目和flaskdemo1项目编写ini
因为之前编写了在线编译这个的ini,现在编写flaskdemo1的ini,在flaskconfig文件夹
cp uwgsi.ini uwgsi1.ini
修改uwgsi1.ini(红色部分是修改部分)
- [uwsgi]
- #启动程序所使用的地址和端口
- http=0.0.0.0:5001
- #记录pid,方便停止和重启服务
- pidfile=/tmp/uwsgi.pid
- #项目所在路径
- chdir=/root/pyproject/flaskdemo1/
- #flask程序启动文件
- wsgi-file=flaskdemo1.py
- #使用主进程
- master=true
- #多站点
- vhost=true
- #flask里面启动Application变量名
- callable=app
- #进程数
- processes=4
- #线程数
- threads=2
- manage-script-name = true
注意
这2个配置文件中要求端口不一样才可以,否则启动会冲突的(因为如果项目1中也有根目录,项目2中也有根目录,同端口,你无法区别是选用哪个项目的)
这2个配置文件在同一个文件夹下/root/pyproject/flaskconfig/
启动uwsgi帝王模式
- uwsgi --emperor /root/pyproject/flaskconfig/ -d my.log
其中,flaskconfig文件夹里包含了各个app的配置文件,这个文件夹将会被emperor一直监视,只要有配置文件的修改或新建,app实例就会被重新加载或新建,可以通过软链接将实际项目中的配置文件链接到vassal文件夹目录下:
emperor监视的是配置文件目录,但是问题来了,如果代码进行改动了,这次更新并没有对配置文件进行修改,实例自然就不会重新启动了。
幸好配置文件提供了touch-reload选项,只要指定文件夹发生改动就重启实例:
- touch-reload = /root/pyproject/flaskdemo1/
相当于是对uwsgi.ini和uwsgi1.ini下进行添加以上参数,值是对应项目文件夹
四、开机自启动脚本
4.1、基本设置
开机后,需要自动启动uwsgi以及其他服务,比如我服务器上开机需要启动Tomcat,这就需要开机自启动,配置流程如下
1、vim修改/etc/rc.d/rc.local文件
在这个文件中添加脚本,我的脚本如下
- #!/bin/bash
- # THIS FILE IS ADDED FOR COMPATIBILITY PURPOSES
- #
- # It is highly advisable to create own systemd services or udev rules
- # to run scripts during boot instead of using this file.
- #
- # In contrast to previous versions due to parallel execution during boot
- # this script will NOT be run after all other services.
- #
- # Please note that you must run 'chmod +x /etc/rc.d/rc.local' to ensure
- # that this script will be executed during boot.
- #自带的,不用管
- touch /var/lock/subsys/local
- #启动Java的Tomcat
- /home/apache-tomcat-9.0.6/bin/startup.sh
- #激活Python虚拟环境
- source /root/venv/bin/activate
- #启动uwsgi帝王模式
- uwsgi --emperor /root/pyproject/flaskconfig/ -d /root/pyproject/myuwsgi.log
2、对rc.local赋权限
- chmod 777 /etc/rc.d/rc.local
3、重启服务器
- reboot
以上就可以完成开启自启动了,但是每次修改rc.local很麻烦,所以我们把他抽离出来,在root文件夹下建立autostart.sh
- #!/bin/bash
- /home/apache-tomcat-9.0.6/bin/startup.sh
- source /root/venv/bin/activate
- uwsgi --emperor /root/pyproject/flaskconfig/ -d /root/pyproject/myuwsgi.log
对autostart.sh赋值权限
- chmod 777 autostart.sh
最后修改/etc/rc.d/rc.local
- #!/bin/bash
- # THIS FILE IS ADDED FOR COMPATIBILITY PURPOSES
- #
- # It is highly advisable to create own systemd services or udev rules
- # to run scripts during boot instead of using this file.
- #
- # In contrast to previous versions due to parallel execution during boot
- # this script will NOT be run after all other services.
- #
- # Please note that you must run 'chmod +x /etc/rc.d/rc.local' to ensure
- # that this script will be executed during boot.
- touch /var/lock/subsys/local
- /root/autostart.sh
以后每次修改我们的autostart.sh即可对开启自启动项进行配置了
以后部署项目就在/root/pyproject下上传项目,在flaskconfig下添加启动文件即可完成,更新项目只需要更新对应的项目文件夹即可
五、配置Nginx
uwsgi的并发处理能力还是低下的,所以上层需要进行大并发处理,搭建Nginx做上层转发处理
5.1、下载与安装
- #下载
- cd /home
- wget -c https://nginx.org/download/nginx-1.10.3.tar.gz
- #解压缩
- tar -zxvf nginx-1.10.3.tar.gz
- #进入Nginx目录
- cd nginx-1.10.3
- #设置配置信息
- ./configure
5.2、相关错误解决办法
错误为:./configure: error: the HTTP rewrite module requires the PCRE library.
安装pcre-devel解决问题
- yum -y install pcre-devel
还有可能出现:
错误提示:./configure: error: the HTTP cache module requires md5 functions
from OpenSSL library. You can either disable the module by using
–without-http-cache option, or install the OpenSSL library into the system,
or build the OpenSSL library statically from the source with nginx by using
–with-http_ssl_module –with-openssl=<path> options.
解决办法:
- yum -y install openssl openssl-devel
5.3、编译
- make
- make install
OK,所有的工作都已经做完啦,下面开始启动Nginx服务并在远程测试,想想是不是很激动。
一般编译安装完的软件都会放在/usr里,这不是user,这是Unix System Resource,是Unix系统资源的缩写。
5.4、启动与停止
在/usr/local/里面发现了nginx,进入。
- cd /usr/local/nginx/
如果你找不到,试试这条命令吧
- #whereis nginx
它会告诉你nginx在哪,nginx的命令在/usr/local/nginx/sbin目录下
对于nginx的启动,停止
- ./nginx #启动
- ./nginx -s stop #停止
- ./nginx -s quit #退出
- ./nginx -s reload #刷新
5.5、单项目配置负载均衡
- cd /usr/local/nginx/conf/
- vim nginx.conf
在http的大括号内添加如下内容
- upstream app1{
- server 0.0.0.0:5001 max_fails=2 fail_timeout=600s weight=10;
- }
在上述项目中,我们配置在uwsgi下有2个项目,一个是5000一个是5001,访问地址,出现不同的内容,这样方便我们验证消息转发,配置文件修改如下
- upstream app1{
- server 0.0.0.0:5000 max_fails=2 fail_timeout=600s weight=10;
- server 0.0.0.0:5001 max_fails=2 fail_timeout=600s weight=10;
- }
在开发环境中,5001和5000应当配置相同的项目,并且可能部署在不同的服务器上,ip地址也不相同,因为nginx主要是处理大并发。应用于一个项目部署在多台服务器上,对请求进行分发,降低单台负载压力,多个server可以配置来源其他服务器上的uwsgi的地址,但是必须是相同的项目,也就是你开发了一个flaskdemo1,其他服务器上部署了uwsgi,nginx配置这个uwsgi的ip地址
在server大括号内的location 内添加
proxy_pass http://app1;
需要注意的是app1是和上面upstream的app1对应上的
因为Apache本身占用了80端口,Nginx需要修改端口
server下修改listen的值为81,这样Nginx启动的端口就是81端口
- cd ../sbin
启动nginx
- ./nginx
没报错就说明启动了
停止nginx
- ./nginx -s stop
这样当我们访问nginx上面这个ip地址的时候,nginx会进行转发,在2个服务器之间根据权值进行分发
反复进行访问的时候服务器访问服务器IP:81 时候,nginx会进行转发,会发现每次显示不同的内容,实际开发肯定是相同的内容
5.6、多项目配置负载均衡
通常一个项目用不满Nginx的性能,所以可以根据路径进行转发规则
比如希望Nginx下部署Java的项目,部署多个Python项目如何进行部署
首先我们看下目前有的项目
简历生成 http://47.93.248.15:8080/jianli/getjianli
爱奇艺前台http://47.93.248.15:8080/Iqiyi2/MovieListServlet
爱奇艺后台 http://47.93.248.15:8080/IqiyiManager/login.jsp
在线编译 http://47.93.248.15:5000/static/index.htm
flaskdemo1 http://47.93.248.15:5001
3个java2个python,路径相对繁杂,期望把Java项目加上Java前缀,python项目加上python前缀
就需要在nginx的配置文件中的location中进行处理
在server外添加
- #java项目路由
- upstream java{
- server 0.0.0.0:8080 max_fails=2 fail_timeout=600s weight=10;
- }
在server内添加
- location /java/{
- root html;
- rewrite ^/java/(.*) /$1 break;
- proxy_pass http://java;
- }
这是做什么呢,相当于进行判断地址以/java/为开头在转发的时候,去掉/java/这段在进行转发,因为/java/是我们自己添加的,在原有地址中不存在,root html;是访问根目录时候必不可少的
以此类推,在server外添加以下路径
- #java项目路由
- upstream java{
- server 0.0.0.0:8080 max_fails=2 fail_timeout=600s weight=10;
- }
- #python 在线编译路由
- upstream python1{
- server 0.0.0.0:5000 max_fails=2 fail_timeout=600s weight=10;
- }
- #python flaskdemo1路由
- upstream python2{
- server 0.0.0.0:5001 max_fails=2 fail_timeout=600s weight=10;
- }
在server内添加
- #转发java
- location /java/{
- root html;
- rewrite ^/java/(.*) /$1 break;
- proxy_pass http://java;
- }
- #转发在线编译
- location /python1/{
- root html;
- rewrite ^/python1/(.*) /$1 break;
- proxy_pass http://python1;
- }
- #转发flaskdemo
- location /python2/{
- root html;
- rewrite ^/python2/(.*) /$1 break;
- proxy_pass http://python2;
- }
重启nginx
/user/local/nginx/sbin/nginx -s stop
/user/local/nginx/sbin/nginx
这样我们的访问地址就统一了
简历生成 http://47.93.248.15:81/java/jianli/getjianli
爱奇艺前台http://47.93.248.15:81/java/Iqiyi2/MovieListServlet
爱奇艺后台 http://47.93.248.15:81/java/IqiyiManager/login.jsp
在线编译 http://47.93.248.15:81/python1/static/index.htm
flaskdemo1 http://47.93.248.81/python2
最后把nginx的启动命令添加在开机自启动脚本autostart.sh中
- #!/bin/bash
- /home/apache-tomcat-9.0.6/bin/startup.sh
- source /root/venv/bin/activate
- uwsgi --emperor /root/pyproject/flaskconfig/ -d /root/pyproject/myuwsgi.log
- /usr/local/nginx/sbin/nginx
以后每次重启服务器,就不用担心写一堆命令行了
部署java项目,直接丢进tomcat下的webapp下即可
部署python项目,丢进pyproject下,在pyproject/flaskconfig项目下编写ini即可
最后重启服务器reboot即可完成
以上步骤,在Python多项目部署时候,会出现所有静态资源丢失,解决办法如下
1、对Python多个项目中的static中内容,集中放在一起,Nginx对静态资源做加载,Nginx配置如下
- location /static/{
- root /home/;
- }
在你的home文件夹下创建一个static的文件夹,把多个flask下对应static合并为一个static文件夹,最后把内容全部上传到home路径下的static下,即可完成,所有静态资源,全部交给nginx进行处理
这种方式对代码改动较小,只需要在nginx下增加个配置文件即可,但是这样如果出现多个项目合并时候,静态资源过多,可能导致图片地址冲突的问题,以及对项目升级带来的麻烦,这些都是不可忽视的
2、单独处理每个Python项目中静态资源地址,对static重命名,在flask的app上对static_path修改地址,模板路径不能写死为static,需要加载相对静态资源地址
比如我有2个flask项目mmonly和iqiyi,static文件夹是默认存储相关静态资源的,需要对static文件夹进行重命名,分别命名为iqiyistatic和mmonlystatic,由于不再是默认文件夹名称,需要在flask上进行对应修改
iqiyi项目做如下修改
- app = Flask(__name__,static_url_path='iqiyistatic')
mmonly项目如下修改
- app = Flask(__name__,static_url_path='mmonlystatic')
在程序的模板中拼接地址,还可能固定写死的static,也需要进行修改
这样地址访问的规则,就从ip地址:端口:static变为ip地址:端口:iqiyistatic或者ip地址:端口:mmonlystatic
接下来做nginx转发规则
- location /iqiyi_static/{
- proxy_pass http://iqiyi;
- }
- location /mmonly_static/{
- proxy_pass http://mmonly;
- }
转发到对应的地址上,即可完成,当然这样其实是大改了,对于项目较小改动还算可以,对于项目较大,那要改吐血了,不过能在一个nginx上部署多个项目,估计项目也大不了哪去
六、uwsgi相关参数和命令
注意,如果要使用pid,需要在uwsgi启动参数中指定 –pidfile,如:
#/etc/rc.local 修改自启动/usr/local/bin/uwsgi /var/www/html/mz_uwsgi.ini –pidfile /tmp/uwsgi.pid
常用命令
uwsgi –ini uwsgi.ini # 启动
uwsgi –reload uwsgi.pid # 重启
uwsgi –stop uwsgi.pid # 关闭
常用配置
chdir=/root/pyproject/flaskdemo1/
processes=2 # worker进程个数
http=0.0.0.0:8080 # 监听端口,测试时候使用
vacuum=true # 退出uwsgi是否清理中间文件,包含pid、sock和status文件
socket=%(chdir)/uwsgi/uwsgi.sock # socket文件,配置nginx时候使用
stats=%(chdir)/uwsgi/uwsgi.status # status文件,可以查看uwsgi的运行状态
pidfile=%(chdir)/uwsgi/uwsgi.pid # pid文件,通过该文件可以控制uwsgi的重启和停止
daemonize=%(chdir)/uwsgi/uwsgi.log # 日志文件,通过该文件查看uwsgi的日志
转载请注明:IT技术圈 » centos-uwgsi-nginx-flask