django + uwsgi + nginx 部署小结

本贴最后更新于 2145 天前,其中的信息可能已经物是人非

1. 环境准备


本文基于 centos7.x + python3.x 完成 django2.0.x 项目的部署。

  • 需要准备以下环境:
  1. python3.x,但不可卸载 python2,因为 centos 的某些系统功能依赖 python2。

  2. pyenv,因为多个 python 版本共存的问题,需要在版本间切换,所以安装 pyenv。

  3. django2.0.x 及相关依赖 python 库,

    首先导出项目需要的依赖库:pip freeze > requirements.txt
    
    然后安装依赖库:pip install -r requirements.txt
    
  4. 上传工程文件,本例中上传到目录:/usr/local/deploy/demo

2. uwsgi


首先,切换到 python3,

输入:pip install uwsgi

然后,检测是否安装成功,
进入到目录/usr/local/deploy/demo 中,

输入:uwsgi --http :8001 --module demo.wsgi

进入浏览器该端口下是否运行正常。

输入:ctrl + c 退出

但是,这种方式依赖于工程本身的配置文件,耦合太高,我采用了配置文件的方式,新建并进入文件夹/usr/local/deploy/scripts。

vim uwsgi.ini

在文件中输入以下内容,并保存。

# uwsig使用配置文件启动
[uwsgi]
# 项目目录
chdir=/usr/local/deploy/demo
# 指定项目的application
module=demo.wsgi:application
# 指定sock的文件路径
socket=/usr/local/deploy/scripts/uwsgi.sock
socket-timeout=360
# 进程个数
workers=5
pidfile=/usr/local/deploy/scripts/uwsgi.pid
# 指定IP端口
http=:8001
# 指定静态文件
static-map=/static=/usr/local/deploy/demo/static
# 启动uwsgi的用户名和用户组
uid=root
gid=root
# 启用主进程
master=true
# 自动移除unix Socket和pid文件当服务停止的时候
vacuum=true
# 序列化接受的内容,如果可能的话
thunder-lock=true
# 启用线程
enable-threads=true
# 设置自中断时间
harakiri=360
harakiri-verbose=true

# 设置内存限制
limit-as=3096
# 设置缓冲
post-buffering=4096
# 设置日志目录
daemonize=/usr/local/deploy/scripts/uwsgi.log

切换到/usr/local/deploy/demo 项目目录下,依次执行:

python manage.py makemigrations
python manage.py migrate
python manage.py collectstatic

启动 uwsgi:

启动:
/root/.pyenv/shims/uwsgi --ini /usr/local/deploy/scripts/uwsgi.ini 
重启:
/root/.pyenv/shims/uwsgi --reload /usr/local/deploy/scripts/uwsgi.pid  
关闭:
/root/.pyenv/shims/uwsgi --stop /usr/local/deploy/scripts/uwsgi.pid

查看 8001 端口,看是否启动好了。查看日志:

tail -500f /usr/local/deploy/scripts/uwsgi.log

3. nginx


安装 nginx

yum install -y nginx

测试:

定位:cd /usr/sbin
启动:./nginx
停止:./nginx -s stop
重启:./nginx -s reload

修改配置文件 nginx.conf:

vim /etc/nginx/nginx.conf

编辑后内容如下(主要是删除了没必要的注释及 server 部分):

# 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;


}

新增配置文件 demo.conf:

touch /etc/nginx/conf.d/demo.conf
vim /etc/nginx/conf.d/demo.conf

编辑并保存,内容如下:

server { # 这个server标识我要配置了
        listen 8000; # 我要监听那个端口
        server_name xxx.xxx.xxx.xxx; # 你访问的路径前面的url名称
        access_log /var/log/nginx/access.log main; # Nginx日志配置
        charset utf-8; # Nginx编码
        gzip_types text/plain application/x-javascript text/css text/javascript application/x-httpd-php application/json text/json image/jpeg image/gif image/png application/octet-stream; # 支持压缩的类型


        error_page 404 /404.html; # 错误页面
        error_page 500 502 503 504 /50x.html; # 错误页面

        # 指定项目路径uwsgi
        location / { # 这个location就和咱们Django的url(r'^admin/', admin.site.urls),
		uwsgi_send_timeout 300;        # 指定向uWSGI传送请求的超时时间,完成握手后向uWSGI传送请求的超时时间。
        uwsgi_connect_timeout 300;   # 指定连接到后端uWSGI的超时时间。
        uwsgi_read_timeout 300;        # 指定接收uWSGI应答的超时时间,完成握手后接收uWSGI应答的超时时间

        include uwsgi_params; # 导入一个Nginx模块他是用来和uWSGI进行通讯的
        uwsgi_pass unix:/usr/local/deploy/scripts/uwsgi.sock; # 指定uwsgi的sock文件所有动态请求就会直接丢给他
        }

        # 指定静态文件路径
        location /static {
        alias /usr/local/deploy/demo/static/;
        }
}

启动 nginx:

cd /usr/bin
./nginx

查看日志:

运行日志:tail -500f /var/log/nginx/access.log
错误日志:tail -500f /var/log/nginx/error.log

访问 8000 端口,看是否正常。

4. 踩坑记录


4.1 uwsgi 无法访问静态文件

解决办法:启动前,运行python manage.py collecstatic

4.2 uwsgi 超过 10s 自动发送重复任务

解决办法:修改harakiri参数改大些。

4.3 uwsgi 无法访问部分 css 文件,报 404.

解决办法:排查后发现引入css时是这样的


<link rel="stylesheet" href={% static "report/css/bootstrap.css" %} />

django解析后成了:[localhost/report/css/boostrap.css/],而不是[localhost/report/css/boostrap.css],导致无法找到资源,改为

<link rel="stylesheet" href='{% static "report/css/bootstrap.css" %}' />

4.4 长连接超过一分钟报 50x 或者 0 错误

解决办法:这是由于请求应答时间过长造成的,需要在demo.conf中设置
uwsgi_read_timeout参数,将它设置长一些

5. 参考资料


https://blog.csdn.net/hshl1214/article/details/46789969
https://www.cnblogs.com/chenice/p/6921727.html
https://segmentfault.com/q/1010000006068317
http://www.mynetcow.com/show_art.php?id=383【安装nginx遇到的报错】
  • Python

    Python 是一种面向对象、直译式电脑编程语言,具有近二十年的发展历史,成熟且稳定。它包含了一组完善而且容易理解的标准库,能够轻松完成很多常见的任务。它的语法简捷和清晰,尽量使用无异义的英语单词,与其它大多数程序设计语言使用大括号不一样,它使用缩进来定义语句块。

    530 引用 • 671 回帖
  • NGINX

    NGINX 是一个高性能的 HTTP 和反向代理服务器,也是一个 IMAP/POP3/SMTP 代理服务器。 NGINX 是由 Igor Sysoev 为俄罗斯访问量第二的 Rambler.ru 站点开发的,第一个公开版本 0.1.0 发布于 2004 年 10 月 4 日。

    311 引用 • 546 回帖 • 68 关注
  • Django
    47 引用 • 72 回帖 • 4 关注
  • uWSGI
    7 引用 • 62 回帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...
  • Sunnnner

    老哥 2.0 好用吗

    1 回复
  • flhuoshan
    作者

    好用,只是教程不太多,只能看官网

  • henry725

    ksdfiisdiiasdis

  • jy02201949

    不错,很详细,当年自己 google 折腾了半宿

    1 回复
  • flhuoshan
    作者

    我折腾的时间比你要多,现在你在做哪方面的东东?

  • namelysweet

    学习了!

请输入回帖内容 ...