部署到生产环境

我们前面的代码都是在我们自己的电脑(通常是Windows操作系统)上面运行的,因为我们还处于开发过程中。

当我们完成一个阶段的开发任务后,就需要把我们开发的网站服务,给真正的用户使用了。

那就需要我们的 网站 部署在公网机器上,而不是我们的个人电脑。 这个给真正用户使用的网站服务器我们通常称之为 生产环境

通常,我们的web服务是部署在云服务厂商的云主机上,比如阿里云的ECS云主机。当然如果你们公司有自己的机房和公网服务器,当然也可以。

现在的web服务,基本都是采用 Linux 操作系统。 而且生产环境不应该使用 SQLite 数据库,通常是 MySQL、Postgresql、Oracle等。

本章内容就是教大家,如何把基于Django的web系统部署到生产环境,也就是 如何 在Linux操作系统上安装 我们 网站系统,包括我们的代码和MySQL数据库服务。

首先,需要大家有 Linux 和MySQL的 基础知识。如果你还没有掌握,点击这里学习白月黑羽的Linux 和MySQL的基础教程

架构说明

一个大型的网站系统,架构通常非常的复杂,包括很多的功能节点。大家可以以后慢慢学习。

当前,我们先从基础的架构学起。

可能你会说,我们前面已经把网站运行起来了呀,现在只需要把系统从 Windows 转移到Linux上了,把SQLite 改为 MySQL就行了吧?

不仅如此,认真学习课程的同学应该记得,我们前面曾经讲过如下两点:

  • Django 在生产环境不应该处理静态资源(比如网页、图片等)的请求

    前面是开发阶段,为了是环境搭建容易,我们还是让Django来处理静态资源的请求了。

    在生产环境不能这样做,这里我们使用Nginx来处理静态资源的请求。

  • Django 在生产环境 不能直接处理 HTTP请求

    Django是 wsgi web application 的框架,它只有一个简单的单线程 wsgi web server。 供调试时使用。性能很低。

    在生产环境必须提供 专业的 wsgi web server,比如 uWSGI 或者 Gunicorn。 我们这里使用 Gunicorn。

    而且即使有了 uWSGI 或者 Gunicorn,我们最好还要在前面设置 Nginx 。所有的客户请求由它先接受,再进行相应的转发。

    为什么要这样?

    Nginx 在整个后端的最前方, 可以实现 负载均衡、反向代理、请求缓存、响应缓存 、负荷控制等等一系列功能。可以大大的提高整个后端的性能和稳定性。

综上, 我们当前这个简单网站,其架构图如下

image

这里为了简单,把整个后端系统都部署在同一台Linux主机上,包括:Nginx、Gunicorn、Django(包括我们的代码)、MySQL服务。

在实际项目中,如果系统的负荷比较大,通常是部署在多台主机上。

这个架构的各个子系统是如何协同工作的?

  • Nginx

    Nginx 运行起来是多个进程,接收从客户端(通常是浏览器或者手机APP)发过来的请求。

    它会 根据请求的URL 进行判断:

    如果请求的 是 静态资源,比如HTML文档、图片等,它直接从配置的路径进行读取,返回内容给客户端。

    如果请求的 是 动态数据, 转发给 Gunicorn+Django 进行处理

  • Gunicorn/Django

    Gunicorn 和 Django 是运行在同一个 Python进程里面的。 它们都是用Python代码写的程序。

    启动Gunicorn的时候,它会根据配置加载Django的入口模块,这个入口模块里面提供了WSGI接口。

    当 Gunicorn 接收到 Nginx 转发的 HTTP请求后,就会调用 Django的 WSGI入口函数,将请求给Django进行处理。

    Django框架 再根据请求的URL 和 我们项目配置的 URL 路由表,找到我们编写的对应的消息处理函数进行处理。

    我们编写的消息处理函数,就是前面章节大家学习到的,处理前端请求。如果需要读写数据库,就从MySQL数据库读写数据。

安装步骤

