本文基于: 阿里云 CentOS 7.4.1708, Python 3.6.1, Django 2.0.2, uWSGI 2.0.15, Nginx 1.12.2
知道怎么样部署之前我们要先弄清楚为什么? 为什么要用 Django+uWSGI+Nginx? 所以更首先我们要知道是什么?
先弄清楚几点概念, 注意大小写区别.
WSGI - 全称为 Python web Server Gateway Interface, 即 Python 服务器网关接口. 是为 Python 语言定义的 Web 服务器和 Web 应用程序或 Web 应用框架之间的一种简单而通用的接口. WSGI 只是一种通信协议. 更详细信息请查看维基百科 WSGI.
通俗一点说就是写 Python 程序时不想花费大量的时间去处理 TCP 连接 HTTP 的请求和响应等等, 于是就把这些都统一成了一个接口 (即 WSGI). 然后由专门的 Web 服务器(uWSGI 等) 和 Web 应用框架 (Django 等) 去实现. 既降低了开发门槛又节约了时间.
uWSGI - uWSGI 是一个实现了 WSGI 协议的 Web 服务器, uWSGI 处理了 HTTP 的响应解析等, 并转成 WSGI 协议, 这样我们编写的 Web 应用程序或 Web 应用框架才可以对传递过来的信息进行处理.
uwsgi - uwsgi 是实现了 WSGI 协议的服务器的内部自有协议, 它定义了传输信息的类型, 用于实现了 WSGI 协议的服务器与其他网络服务器的数据通信.
了解了基本的概念之后, 就知道了为什么要 Django+uWSGI. Django 是 Python 的 Web 应用框架, 他帮我们做了很多基础工作, 让开发者可以专心的写业务代码. 而 uWSGI 是实现了 WSGI 协议的 Web 服务器, 只有这两者组合在一起, Python 的应用程序才可以发挥作用.
理论上, 有了这一套, 就可以部署到服务器使用了. 而我们还要加上 Nginx 的原因, 当然是因为 Nginx 可以做一些 uWSGI 做不到的事情, 或者把事情做得更好.
Nginx 是一款面向性能设计的 HTTP 服务器, 相较于 Apache 具有占有内存少, 稳定性高等优势. 可以被用作反向代理, 负载平衡器 和 HTTP 缓存. 所以使用 Nginx 的最大原因之一就是性能问题. 如果只是个小网站, 不会有很大了流量, 当然 uWSGI 可以满足要求, 但是在高并发情况下就需要 Nginx 了, 并且 Nginx 相比 Apache 有很大的高并发优势.
另外, Nginx 能带来更好的安全性. 并且可以直接处理静态内容, 不需要通过 uWSGI, 让 uWSGI 专心处理动态内容, 从而提高性能. 更多 Nginx 内容可以访问 Nginx, epoll, about Nginx.
总结一下各自的任务以及工作原理: Nginx 接收到客户端的请求, 如果请求的是静态内容就直接返回静态内容, 如果请求的是动态内容, 就把请求转发给 uWSGI ,uWSGI 连接 Django 进入我们的 Python 程序进行处理.
知道了 Django, uWSGI, Nginx 分别是什么, 并且知道了为什么要用 Django+uWSGI+Nginx 之后, 就可以进行服务器的部署工作了.
在服务器部署 Python 3.6 和 Django 2.0.2
连接阿里云服务器. 在 Mac 终端输入 $ SSH root@xxx.cn, root 是用户名 xxx.cn 是服务器域名或者 IP 地址
安装 Nginx
- # yum install epel-release
- # yum install python-devel nginx
使用 pip 安装 uwsgi
>>> pip3 install uwsgi--upgrade
配置 uWSGI 和 Nginx 配置文件并直接放在项目根目录
因为配置文件只需要在部署时使用一次, 直接在服务器配置会更合适. 当然你也可以在本地的项目文件夹新建对应的配置文件并写入配置. 但是需要注意配置文件中的路径都是服务器端的路径.
uWSGI 配置文件 uwsgi.ini. 更多信息请查看 uWSGI Configuration.
- [uwsgi]
- # 使用 HTTP 访问的端口号, 使用这个端口号是直接访问了 uWSGI, 绕过了 Nginx
- http = :8010
- # 与外界连接的端口号, Nginx 通过这个端口转发给 uWSGI
- socket = 127.0.0.1:8001
- # 是否使用主线程
- master = true
- # 项目在服务器中的目录(绝对路径)
- chdir = /project_dir/
- # Django's wsgi 文件目录
- wsgi-file = project_name/wsgi.py
- # 最大进程数
- processes = 4
- # 每个进程的线程数
- threads = 2
- # 状态监听端口
- stats = 127.0.0.1:9191
- # 退出时自动清理环境配置
- vacuum = true
- # 目录下文件改动时自动重启
- touch-reload = /project_dir
- #Python 文件改动时自动重启
- #py-auto-reload = 1
- # 后台运行并把日志存到. log 文件
- daemonize = /project_dir/uWSGI.log
Nginx 需要两个配置文件. uwsgi_params 文件和 project_name.conf 文件
uwsgi_params 文件可以直接在 Nginx 的 git 仓库中可以下载.
project_name.conf 通过复制 nginx.conf 配置文件并进行修改. 首先查找 nginx.conf 文件的位置:
# nginx -t
会打印出类似信息:
- nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
- nginx: configuration file /etc/nginx/nginx.conf test is successful
新建 project_name.conf 文件, 复制 nginx.conf 文件的所有信息到 project_name.conf. 并替换掉 server 部分内容.
- server {
- # 把 nginx.conf 这一部分内容替换掉
- ...
- }
替换之后的文件为:
- #For more information on configuration,
- see: # * Official English Documentation: http: //nginx.org/en/docs/
- # * Official Russian Documentation: http: //nginx.org/ru/docs/
- user nginx;
- worker_processes auto;
- error_log /
- var / log / nginx / error.log;
- pid / run / nginx.pid;#Load dynamic modules.See / usr / share / nginx / README.dynamic.include / usr / share / nginx / modules
- /*.conf;
- events {
- worker_connections 1024;
- }
- http {
- log_format main '$remote_addr - $remote_user [$time_local]"$request" '
- ¦ ¦ ¦ ¦ ¦ '$status $body_bytes_sent"$http_referer" '
- ¦ ¦ ¦ ¦ ¦ '"$http_user_agent" "$http_x_forwarded_for"';
- access_log /var/log/nginx/access.log main;
- sendfile on;
- tcp_nopush on;
- tcp_nodelay on;
- keepalive_timeout 65;
- types_hash_max_size 2048;
- include /etc/nginx/mime.types;
- default_type application/octet-stream;
- # Load modular configuration files from the /etc/nginx/conf.d directory.
- # See http://nginx.org/en/docs/ngx_core_module.html#include
- # for more information.
- include /etc/nginx/conf.d/*.conf;
- #下面的部分是替换之后的配置
- # the upstream component nginx needs to connect to
- upstream django {
- # 连接到 Django 的端口号, 和 uwsgi.ini 文件中端口一致. 127.0.0.1 说明只允许本地转发
- server 127.0.0.1:8001; # for a web port socket (we'll use this first)
- }
- # configuration of the server
- server {
- # 端口号, 客户端通过这个端口连接到 Nginx
- listen 80;
- # 服务器地址
- server_name pefami.cn; # substitute your machine's IP address or FQDN
- # 编码
- charset utf-8;
- #日志文件在服务器中的路径
- access_log /project_dir/nginx_access.log;
- error_log /project_dir/nginx_error.log;
- # 上传文件最大体积限制
- client_max_body_size 75M; # adjust to taste
- # Django media 文件路径
- location /media {
- alias /project_dir/media; # your Django project's media files - amend as required
- }
- # Django 静态文件路径
- location /static {
- alias /project_dir/static; # your Django project's static files - amend as required
- }
- # Finally, send all non-media requests to the Django server.
- location / {
- uwsgi_pass django;
- include /project_dir/uwsgi_params; # the uwsgi_params file you installed
- }
- }
- }*/
配置好了配置文件以后, 把项目整个上传到服务器. 接下来只要在服务器运行 uWSGI 和 Nginx 就可以了. 这个有个需要注意: 在阿里云服务器打开对应端口, 比如上边配置中使用了的 8001 和 80 端口. 否则客户端无法连接上服务器.
启动 uWSGI
#uwsgi--ini uwsgi.ini
也可以不需要配置文件直接启动 uWSGI, 这时就不需要配置 uwsgi.ini 文件. 如下:
#uwsgi--http: 8001--chdir / project_dir / project_name--home = /path/to / env--module project_name.wsgi
其中 --home 指定 virtualenv 路径, 如果没有可以去掉.
启动 Nginx
#nginx - c / project_dir / static / project_name.conf
启动完成之后可以查看一下网络端口的状态
# netstat -nltp
正常情况下回打印出类似下列信息. 显示 uwsgi 和 nginx 是处于服务状态的.
- Active Internet connections (only servers)
- Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
- tcp 0 0 0.0.0.0:6379 0.0.0.0:* LISTEN 18977/./src/redis-s
- tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 4752/nginx: master
- tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 1117/sshd
- tcp 0 0 127.0.0.1:32000 0.0.0.0:* LISTEN 969/java
- tcp 0 0 127.0.0.1:8001 0.0.0.0:* LISTEN 8989/uwsgi
- tcp 0 0 127.0.0.1:9191 0.0.0.0:* LISTEN 8989/uwsgi
- tcp 0 0 0.0.0.0:8010 0.0.0.0:* LISTEN 8989/uwsgi
- tcp6 0 0 :::3306 :::* LISTEN 1145/mysqld
到这里, 部署的全过程就完成了.
另外, 修改了文件之后, Nginx 需要重新启动:
# nginx -s reload
因笔者知识有限, 如有错误, 欢迎指正.
来源: http://www.jianshu.com/p/a13307242ca3