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

  1. yum -y install wget

 

2.3.1安装zlib

  1. wget http://www.zlib.net/zlib-1.2.11.tar.gz
  2.  
  3. tar -zxvf zlib-1.2.11.tar.gz
  4.  
  5. cd zlib-1.2.11
  6.  
  7. ./configure
  8.  
  9. make
  10.  
  11. make install

如果没有make,安装make

  1. yum install make

默认在会安装在/usr/local/lib 下,这个在安装过程中,有显示的

2.3.2安装openssl-devel

  1. yum install openssl-devel;
  1. yum install sqlite-devel
  2. #以下要是安装报错可以忽略
  3. yum install sqlite2
  4. yum install tcl-devel
  5. yum install tk_devel

2.3.3安装python3

进入到/usr/bin目录下

  1. cd /usr/bin

备份原来python

  1. mv python python.back

下载python3.5.1

  1. wget https://www.python.org/ftp/python/3.5.1/Python-3.5.1.tgz

解压缩

  1. tar -zxvf Python-3.5.1.tgz

删除安装包

  1. rm -rf Python-3.5.1.tgz

进入安装包目录

  1. cd Python-3.5.1

运行配置脚本,指定zlib位置(重要)有可能也不需要加zlib

  1. ./configure --with-zlib=/usr/local/lib 

编译

  1. make

安装

  1. make install

查看python版本

  1. python3.5 -V

2.3.4建立软连接(不建议使用,不影响后续使用)

建立软连接

  1. ln -s /usr/local/bin/python3.5 /usr/bin/python

#修改yum配置文件

  1. vim /usr/bin/yum

把头文件#!/usr/bin/python改为#!/usr/bin/python2.7   #因为yum需要依赖2.7版本

  1. vim /usr/libexec/urlgrabber-ext-down

把头文件#!/usr/bin/python改为#!/usr/bin/python2.7   #因为yum需要依赖2.7版本

2.4创建虚拟环境

2.4.1安装virtualenv

  1. pip install virtualenv

创建python环境目录,默认是python2                     

  1. virtualenv venv

2.4.2指定python环境(这步如果没安装zlib会出现错误)                 

  1. virtualenv -p /usr/bin/python3.5   

2.4.3激活虚拟环境

  1. source venv/bin/activate

2.4.4退出虚拟环境(前面那个点不能少)

  1. .venv/bin/deactivate

2.5安装flask(在虚拟环境中安装)

  1. pip install flask

准备2flask工程,这里的flask程序可以是你已经开发完成的

这里我的工程一个叫做在线编译,其中flask的程序在在线编译文件夹下的在线编译.py,一个叫做flaskdemo1文件夹下的flaskdemo1.py,这2个程序我放在/root/pyproject

分别运行2个程序,测试是否能够在服务器上正常运行,测试的方法是直接运行flask的那个文件

  1. 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

  1. pip install uwsgi

如果报错you need a C compiler to build uWSGI,说明没有c的编译环境

  1. yum install -y gcc gcc-c++

 

执行uwsgi有2种方式

1、命令行方式

2、配置文件方式

使用命令行

进入到和这个文件夹同级下,比如进入/root/pyproject/在线编译文件夹下,输入以下命令启动uwsgi

  1. 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/在线编译/  具体命令如下

  1. 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

  1. vim uwsgi.ini

输入以下内容([uwsgi]一定不能少)

  1. [uwsgi]
  2. #启动程序所使用的地址和端口
  3. http=0.0.0.0:5000
  4. #记录pid,方便停止和重启服务
  5. pidfile=/tmp/uwsgi.pid
  6. #项目所在路径
  7. chdir=/root/pyproject/在线编译/
  8. #flask程序启动文件
  9. wsgi-file=在线编译.py
  10. #使用主进程
  11. master=true
  12. #多站点(这个可以不配置)
  13. vhost=true
  14. #flask里面启动Application变量名
  15. callable=app
  16. #进程数
  17. processes=4
  18. #线程数
  19. threads=2
  20. manage-script-name = true