前面我们说过,通常,我们的web服务是部署在云服务厂商的云主机上,比如阿里云的ECS云主机。

这里大家练习的时候,可以先用一台安装了Linux的虚拟机。

我们这里以一台安装了 CentOS 7 的虚拟机为例,给大家演示如何安装部署环境。

白月黑羽的有如何安装 CentOS 的视频教程,大家可以点击这里,根据此教程 先安装好 CentOS 7

做好产品发布包

以后当你负责产品发布,你需要准备发布的产品包。

产品的发布包,是不是只是需要把你的代码 用zip打个包?

不是那样简单的。

稍微复杂写的产品都会 涉及到好多子系统,前端通常包括 web前端、app前端, 后端 包括 业务处理系统、数据库系统、消息队列、异步任务系统、缓存系统等等。

为了保证这些子系统能在生产环境 友好配合 , 需要仔细的规划、配置、产生发布包。


我们先从基本的做起,我们现在的系统 包括 web前端系统(包括web前端的HTML、css、图片、js业务代码、js库等文件)、业务处理系统、数据库系统。

需要做到产品发布包里面的 包括 web前端系统 和 业务处理系统 的代码。

不同的运营架构,部署的方式不同,需要构建发布包的方式也不同。

这里,根据我们的架构图,可以把 前端系统代码 做在一个发布包中, 后端系统做在另一个发布包中。

我们完全可以 把 前后端系统 分别部署到 两台 Linux主机上。当有请求需要Django后端业务系统处理的时候,转发给Django所在的主机即可。 如果请求只是获取一些静态资源,比如HTML、图片等,在前端主机处理完即可。 这样 做到 部署的前后端分离。

目前我们先按照简单的来, 根据我们的架构图, 都部署在同一台机器上。


首先,我们需要为当前版本的发布,准备 web前端发布包,和web后端发布包。

现在我们假定发布的 版本号为 1.5

前端发布包,由前端开发人员提供, 点击这里下载前端开发人员提供的发布包


你们作为后端的开发人员,当然由你提供,后端的发布包。

基于Django开发的后端系统,要发布正式版本:

  • 首先应该 修改项目配置文件中的配置项DEBUG值为 False。

修改 ./bysms/settings.py ,把下面的 配置项DEBUG值为 False

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
  • 把数据库改为生产环境的数据库

前面我们为了开发简单,一直用的SQLite数据库,现在需要改为生产环境的MySQL数据库。

按照如下示例,修改 ./bysms/settings.py

#DATABASES = {
#   'default': {
#        'ENGINE': 'django.db.backends.sqlite3',
#       'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
#    }
#}

DATABASES = {
  'default': {
      'ENGINE': 'django.db.backends.mysql',
      'NAME': 'bysms',   # 数据库名
      'USER': 'byhy',    # 数据库 用户名
      'PASSWORD': 'Mima123$',# 数据库 用户密码
      'HOST': '127.0.0.1', # 数据库服务主机名
      'PORT': '3306',      # 数据库服务端口
      'CONN_MAX_AGE': 0, 
      'OPTIONS': {
             "init_command": "SET storage_engine=INNODB",
      }
  }
}

当然,上面配置的 MySQL连接的 用户名、密码、数据库名、数据库服务主机名、端口 都要和你的环境匹配。

  • 添加 Linux 启动shell脚本

生产环境,我们使用 Gunicorn 作为 Django的WSGI前端,首先我们需要创建一个 Gunicorn启动配置文件 ./bysms/gunicorn_conf.py ,内容如下

# gunicorn/django  服务监听地址、端口
bind = '127.0.0.1:8000'

# gunicorn worker 进程个数,建议为: CPU核心个数 * 2 + 1
workers =  3 

# gunicorn worker 类型, 使用异步的event类型IO效率比较高
worker_class =  "gevent"  

# 日志文件路径
errorlog = "/home/byhy/gunicorn.log"
loglevel = "info"

import sys,os

cwd = os.getcwd()
sys.path.append(cwd)

要保证我们的Django后端服务在linux上一个命令就能启动,需要开发一个 Linux 启动shell脚本 ./run.sh

