基于Nginx和uWSGI在CentOS上部署Django


=Start=

缘由:

Django其实自带了一个Web服务器,但是建议只在开发/测试时使用,因为它在修改Python代码后会自动重启,方便调试和开发,但是由于性能问题,建议只用来测试,不要用在生产环境。

在生产环境中,一般是使用Apache或Nginx作为Web服务器,所以,这里我们讲一讲如何基于Nginx和uWSGI在CentOS上部署Django。

正文:

主要参考文章「基于nginx和uWSGI在Ubuntu上部署Django」进行配置,期间碰到了很多问题,主要是权限问题……

1.安装Nginx

CentOS 6.5默认的yum源中Nginx的版本较老,而且,为了使用一些新的特性,我这里用OpenResty替代Nginx,下面是安装方法:

$ sudo yum install readline-devel pcre-devel openssl-devel perl
$ wget https://openresty.org/download/openresty-1.9.7.3.tar.gz
$ tar zxf openresty-1.9.7.3.tar.gz
$ cd openresty-1.9.7.3

$ ./configure --prefix=/opt/openresty \
              --with-http_stub_status_module \
              --with-http_iconv_module

$ gmake
$ sudo gmake install

export PATH=/opt/openresty/nginx/sbin:$PATH
2.安装uWSGI和supervisor
$ sudo -H pip install uwsgi supervisor
3.基于 uWSGI 和 Nginx 部署 Django

原理:

the web client <-> the web server(nginx) <-> the socket <-> uwsgi <-> Django

基本单项测试:

  1. 测试 uWSGI 是否正常 [the web client <-> uWSGI <-> Python]
  2. 测试 Django 项目是否正常 [the web client <-> Django]
  3. 测试 uWSGI + Django 项目是否正常 [the web client <-> uWSGI <-> Django]
  4. 测试 Nginx 是否正常 [the web client <-> the web server(nginx)]

组合项测试:

#test.py的内容
def application(env, start_response):
    start_response('200 OK', [('Content-Type', 'text/html')])
    return ["Hello World"]