配置完成后使用如下命令进行启动

  1. 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进行删除

  1. ps aux| grep uwsgi    

3.2.2可以编写脚本来方便删除,通过vim stop.sh

  1. #!/bin/sh
  2. NAME="uwsgi"
  3. if [ ! -n "$NAME" ];then
  4.     echo "no arguments"
  5.     exit;
  6. fi
  7. echo $NAME
  8. ID=`ps -ef | grep "$NAME" | grep -v "$0" | grep -v "grep" | awk '{print $2}'`
  9. echo $ID
  10. echo "################################################"
  11. for id in $ID
  12. do
  13. kill -9 $id
  14. echo "kill $id"
  15. done
  16. echo  "################################################"

编写后记得赋值权限后才能使用,通过chmod 777 stop.sh,使用的时候./stop.sh即可全部停止

3.2.3方法2(不好用,限制多,还未必能停)

进行关闭

  1. 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.iniuwsgi1.ini这2个配置文件

如何启动帝王模式

为2个应用在线编译项目和flaskdemo1项目编写ini

因为之前编写了在线编译这个的ini,现在编写flaskdemo1的ini,在flaskconfig文件夹

cp uwgsi.ini uwgsi1.ini

修改uwgsi1.ini(红色部分是修改部分)

  1. [uwsgi]
  2. #启动程序所使用的地址和端口
  3. http=0.0.0.0:5001
  4. #记录pid,方便停止和重启服务
  5. pidfile=/tmp/uwsgi.pid
  6. #项目所在路径
  7. chdir=/root/pyproject/flaskdemo1/
  8. #flask程序启动文件
  9. wsgi-file=flaskdemo1.py
  10. #使用主进程
  11. master=true
  12. #多站点
  13. vhost=true
  14. #flask里面启动Application变量名
  15. callable=app
  16. #进程数
  17. processes=4
  18. #线程数
  19. threads=2
  20. manage-script-name = true

注意

这2个配置文件中要求端口不一样才可以,否则启动会冲突的(因为如果项目1中也有根目录,项目2中也有根目录,同端口,你无法区别是选用哪个项目的)

这2个配置文件在同一个文件夹下/root/pyproject/flaskconfig/

启动uwsgi帝王模式

  1. uwsgi --emperor /root/pyproject/flaskconfig/ -d my.log

其中,flaskconfig文件夹里包含了各个app的配置文件,这个文件夹将会被emperor一直监视,只要有配置文件的修改或新建,app实例就会被重新加载或新建,可以通过软链接将实际项目中的配置文件链接到vassal文件夹目录下:

emperor监视的是配置文件目录,但是问题来了,如果代码进行改动了,这次更新并没有对配置文件进行修改,实例自然就不会重新启动了。 
幸好配置文件提供了touch-reload选项,只要指定文件夹发生改动就重启实例:

  1. touch-reload = /root/pyproject/flaskdemo1/

相当于是对uwsgi.ini和uwsgi1.ini下进行添加以上参数,值是对应项目文件夹

四、开机自启动脚本

4.1、基本设置

开机后,需要自动启动uwsgi以及其他服务,比如我服务器上开机需要启动Tomcat,这就需要开机自启动,配置流程如下

1、vim修改/etc/rc.d/rc.local文件

在这个文件中添加脚本,我的脚本如下

  1. #!/bin/bash
  2. # THIS FILE IS ADDED FOR COMPATIBILITY PURPOSES
  3. #
  4. # It is highly advisable to create own systemd services or udev rules
  5. # to run scripts during boot instead of using this file.
  6. #
  7. # In contrast to previous versions due to parallel execution during boot
  8. # this script will NOT be run after all other services.
  9. #
  10. # Please note that you must run 'chmod +x /etc/rc.d/rc.local' to ensure
  11. # that this script will be executed during boot.
  12. #自带的,不用管
  13. touch /var/lock/subsys/local
  14. #启动Java的Tomcat
  15. /home/apache-tomcat-9.0.6/bin/startup.sh
  16. #激活Python虚拟环境
  17. source /root/venv/bin/activate
  18. #启动uwsgi帝王模式
  19. uwsgi --emperor /root/pyproject/flaskconfig/ -d /root/pyproject/myuwsgi.log

 