可以参考下面的 shell脚本内容

#!/bin/bash
DIR="$( cd "$( dirname "$0" )" && pwd )"
echo $DIR

cd $DIR

# ulimit -n 50000
nohup gunicorn --config=bysms/gunicorn_conf.py bysms.wsgi &> /dev/null &
  • 我们可以在该文件的末尾,加上版本号
VERSION = '1.5'

然后,我们把整个Django后端的代码打包,包名为 bysms_back_v1.5.zip

安装、配置 Nginx

大家首先以root 用户 登录 CentOS 主机,按照下面的步骤安装Nginx

  • 先执行命令 yum install gcc 确保gcc编译器安装好

  • 先 安装Nginx依赖包 ,执行命令 yum -y install pcre-devel openssl openssl-devel

  • 下载、编译、安装 Nginx

    执行命令 wget http://nginx.org/download/nginx-1.15.5.tar.gz 下载Nginx代码包;

    执行命令 tar zxvf nginx-1.15.5.tar.gz 解压 代码包

    执行命令 cd nginx-1.15.5 进入到代码目录

    执行命令 ./configure --prefix=/usr/local/nginx --with-http_ssl_module 配置编译安装选项

    执行命令 make && make install 编译安装


接下来我们需要配置Nginx。

安装上面的安装方式,Nginx的配置文件路径是:/usr/local/nginx/conf/nginx.conf

当然我们可以使用vi去编辑这个文件,但是白月黑羽建议大家使用 winscp 连接 Linux主机并且,配置用notepad++远程打开。因为这样看起来更清楚,特别是配置文件中如果有中文,vi看起来可能会比较乱。具体操作参考我们的视频讲解。

打开 Nginx 配置文件 /usr/local/nginx/conf/nginx.conf ,修改其中的配置项,以满足你的网站需求。

下面是一个Nginx配置示例,列出了其中核心的配置

user  byhy;          # 用byhy用户运行Nginx进程
worker_processes  2; # 启动两个Nginx worker 进程

events {
    # 每个工作进程 可以同时接收 1024 个连接
    worker_connections  1024; 
}

# 配置 Nginx worker 进程 最大允许 2000个网络连接
worker_rlimit_nofile 2000;

http {
    include       mime.types;
    default_type  application/octet-stream;

    sendfile        on;

    keepalive_timeout  30;

    gzip  on;
    
    # 配置 动态服务器(比如Gunicorn/Django)
    # 主要配置 名称(这里是apiserver) 地址和端口    
    upstream apiserver  {

        # maintain a maximum of 20 idle connections to each upstream server
        keepalive 20;

        server 127.0.0.1:8000; # 地址和端口
    }
   
    # 配置 HTTP 服务器信息
    server {
        # 配置网站的域名
        server_name  www.byhy.com;  

        # 配置访问静态文件的根目录,        
        root /home/byhy/bysms_frontend;
        
        # 配置动态数据请求怎么处理
        # 下面这个配置项说明了,当 HTTP 请求 URL以 /api/ 开头,
        # 则转发给 apiserver 服务器进程去处理        
        location /api/      {
            proxy_pass         http://apiserver;
            proxy_set_header   Host $host;
        }
    }

}


启动 Nginx

启动Nginx,必须以root用户执行。

执行命令 /usr/local/nginx/sbin/nginx ,即可启动Nginx服务。


如果启动报错,你需要查看日志文件,可以打开 /usr/local/nginx/logs/error.log 查看错误日志文件。


如果你修改了配置文件,需要重启Nginx,可以执行如下命令

/usr/local/nginx/sbin/nginx -s reload


如果需要关闭Nginx服务,可以执行如下命令

/usr/local/nginx/sbin/nginx -s stop

安装 python 3.6

现在的Linux上缺省安装的都是 Python 2, 现在开发基本都是使用Python 3了, 所以需要我们手工安装 Python 3

我们选择 3.6 的Python版本,目前最为主流支持。

  • 执行下面的命令 安装必需的库