#nginx.conf片段
server {
    listen      80;
    server_name localhost;

    charset     utf-8;
    client_max_body_size 75M;

    location /assets {
        alias /opt/learn_django/mysite/assets;
    }

    location / {
        uwsgi_pass  unix:///tmp/mysite.sock;
        #uwsgi_pass  127.0.0.1:8001;
        include     /etc/nginx/uwsgi_params;
    }
}
一、Nginx and uWSGI and test.py
    编辑 nginx.conf 使其支持
        端口转发   [uwsgi_pass 127.0.0.1:8001;]
    或
        socket    [uwsgi_pass unix:///tmp/mysite.sock;]

    测试 Nginx 配置语法问题
        sudo /etc/init.d/nginx configtest
        sudo /etc/init.d/nginx reload
        sudo /etc/init.d/nginx restart

uwsgi --socket :8001 --wsgi-file test.py
uwsgi --socket mysite.sock --wsgi-file test.py
uwsgi --socket mysite.sock --wsgi-file test.py --chmod-socket=666
uwsgi --socket mysite.sock --wsgi-file test.py --chmod-socket=664

    如果没有成功:
        检查 Nginx 错误日志(/var/log/nginx/error.log)


二、Nginx and uWSGI and Django application
uwsgi --socket mysite.sock --module mysite.wsgi --chmod-socket=664

# 创建 uwsgi.ini 简化启动命令
在application目录下创建文件 mysite_uwsgi.ini ,按需修改内容后用下面的命令进行启动:
uwsgi --ini mysite_uwsgi.ini
4.使用supervisor来管理 uWSGI 进程
(sudo) echo_supervisord_conf > /etc/supervisord.conf
打开 supervisor.conf 在最底部添加(每一行前面不要有空格,防止报错):
[program:mysite]
command=/path/to/uwsgi --ini mysite_uwsgi.ini
directory=/path/to/mysite
startsecs=0
stopwaitsecs=0
autostart=true
autorestart=true

启动 supervisor
(sudo) supervisord -c /etc/supervisord.conf

重启 supervisor
(sudo) supervisorctl -c /etc/supervisord.conf restart mysite
或
(sudo) supervisorctl -c /etc/supervisord.conf restart all
参考链接:

=END=


《“基于Nginx和uWSGI在CentOS上部署Django”》 有 9 条评论

  1. Nginx配置杂记「https://wenjs.me/p/note-of-nginx-configure」
    里面讲了很多内容,值得深入学习。

  2. Python代码的自动重载(Autoreload Code in Python)
    https://ivan-site.com/2013/04/autoreload-code-in-python/
    `
    For example, if you’re using werkzeug you can just pass the use_reloader flag:
    run_sumple(‘127.0.0.1’, 5000, app, use_reloader=True)

    For Flask, which actually uses werzeug internally, setting debug=True is all you need:
    app.run(debug=True)

    Django will automatically do it for you when you use:
    python manage.py runserver

    uWSGI
    # …

    gunicorn
    # …

    external solution
    # watchdog/…
    `

  3. 解决 supevisor 提示 socket error 错误
    http://pycode.cc/supervisor-socket-error/
    https://stackoverflow.com/questions/18859063/supervisor-socket-error-issue
    https://github.com/Supervisor/supervisor/issues/121
    https://www.gznotes.com/supervisor-socket-error-errno-101/
    https://www.jianshu.com/p/687f0956081c
    `
    $ supervisorctl -c supervisor.conf reload
    error: , [Errno 111] Connection refused: file: /path/to/python27/lib/python2.7/socket.py line: 228

    # 先启动 supervisord
    $ supervisord -c supervisor.conf
    # 再用 supervisorctl 启动程序
    $ supervisorctl -c supervisor.conf reload
    # supervisord和supervisorctl要使用的 supervisor.conf 要一致,否则也会出问题
    `

  4. 部署 Django 项目背后的原理:为什么需要 Nginx 和 Gunicron这些东西?
    https://www.centos.bz/2018/06/%E9%83%A8%E7%BD%B2-django-%E9%A1%B9%E7%9B%AE%E8%83%8C%E5%90%8E%E7%9A%84%E5%8E%9F%E7%90%86%EF%BC%9A%E4%B8%BA%E4%BB%80%E4%B9%88%E9%9C%80%E8%A6%81-nginx-%E5%92%8C-gunicron%E8%BF%99%E4%BA%9B%E4%B8%9C/
    `
    即 Django 做的事情只是一个框架,不会去关心一些安全问题、HTTP 的性能问题等。所以我们需要一个专业的 HTTP 服务器。这就出现了 Nginx 或 Apache。那么如何将 HTTP 服务器和我们的应用连接起来呢?动态网站问世的时候,就出现了 CGI 协议。注意这是一个协议,定义了HTTP 服务器如何通过后端的应用获取动态内容。可以简单的理解成 HTTP 服务器通过CGI 协议调用后端应用吧!WSGI 可以理解成 Python 的 CGI。uWSGI 和 Gunicorn 是这种 WSGI 的一些实现。这样,就出现了上面提到的三层的部署。

    但是,为什么我们还需要 Nginx 呢?这些 WSGI 程序本身不是也提供访问吗?

    uWSGI 和 Gunicorn 本身就是一个便携的 web 服务器了,Nginx 作为一个经过更长时间验证的 HTTP 服务器来说,它有很多 uWSGI 没有支持的 feature。

    专业的事情交给专业的人去做。
    `

  5. Python后端架构演进
    https://zhu327.github.io/2018/07/19/python%E5%90%8E%E7%AB%AF%E6%9E%B6%E6%9E%84%E6%BC%94%E8%BF%9B/
    `
    架构的演进经历了4个大的阶段: 1. MVC 2. 服务拆分 3. 微服务架构 4. 领域驱动设计.

    架构的设计, 技术的选型, 不能完全按照流行的技术走, 最终还是服务于产品, 服务于客户的需求. 设计过程中由于团队, 人员的结构问题, 有很多的妥协之处, 如何在妥协中找到最优解才是最大的挑战.
    `

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注