2、对rc.local赋权限

  1.     chmod 777 /etc/rc.d/rc.local

3、重启服务器

  1.     reboot

以上就可以完成开启自启动了,但是每次修改rc.local很麻烦,所以我们把他抽离出来,在root文件夹下建立autostart.sh

  1. #!/bin/bash
  2. /home/apache-tomcat-9.0.6/bin/startup.sh
  3. source /root/venv/bin/activate
  4. uwsgi --emperor /root/pyproject/flaskconfig/ -d /root/pyproject/myuwsgi.log

对autostart.sh赋值权限

  1. chmod 777 autostart.sh

最后修改/etc/rc.d/rc.local

  1. #!/bin/bash
  2. # THIS FILE IS ADDED FOR COMPATIBILITY PURPOSES
  3. #
  4. # It is highly advisable to create own systemd services or udev rules
  5. # to run scripts during boot instead of using this file.
  6. #
  7. # In contrast to previous versions due to parallel execution during boot
  8. # this script will NOT be run after all other services.
  9. #
  10. # Please note that you must run 'chmod +x /etc/rc.d/rc.local' to ensure
  11. # that this script will be executed during boot.
  12. touch /var/lock/subsys/local
  13. /root/autostart.sh

以后每次修改我们的autostart.sh即可对开启自启动项进行配置了

以后部署项目就在/root/pyproject下上传项目,在flaskconfig下添加启动文件即可完成,更新项目只需要更新对应的项目文件夹即可

五、配置Nginx

uwsgi的并发处理能力还是低下的,所以上层需要进行大并发处理,搭建Nginx做上层转发处理
5.1、下载与安装

  1. #下载
  2. cd /home
  3. wget -c https://nginx.org/download/nginx-1.10.3.tar.gz
  4. #解压缩
  5. tar -zxvf nginx-1.10.3.tar.gz
  6. #进入Nginx目录
  7. cd nginx-1.10.3
  8. #设置配置信息
  9. ./configure

5.2、相关错误解决办法
错误为:./configure: error: the HTTP rewrite module requires the PCRE library.
安装pcre-devel解决问题

  1. 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.
解决办法:

  1. yum -y install openssl openssl-devel

5.3、编译

  1. make
  2. make install

OK,所有的工作都已经做完啦,下面开始启动Nginx服务并在远程测试,想想是不是很激动。
一般编译安装完的软件都会放在/usr里,这不是user,这是Unix System Resource,是Unix系统资源的缩写。

5.4、启动与停止
在/usr/local/里面发现了nginx,进入。

  1. cd /usr/local/nginx/

如果你找不到,试试这条命令吧

  1. #whereis nginx

它会告诉你nginx在哪,nginx的命令在/usr/local/nginx/sbin目录下
对于nginx的启动,停止

  1. ./nginx           #启动
  2. ./nginx -s stop   #停止
  3. ./nginx -s quit   #退出
  4. ./nginx -s reload #刷新

5.5、单项目配置负载均衡

  1. cd /usr/local/nginx/conf/
  2. vim nginx.conf

在http的大括号内添加如下内容

  1. upstream app1{
  2. server 0.0.0.0:5001  max_fails=2 fail_timeout=600s weight=10;
  3. }