yum 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 https://www.python.org/ftp/python/3.6.8/Python-3.6.8.tgz
tar zxf Python-3.6.8.tgz

执行下面的命令进入代码目录、配置、编译、安装

cd Python-3.6.8 ; ./configure ; make && make install

这样安装后, pip 程序的路径应该是 /usr/local/bin/pip3

安装 Django

比较简单,执行命令 pip3 install Django 即可

通常,我们需要 pycrypto库,执行命令 pip3 install pycrypto 安装一下

安装 MySQL,创建数据库和用户

MySQL的安装 点击这里参考我们的教程

安装 好MySQL 服务后:

  • 先使用root用户创建数据库bysms,指定使用utf8的缺省字符编码,执行命令如下
CREATE DATABASE bysms CHARACTER SET utf8mb4  COLLATE utf8mb4_unicode_520_ci;
  • 再创建 使用数据库的用户,保证该用户有访问 bysms数据库的权限,比如
CREATE USER 'byhy'@'localhost' IDENTIFIED BY 'Mima123$';
CREATE USER 'byhy'@'%' IDENTIFIED BY 'Mima123$';

随后输入如下命令,赋予byhy 用户所有权限,就是可以 该DBMS系统上 访问所有数据库里面所有的表

GRANT ALL ON *.* TO 'byhy'@'localhost';
GRANT ALL ON *.* TO 'byhy'@'%';

安装 Gunicorn

执行下面的命令安装 依赖的库 gevent 和 greenlet (异步模式需要)

pip3 install greenlet  
pip3 install gevent    

再执行命令安装gunicorn

pip3 install gunicorn

创建产品运行用户

通常我们需要为运行产品进程,比如 Nginx work进程、Gunicorn 等,创建一个专门的用户。

这里我们使用byhy用户

执行命令创建用户 useradd byhy

然后给 byhy用户设置密码 passwd byhy

安装产品发布包

我们以 root用户 登录Linux 主机,执行如下命令安装工具: zip 、 unzip 、dos2unix

yum install zip unzip dos2unix

然后再以 byhy用户 登录Linux 主机,执行如下命令下载 前端 和 后端的 发布包。

wget http://v.python666.vip/file/django/bysms_front_v1.5.zip
wget http://v.python666.vip/file/django/bysms_back_v1.5.zip

实际项目中,发布包如果不好直接wget下载,可以使用 winscp 拷贝到 Linux 主机上。{: .notice–info}

然后执行下面的命令进行解压。

unzip bysms_front_v1.5.zip
unzip bysms_back_v1.5.zip

然后进入到 目录 bysms_backend 中,

执行命令

dos2unix run.sh
chmod +x run.sh

创建数据库表

执行下面的命令, 让Django 在数据库中 创建 你的系统所需要的表

python manage.py makemigrations auth
python manage.py makemigrations <your_app_label>
python manage.py migrate 

注意, <your_app_label> 需要替换成你的 Django 项目中的 app (只需要写包含了数据库表定义的App)的名字,可以是多个app,中间用空格隔开

启动 Gunicorn/Django

进入到 byhy 用户home目录,执行命令 run.sh

然后,执行命令 ps -ef | grep python |grep gunicorn_conf |grep -v grep 查看 是否启动成功。

自动化部署

上面的过程是不是很麻烦?

一个成熟的产品团队,通常可以开发自动化部署软件。可以一键部署,大大提高效率。

具备了Python开发能力的你,自己就可以尝试开发 自动化部署程序哦。

HTTPS 服务

这里,我们的服务运行在80端口上,是不加密的网站服务。

以后,为了安全考虑,需要运行在HTTPS协议上。

这就需要我们申请证书,并且配置Nginx 使用HTTPS。

以后我们的教程会补充这方面的内容。


作业和练习

根据教程,在阿里云主机,或者虚拟机上,安装 白月医疗系统。

安装成功后,浏览器打开该网站服务,验证可以正确访问。


扫码分享给朋友,一起学更有动力哦



上一页 下一页