django+uwsgi+Nginx部署总结

作者: 终可见丶 | 来源:发表于2018-05-24 01:32 被阅读88次

    还记得去年做实验室官网的后台的时候,代码写好了,就差部署了。
    网上找了很多教程,最后还是失败了,直接就 runserver 裸奔的。

    今年又去看了自强学堂涂伟忠老师的教程,感觉虽然很详细,但是比较复杂,并且环境有点不兼容,因为今年我是用的Python3写的了。所以就换了个。

    找了很久找到了一个比较简洁但是好用的教程: Django + Uwsgi + Nginx 的生产环境部署

    我基本上照着这个教程走,大部分操作可以完成,不过也遇到了一些比较奇怪的问题和一些操作问题:

    首先需要注意的问题是,我们操作的目录,应该是在你的manage.py的同级目录。
    其次需要注意的问题是命令和配置里面的路径设置,一定要和你的项目路径匹配,否则会发生很多很奇怪的错误的。

    • 运行uwsgi提示no app found
      运行这条命令之后出现了该问题,并且访问服务器的8080端口也打不开。
      uwsgi --http 0.0.0.0:8080 --file teacher/wsgi.py
      经过大量的检查,发现是我本地上传的代码,环境和服务器不一致。比如本地用了MySQLdb这个库,服务器并没有安装,仔细看报错信息也确实发现了报了这个错。于是就把服务器上没有的库都装上了,于是问题成功解决。

    • 运行Nginx:access_log main 这一行报错
      排查了问题,发现是作者把access_log放进了server的设置里面,所以报错了,于是把access_log拿出来了,报错charset=utf-8。然后按照新的教程添加了gzip支持。

    • gzip重复开启
      在设置里面我只开了一个 gzip on 的命令我查看conf.d目录下,就我这一个设置文件,感到了困惑,然后又百度之,发现在/etc/nginx/目录下有个nginx.conf文件,打开查看了,里面果然开启了gzip。所以我把我的设置里面的gzip on删了。

    • 重启uwsgi命令不会用

    uwsgi --ini uwsgi.ini             # 启动
    uwsgi --reload uwsgi.pid          # 重启
    uwsgi --stop uwsgi.pid            # 关闭
    

    uwsgi.pid和uwsgi.ini的位置都在我们的uwsgi.ini里面设置了。所以直接找到这uwsgi.pid文件,然后敲命令回车应该就可以了。但是报错了,路径出问题了,因为uwsgi.ini是在project/script/目录下的,我们重载的时候,也应该到manage.py的目录重启,否则配置文件里面的路径就会出错。所以重启应该改成uwsgi --reload ./script/uwsgi.pid

    • 重启Nginx
      我凭感觉,用了nginx restart,不行。于是查资料:正确的应该是service nginx restart

    • 用ip访问和用网址访问结果不一样
      我终于配置好了Nginx和uwsgi。我用IP访问我的服务器的时候,看得到Nginx的服务页面,但是其他所有页面都是404,但是我通过网址访问的时候,又是正常的。这个操作也是Nginx的一个优点,同一个端口,可以区分来源是哪里的,然后分别转发到不同的端口。具体设置是在server{server_name www.xxx.com ...}这里,如果server_name是ip,那么也不能通过网址正常访问了。


    学习了“一年”的配置的一点总结

    之前一直不知道uwsgi和Nginx是怎么发生关系的,看过博客之后,稍微多了一丝了解:

    • uwsgi是用来启动Django项目的。也就是我们不需要敲python manage.py runserver 8000,而是直接到uwsgi.ini里面配置好,直接使用uwsgi运行就好了,运行成功的话,我们就可以看到网站在127.0.0.1:8000成功运行了,如果需要外网访问的,就把IP设置成0.0.0.0,这样所有的IP都可以访问网站了,不止是本机。

    • Nginx是用来做请求转发与静态文件处理的。请求转发的情况是这样的,为了安全起见(也许不是),我们限制uwsgi的应用只能在本机跑,那么除了本机,没有任何人能够访问到网站。要让别人也访问,就只有开放另一个端口出来,用来接收到外界来的请求,然后转发到127.0.0.1:8000端口我们的网站上,这样uwsgi就成功接收到了外界的请求了。Nginx就是个中间人,把外界的请求转发进来,把内部请求返回回去。它既然承接了所有的请求,那么他就可以做一些多的事情了,比如压缩请求的内容(gzip),限制访问的频率,把静态文件(css/js/图片/视频/文件)直接返回回去,而不用经过网站请求的验证,Nginx的强大之处就在于对静态文件的处理。

    • Nginx到底是怎么和uwsgi发生关系的?通过uwsgi产生的sock文件。通过这个文件,Nginx知道了uwsgi的端口等信息,然后就自动配置了。在server里面配置uwsgi的sock 文件的目录,使用绝对路径。

    uwsgi和Nginx,特别是Nginx,是一门高深的学问,它的设置项是真的多。。。

    附上我的uwsgi.ini和mynginx.conf设置文件内容:

    uwsgi.ini:

    # uwsig使用配置文件启动
    [uwsgi]
    # 项目目录
    chdir=/data/office/office1/
    # 指定项目的application
    module=office1.wsgi:application
    # 指定sock的文件路径       
    socket=/data/office/office1/script/uwsgi.sock
    # 进程个数       
    workers=5
    pidfile=/data/office/office1/script/uwsgi.pid
    # 指定IP端口       
    http=0.0.0.0:8080
    # 指定静态文件
    # static-map=/static=/opt/proj/teacher/static
    # 启动uwsgi的用户名和用户组
    uid=root
    gid=root
    # 启用主进程
    master=true
    # 自动移除unix Socket和pid文件当服务停止的时候
    vacuum=true
    # 序列化接受的内容,如果可能的话
    thunder-lock=true
    # 启用线程
    enable-threads=true
    # 设置自中断时间
    harakiri=30
    # 设置缓冲
    post-buffering=4096
    # 设置日志目录
    daemonize=/data/office/office1/script/uwsgi.log
    

    我的项目名叫office1,位于/data/office/目录下。所以配置文件首先就chdir,打开了我的manage.py的的目录,然后第二个设置才能起作用,找到application的位置。在manage.py同级目录创建了script文件夹之后,把uwsgi的ini,pid,sock文件都放在了script文件夹里面。

    mynginx.conf

    # $gzip_ratio计算请求的压缩率,$body_bytes_sent请求体大小
        log_format  main  '$remote_addr - $remote_user [$time_local] "$host" - "$request" '
                        '$gzip_ratio - $body_bytes_sent - $request_time';
    
    
        # 启用gzip压缩的最小文件,小于设置值的文件将不会压缩
        gzip_min_length 1k;
    
        # gzip 压缩级别,1-9,数字越大压缩的越好,也越占用CPU时间,后面会有详细说明
        gzip_comp_level 1;
    
        # 进行压缩的文件类型。javascript有多种形式。其中的值可以在 mime.types 文件中找到。
        gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png application/vnd.ms-fontobject font/ttf font/opentype font/x-woff image/svg+xml;
    
        # 是否在http header中添加Vary: Accept-Encoding,建议开启
        gzip_vary on;
    
        # 禁用IE 6 gzip
        gzip_disable "MSIE [1-6]\.";
    
        # 设置压缩所需要的缓冲区大小
        gzip_buffers 32 4k;
    
        # 设置gzip压缩针对的HTTP协议版本
        gzip_http_version 1.0;
    
            charset utf-8; # Nginx编码
    
    server { # 这个server标识我要配置了
            listen 80; # 我要监听那个端口
            server_name www.yoururl.com; # 你访问的路径前面的url名称
    
    
            # error_page 404 /404.html; # 错误页面
            # error_page 500 502 503 504 /50x.html; # 错误页面
    
            # 指定项目路径uwsgi
            location / { # 这个location就和咱们Django的url(r'^admin/', admin.site.urls),
                    include uwsgi_params; # 导入一个Nginx模块他是用来和uWSGI进行通讯的
                    uwsgi_connect_timeout 30; # 设置连接uWSGI超时时间
                    uwsgi_pass unix:/data/office/office1/script/uwsgi.sock; # 指定uwsgi的sock文件所有动态请求就会直接丢给他
            }
    
            # 指定静态文件路径
            location /static/ {
                    alias /data/office/office1/static/;
                    index /data/office/office1/templates/index.html;  # 配置两个index.html也只认第一个
            }
    
    }
    

    配置完成了之后,重启Nginx就OK了。

    相关文章

      网友评论

        本文标题:django+uwsgi+Nginx部署总结

        本文链接:https://www.haomeiwen.com/subject/fmihjftx.html