HeLei Blog

Nginx+uWSGI+Django部署服务器

概念

先弄清楚几点概念, 注意大小写区别.

  • 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专心处理动态内容, 从而提高性能.

部署过程

我的机器已经安装了anaconda

  1. 打开python虚拟环境

    1
    2
    3
    4
    5
    6
    $ conda info -e
    # conda environments:
    #
    python27 /home/chris/anaconda2/envs/python27
    $ source activate python27
  2. 安装nginx

  3. 安装uwsgi

    1
    pip install uwsgi

安装完成后,出现了如下错误

1
2
# uwsgi --version
uwsgi: error while loading shared libraries: libpcre.so.1: cannot open...

可以按照下面的方法解决:
https://stackoverflow.com/questions/43301339/pcre-issue-when-setting-up-wsgi-application

  1. 在django项目下新建uwsgi.ini文件,配置如下
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    # uwsig使用配置文件启动
    [uwsgi]
    # 项目目录
    chdir=/home/chris/myspace/python/myblog
    # 指定项目的application
    module=myblog.wsgi:application
    # 指定sock的文件路径
    socket=127.0.0.1:8080
    #socket=/home/chris/myspace/python/myblog/script/uwsgi.sock
    # 进程个数
    workers=5
    pidfile=/home/chris/myspace/python/myblog/script/uwsgi.pid
    # 指定IP端口
    http=127.0.0.1:8080
    # 指定静态文件
    static-map=/static=/home/chris/myspace/python/myblog/static
    # 启动uwsgi的用户名和用户组
    uid=root
    gid=root
    # 启用主进程
    master=true
    # 自动移除unix Socket和pid文件当服务停止的时候
    vacuum=true
    # 序列化接受的内容,如果可能的话
    thunder-lock=true
    # 启用线程
    enable-threads=true
    # 设置自中断时间
    harakiri=30
    # 设置缓冲
    post-buffering=100004096
    # 设置日志目录
    daemonize=/home/chris/myspace/python/myblog/script/uwsgi.log

socket参数这里配置为网络地址

1
socket=127.0.0.1:7070

但如果Nginx和uWSGI同在一个服务器上,可以使用socket文件的形式

1
socket=/home/chris/myspace/python/myblog/script/uwsgi.sock

使用netstat查看8080端口,已经在监听,说明服务已启动

1
2
(python27) $ sudo netstat -apn |grep 8080
tcp 0 0 127.0.0.1:8080 0.0.0.0:* LISTEN 19700/uwsgi

  1. 配置nginx

拷贝nginx默认的配置文件nginx.conf并重命名为nginx_django.conf,配置如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
http {
···
server {
listen 8000;
server_name localhost;
location / {
include /usr/local/nginx/conf/uwsgi_params;
#include uwsgi_params;
uwsgi_pass 127.0.0.1:8080;
#uwsgi_pass unix:/home/chris/myspace/python/myblog/script/uwsgi.sock;
uwsgi_connect_timeout 300; #nginx跟后端服务器连接超时时间(代理连接超时)
uwsgi_send_timeout 300; #后端服务器数据回传时间(代理发送超时)
uwsgi_read_timeout 300; #连接成功后,后端服务器响应时间(代理接收超时)
}
}
···
}

  1. 启动Nginx

    1
    $ nginx -c nginx_django.conf
  2. 在浏览器访问nginx配置的端口

    1
    127.0.0.1:8000/index

到这里,就完了用Nginx+uWSGI+Django搭建Web服务。

坚持原创技术分享,您的支持将鼓励我继续创作!