在上述项目中,我们配置在uwsgi下有2个项目,一个是5000一个是5001,访问地址,出现不同的内容,这样方便我们验证消息转发,配置文件修改如下

  1. upstream app1{
  2. server 0.0.0.0:5000  max_fails=2 fail_timeout=600s weight=10;
  3. server 0.0.0.0:5001  max_fails=2 fail_timeout=600s weight=10;
  4. }

在开发环境中,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端口

  1. cd ../sbin

启动nginx

  1. ./nginx

没报错就说明启动了
停止nginx

  1. ./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外添加

  1. #java项目路由
  2. upstream java{
  3. server 0.0.0.0:8080 max_fails=2 fail_timeout=600s weight=10;
  4. }

在server内添加

  1. location /java/{
  2.     root html;
  3.             rewrite ^/java/(.*) /$1 break;
  4.             proxy_pass http://java;
  5.         }

这是做什么呢,相当于进行判断地址以/java/为开头在转发的时候,去掉/java/这段在进行转发,因为/java/是我们自己添加的,在原有地址中不存在,root html;是访问根目录时候必不可少的

以此类推,在server外添加以下路径

  1.     #java项目路由
  2.     upstream java{
  3.        server 0.0.0.0:8080 max_fails=2 fail_timeout=600s weight=10;
  4.         }
  5.     #python 在线编译路由
  6.     upstream python1{
  7.        server 0.0.0.0:5000 max_fails=2 fail_timeout=600s weight=10;
  8.         }
  9.     #python flaskdemo1路由
  10.     upstream python2{
  11.        server 0.0.0.0:5001 max_fails=2 fail_timeout=600s weight=10;
  12.      }

在server内添加

  1.        #转发java
  2.         location /java/{
  3.             root html;
  4.             rewrite ^/java/(.*) /$1 break;
  5.             proxy_pass http://java;
  6.         }
  7.         #转发在线编译
  8.          location /python1/{
  9.             root html;
  10.             rewrite ^/python1/(.*) /$1 break;
  11.             proxy_pass http://python1;
  12.         }
  13.         #转发flaskdemo
  14.          location /python2/{
  15.             root html;
  16.             rewrite ^/python2/(.*) /$1 break;
  17.             proxy_pass http://python2;
  18.         }

重启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中

  1. #!/bin/bash
  2. /home/apache-tomcat-9.0.6/bin/startup.sh
  3. source /root/venv/bin/activate
  4. uwsgi --emperor /root/pyproject/flaskconfig/ -d /root/pyproject/myuwsgi.log
  5. /usr/local/nginx/sbin/nginx

以后每次重启服务器,就不用担心写一堆命令行了

部署java项目,直接丢进tomcat下的webapp下即可

部署python项目,丢进pyproject下,在pyproject/flaskconfig项目下编写ini即可

最后重启服务器reboot即可完成

以上步骤,在Python多项目部署时候,会出现所有静态资源丢失,解决办法如下

1、对Python多个项目中的static中内容,集中放在一起,Nginx对静态资源做加载,Nginx配置如下

  1. location /static/{
  2.          root /home/;
  3.     }

在你的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项目做如下修改

  1. app = Flask(__name__,static_url_path='iqiyistatic')

mmonly项目如下修改

  1. app = Flask(__name__,static_url_path='mmonlystatic')

在程序的模板中拼接地址,还可能固定写死的static,也需要进行修改

这样地址访问的规则,就从ip地址:端口:static变为ip地址:端口:iqiyistatic或者ip地址:端口:mmonlystatic

接下来做nginx转发规则

  1. location /iqiyi_static/{
  2. proxy_pass http://iqiyi;
  3. }
  4. location /mmonly_static/{
  5. proxy_pass http://mmonly;
  6. }

转发到对应的地址上,即可完成,当然这样其实是大改了,对于项目较小改动还算可以,对于项目较大,那要改吐血了,不过能在一个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是否清理中间文件,包含pidsockstatus文件

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

 

posted on 2018-12-05 14:49  A-Way  阅读(510)  评论(0编辑  收藏  举报

导航