操作系统: Linux (CentOS 7 )
处于开发阶段的时候,大都是在个人电脑(通常是Windows操作系统)上面运行的。
完成一个阶段的开发任务后,就需要把我们开发的网站服务,需要我们的网站部署在公网上,这个给真正用户使用的网站服务器也被称之为生产环境。
通常,我们的web服务是部署在云服务厂商的云主机上,比如阿里云的ECS云主机。
现在的web服务,基本都是采用 Linux 操作系统。 而且生产环境不应该使用 SQLite 数据库,通常是 MySQL、Postgresql、Oracle等。
把基于Django的web系统部署到生产环境,就是在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 在整个后端的最前方, 可以实现负载均衡、反向代理、请求缓存、响应缓存 、负荷控制等等一系列功能。可以大大的提高整个后端的性能和稳定性。
为了简单,把整个后端系统都部署在同一台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数据库读写数据。
产品发布包:
产品的发布包,是不是只是需要把你的代码用zip打个包?哪有那么简单
稍微复杂些的产品都会涉及到好多子系统:
前端通常包括 web前端、app前端;
后端 包括业务处理系统、数据库系统、消息队列、异步任务系统、缓存系统等等。
为了保证这些子系统能在生产环境 友好配合 , 需要仔细的规划、配置、产生发布包。
现在的系统 包括 web前端系统(包括web前端的HTML、CSS、图片、js业务代码、js库等文件)、后端业务处理系统、数据库系统。
需要做到产品发布包里面的 包括 web前端系统 和 业务处理系统 的代码。
不同的运营架构,部署的方式不同,需要构建发布包的方式也不同。
这里,把前端系统代码做在一个发布包中, 后端系统做在另一个发布包中。
完全可以把前后端系统分别部署到两台 Linux主机上。当有请求需要Django后端业务系统处理的时候,转发给Django所在的主机即可。 如果请求只是获取一些静态资源,比如HTML、图片等,在前端主机处理完即可。 这样做到部署的前后端分离。 目前先按简单的来,都部署在同一台机器上。
首先,我们需要为当前版本的发布,准备 web前端发布包,和web后端发布包。
现在我们假定发布的 版本号为 1.5
- 前端发布包,由前端开发人员提供。
- 后端开发人员准备后端的发布包。
基于Django开发的后端系统,要发布正式版本。
一、首先应该修改项目配置文件中的配置项DEBUG值为 False。
修改 settings.py :
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = False
二、修改数据库
开发过程中,一直用的SQLite数据库,需要改为生产环境的MySQL数据库。
修改 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
}
}
配置的 MySQL连接的 用户名、密码、数据库名、数据库服务主机名、端口都要和自己的环境匹配。
三、添加 Linux 启动shell脚本
生产环境,我们使用 Gunicorn 作为 Django的WSGI前端,首先在项目同名目录表下创建一个 Gunicorn启动配置文件 gunicorn_conf.py ,内容如下:
# gunicorn/django 服务监听地址、端口
bind = '127.0.0.1:8080'
# 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 :
#!/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