• 基于腾讯云CentOS7.4+MySQL5.7+Python3+uWSGI+Nginx的Django项目部署


    准备知识

    1、django
    一个基于python的开源web框架,请确保自己熟悉它的框架目录结构。

    2、uWSGI
    一个基于自有的uwsgi协议、wsgi协议和http服务协议的web网关

    3、nginx
    常用高性能代理服务器

    4、wsgi.py
    django项目携带的一个wsgi接口文件
    如果项目名叫mysite的话,此文件就位于[/mysite/mysite/wsgi.py]

    项目运行流程 

    1、首先客户端请求服务资源;
    2、Nginx作为直接对外的服务接口,接收到客户端发送过来的http请求,会解包、分析;
    3、如果是静态文件请求就根据Nginx配置的静态文件目录,返回请求的资源;
    4、如果是动态的请求,Nginx就通过配置文件,将请求传递给uWSGI;uWSGI 将接收到的包进行处理,并转发给WSGI;
    5、WSGI根据请求调用Django工程的某个文件或函数,处理完后Django将返回值交给WSGI;
    6、WSGI将返回值进行打包,转发给uWSGI,
    7、uWSGI接收后转发给Nginx,Nginx最终将返回值返回给客户端(如浏览器)。
    注:不同的组件之间传递信息涉及到数据格式和协议的转换

    说明:

    1、第一级的Nginx并不是必须的,uwsgi完全可以完成整个的和浏览器交互的流程;
    2、在Nginx上加上安全性或其他的限制,可以达到保护程序的作用;
    3、uWSGI本身是内网接口,开启多个work和processes可能也不够用,而Nginx可以代理多台uWSGI完成uWSGI的负载均衡;
    4、django在debug=False下对静态文件的处理能力不是很好,而用nginx来处理更加高效。

    为方便理解,uWSGI,WSGI和uwsgi在网站项目流程图中的功能如下:(图片来自博客:https://www.cnblogs.com/new-rain/p/10089941.html

    uWSGI,WSGI和uwsgi的区别

    (1)WSGI:全称 Web Server Gateway Interface,或者 Python Web Server Gateway Interface ,是为 Python 语言定义的 Web 服务器和 Web 应用程序或框架之间的一种简单而通用的接口。也可以认为WSGI是一种通信协议。自从 WSGI 被开发出来以后,许多其它语言中也出现了类似接口。

    WSGI 的官方定义是,Python Web Server Gateway Interface。从名字就可以看出来,这东西是一个Gateway,也就是网关。网关的作用就是在协议之间进行转换。

    WSGI 是作为 Web 服务器与 Web 应用程序或应用框架之间的一种低级别的接口,以提升可移植 Web 应用开发的共同点。WSGI 是基于现存的 CGI 标准而设计的。

    WSGI是 Web 服务器(uWSGI)与 Web 应用程序或应用框架(Django)之间的一种低级别的接口

    (2)uwsgi:是服务器和服务端应用程序的一种协议,规定了怎么把请求转发给应用程序和返回;uwsgi是一种线路协议而不是通信协议,在此常用于在uWSGI服务器与其他网络服务器的数据通信。

    (3)uWSGI:是一种 Python Web Server 或称为 Server/Gateway,uWSGI 是实现了 uwsgi 和 WSGI 两种协议的Web服务器,负责响应 Python 的 Web 请求。 

    因为Apache、Nginx等,它们自己都没有解析动态语言如 php 的功能,而是分派给其他模块来做,比如 Apache 就可以说内置了php模块,让人感觉好像Apache就支持 php 一样。 

    uWSGI实现了wsgi协议、uwsgi协议、http等协议。 Nginx中 HttpUwsgiModule 的作用是与 uWSGI 服务器进行交换。

    一、CentOS7.4自带Python2安装Python3

    # 查看python的执行位置

    which python

    # 安装依赖,使用yum安装

    yum -y groupinstall "Development tools"

    yum -y install zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel gdbm-devel db4-devel libpcap-devel xz-devel

    # 下载python3的安装包

    wget -c https://www.python.org/ftp/python/3.7.0/Python-3.7.0.tgz

    # 创建安装目录

    mkdir /usr/local/python3

    # 解压安装包

    tar -zxvf Python-3.7.0.tgz 

    # 进入解压目录

    cd Python-3.7.0

    # 编译源码包代码,--prefix参数,指定稍后源码包程序的安装路径

    ./configure --prefix=/usr/local/python3

    # 生成二进制安装程序

    make

    # 运行二进制的服务程序安装包

    make install

    注意,在这里可能会报以下错误

    File "/usr/local/src/Python-3.7.0/Lib/ctypes/__init__.py", line 7, in <module> from _ctypes import Union, Structure, Array ModuleNotFoundError: No module named ‘_ctypes‘ make: *** [install] Error 1

    安装libffi-devel即可解决,yum install libffi-devel,安装完记得再次运行 make install

    安装成功的界面:

    # 创建软链接,安装完成之后,建立软链接,添加变量,方便在终端中直接使用python3

    ln -s /usr/local/python3/bin/python3 /usr/bin/python3

    # pip3创建软链接,Python3安装完成之后pip3也一块安装完成,不需要再单独安装,一样建立软链接

    ln -s /usr/local/python3/bin/pip3 /usr/bin/pip3

    # 清理源码包临时文件

    make clean

    # 查看Python3和pip3安装情况

    二、安装MySQL

    安装的方式使用rpm包方式安装,要是想用yum安装见另一篇博客,https://www.cnblogs.com/opsprobe/p/10681063.html

    # 下载安装MySQL

    wget https://cdn.mysql.com//Downloads/MySQL-5.7/mysql-5.7.25-1.el7.x86_64.rpm-bundle.tar

    # 解压安装包

    tar -vxf mysql-5.7.25-1.el7.x86_64.rpm-bundle.tar

    # 查看mysql相关

    whereis mysql

    # 移除mysql相关的lib(可选项操作,建议操作)

    yum remove mysql-libs

    #安装mysql rpm相关的包,相互之见存在依赖关系,按照顺序安装 common --> libs --> clients --> server

    rpm -ivh mysql-community-common-5.7.25-1.el7.x86_64.rpm

    rpm -ivh mysql-community-libs-5.7.25-1.el7.x86_64.rpm

    rpm -ivh mysql-community-client-5.7.25-1.el7.x86_64.rpm

    rpm -ivh mysql-community-libs-compat-5.7.25-1.el7.x86_64.rpm

    rpm -ivh mysql-community-server-5.7.25-1.el7.x86_64.rpm

    下面的截图是其他机器上用yum安装时的显示,可以看到依赖关系:

    注意:安装时可能会报以下错误:安装yum -y install numactl,即可解决

    # 这个在后面安装 msyqlclient 需要依赖的包 rpm -ivh mysql-community-devel-5.7.25-1.el7.x86_64.rpm

    # 安装完成之后,启动服务

    systemctl start mysqld

     

    注意: 可能出现警告 [warning: mysql-community-server-5.7.19-1.el6.x86_64.rpm: Header V3 DSA/SHA1 Signature, key ID 5072e1f5: NOKEY](https://www.cnblogs.com/royfans/p/7243641.html)

    解决方法,安装时加上命令:rpm -ivh mysql-community-server-5.7.19-1.el6.x86_64.rpm --force --nodeps

     

    # 查看服务状态

    systemctl status mysqld

    至此MySQL安装完成

    配置MySQL相关:修改MySQL密码

    # 登录mysql

    mysql -u root -p

    # 在此时需要密码,密码隐藏在log中,查找默认随机密码

    grep 'password' /var/log/mysqld.log

    然后执行 mysql -u root -p ,输入上面查到的密码进入,用该密码登录后,必须马上修改新的密码,不然操作会报如下错误:

    # 修改密码,获取随机密码之后,登录修改密码(由于mysql密码策略限制,密码需要包含大小写数字,特殊字符)

    alter user 'root'@'localhost' identified by 'xxxxx';(或者用 set password=password("youpassword");)

    密码设置太简单,会报以下错误

     这个其实与validate_password_policy的值有关。

    validate_password_policy有以下取值:

    默认是1,即MEDIUM,所以刚开始设置的密码必须符合长度,且必须含有数字,小写或大写字母,特殊字符。
    有时候,只是为了自己测试,不想密码设置得那么复杂,譬如说,我只想设置root的密码为123456。
    必须修改两个全局参数:

    首先,修改validate_password_policy参数的值

    mysql> set global validate_password_policy=0;

    validate_password_length(密码长度)参数默认为8,我们修改为1

    mysql> set global validate_password_length=1;

    完成之后再次执行修改密码语句即可成功

    mysql> alter user 'root'@'localhost' identified by '123456';

    刷新权限

    flush privileges;

    重新登录MySQL

    mysql -u root -p

     

    安装virtualenv ,建议大家都安装一个virtualenv,方便不同版本项目管理(pip3安装的包都在 /data/environment/lab_reports/lib/python3.7/site-packages/ 目录下)。

    pip3 install virtualenv

    在这里要是出现如下错误提示,就需要更新pip

    运行以下命令更新pip,更新pip完成后重新运行命令pip3 install virtualenv

    python3 -m pip install --upgrade pip

     

    建立软链接

    ln -s /usr/local/python3/bin/virtualenv /usr/bin/virtualenv

     

    安装成功在根目录下建立两个文件夹,主要用于存放environment和网站文件的。(个人习惯,其它人可根据自己的实际情况处理)

    mkdir -p /data/environment

    mkdir -p /data/wwwroot

    切换到 cd /data/environment/ 下,创建指定版本的虚拟环境。

    virtualenv --python=/usr/bin/python3 blog(blog是自定义的)

    然后进入cd /data/environment/blog/bin/

    启动虚拟环境:source activate

    退出虚拟环境:deactivate

     

    留意红框标记的位置,出现(blog),说明是成功进入虚拟环境。(注意:以下的操作都需要在虚拟环境下进行)

     

    安装Django:

    pip3 install django (如果用于生产的话,则需要指定安装和你项目相同的Django版本)

    例如:在Windows下查看Django的版本,如下图所示,可以看到是2.1.5版本的Django

    在服务器上虚拟环境下安装2.1.5版本的Django

    pip3 install django==2.1.5

    卸载指定版本 django 的命令

    pip3 uninstall django==2.1.5

    在本地生成并导出依赖包(导出依赖包的两种方式,参考自其他博客:https://www.cnblogs.com/clement-jiao/p/9905611.html

    # 进入项目目录,运行以下命令,导出依赖包,我是在PyCharm下操作的

    pip3 freeze > requirements.txt

    或者:pipreqs ./ --encoding=utf8

    # 导出的默认位置就在项目的根目录下

    Django 静态文件收集

    命令:python manage.py collectstatic

    运行静态文件收集命令时,先需要在 settings.py 里配置这个STATIC_ROOT,收集完后,还需要改回来。

    注意!!!

    它可能会和 STATICFILES_DIRS 冲突,视情况而定。

    Django 静态文件,自强学堂做了很好的说明:https://code.ziqiangxuetang.com/django/django-static-files.html

    切换到网站目录/data/wwwroot,上传Django项目到这里,包括刚生成的项目依赖文件requirements.txt

    安装依赖包

    # 安装项目依赖(注意:安装依赖时可能会有错误,请百度自行解决)

    pip3 install -r requirements.txt

    # 接下来需要先在MySQL数据库里手动新建项目连接的数据库,然后在项目目录下,运行下面的命令进行数据库表的初始化操作

    python3 manage.py makemigrations

    python3 manage.py migrate

    测试运行项目

    # 运行项目,0.0.0.0地址为任意客户端IP都可以访问,端口自定义

    python3 manage.py runserver 0.0.0.0:8000

    # 在客户端的浏览器通过服务器的公网地址访问项目,若能访问到项目,说明项目部署成功。

    Django正常运行之后我们就开始配置uWSGI和nginx,接着还是在虚拟环境里用pip3安装uWSGI

    pip3 install uWSGI

    在项目根目录下创建uwsgi.ini文件,输入如下内容:

    # 指定uwsgi配置
    [uwsgi]
    # 指定部署项目之后的HTTP访问,和后面Nginx配置文件里的uwsgi_pass 127.0.0.1:8080处要一致
    socket = 127.0.0.1:8080
    #http=47.106.218.225:8080(使用uwsgi代理时)
    # 指定项目的绝对路径
    chdir=/data/wwwroot/blogs/mysite
    # 指定wsgi文件
    wsgi-file=mysite/mysite/wsgi.py
    # 指定启动进程数量processes/workers
    processes=4
    # 指定启动线程数量
    threads=2
    # 指定启动主进程管理
    master=true
    # 指定存放进程编号的id文件
    pidfile=uwsgi.pid
    # 指定进程停止时清楚垃圾数据
    vacuum=true
    # 指定启用日志记录(这里指定了uWSGI日志的存储路径。)
    daemonize=uwsgi.log
    # 指定静态文件映射
    #static-map=/static=static_file(使用uwsgi代理时)

    :wq 退出,保存

    至此,uwsgi+django就完美结合了,但是,光有uwsgi还不够,uwsgi处理动态请求能力高,但对于静态请求(如static文件,css,js文件等)处理能力差,此时就要结合nginx一起使用

     

    安装nginx和配置nginx.conf文件(nginx下载地址:http://nginx.org/en/download.html

    wget -c http://nginx.org/download/nginx-1.16.0.tar.gz

    下载完成后,执行解压命令:

    tar -zxvf nginx-1.16.0.tar.gz

    进入解压后的nginx-1.16.0/目录:cd nginx-1.16.0/

    依次执行以下命令:

    ./configure

    make

    make install

    make clean

     

    nginx一般默认安装好的路径为/usr/local/nginx
    在/usr/local/nginx/conf/中先备份一下nginx.conf文件,以防意外。

    cp nginx.conf nginx.conf-backup

     

    然后打开nginx.conf,把原来的内容删除,直接加入以下内容:

    worker_processes 1;
    events {
    worker_connections 1024;
    }
    http {
    include mime.types;
    default_type application/octet-stream;
    sendfile on;
    server {
    listen 90;    # 我要监听那个端口
    server_name 172.27.0.6;   # 服务器上ifconfig命令查出来的IP地址
    charset utf-8;   # Nginx编码

    access_log   /data/wwwroot/blogs/mysite/nginx_access.log;
    error_log   /data/wwwroot/blogs/mysite/nginx_error.log;      # access_log和error_log是定义nginx访问日志和错误日志的存放路径。 


    location / {
    include uwsgi_params;
    uwsgi_pass 127.0.0.1:8080;   # 是指uWSGI绑定的监听地址,端口与原来的uwsgi.ini中设置的端口一致
    uwsgi_param UWSGI_SCRIPT mysite.wsgi;
    uwsgi_param UWSGI_CHDIR /data/wwwroot/blogs/mysite/;  # 项目的绝对路径
     }

    # 指定静态文件路径
    location /static/ {
    alias /data/wwwroot/blogs/mysite/static/;
    }
    }
    }

    这里需要注意的就是项目路径,一定要写对,我刚开始就把项目路径搞错了,导致花了很多时间去找错误。 

     

    启动项目,访问项目的页面。(再次提醒,注意:以下操作是在虚拟环境下进行)

    进入cd /usr/local/nginx/sbin/目录

    执行 ./nginx -t 命令先检查配置文件是否有错,没有错就执行以下命令,启动nginx:

    ./nginx

    终端没有任何提示就证明nginx启动成功。

    重启nginx命令:./nginx -s reload(注意:nginx启动时,才能使用该命令,否则会报错)

     

    进入网站项目目录

    cd /data/wwwroot/blogs/mysite

    执行下面命令,通过配置文件启动:

    uwsgi --ini uwsgi.ini

    # 停掉uwsig

    uwsgi --stop uwsgi.pid

     

    以上步骤都没有出错的话,就在客户端浏览器里访问你的项目地址!(服务器的IP地址:nginx的端口号/项目路径)

    如果启动时就报错,查看终端信息,解决错误。 

    如果终端没有报错,但是浏览时出现500、502等错误,就去项目目录查看nginx日志和uWSGI日志,解决错误。

    ps aux命令

    a:显示现行终端机下的所有程序,包括其他用户的程序

    u:以面向用户的格式显示进程

    x:显示所有程序,不以终端机来区分

    # 分别查看系统nginx和uwsgi进程信息

    ps aux | grep nginx

    ps aux | grep uwsgi

    # 强制杀死nginx和uwsgi的进程

    killall -9 nginx

    killall -9 uwsgi

     

    查看python安装路径以及pip安装的包,参考自其它博客:https://blog.csdn.net/mr_cat123/article/details/80435861

    CentOS7设置Nginx为开机启动:参考自博客:https://www.cnblogs.com/xiaojf/p/7891345.html

  • 相关阅读:
    Runloop 新的看法
    如何利用openCV做灰度图片
    WebViewJavascriptBridge使用说明(iOS)
    页面滑动返回和点击返回按钮动作实现;
    获取设备UDID、IMEI、ICCID、序列号、Mac地址等信息
    设计模式----单例模式
    多线程理论知识 -- 小白的教程
    SQLite 的创建与编辑
    strong,weak, retain, assign的区别
    CGContextRef 画线简单用法
  • 原文地址:https://www.cnblogs.com/opsprobe/p/10507203.html
Copyright © 2020-2023  润新知