django项目之生产环境部署Django+uwsgi+nginx

版权声明:本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。本文为博主原创文章,转载请附上博文链接! https://blog.csdn.net/Burgess_zheng/article/details/86760527

目录篇:Django总目录篇 点击跳转

目录


部署前戏

pycharm环境下的django承受不了多并发(几十个人并发访问就down掉)
生成环境中django需要承载高并发的,所以是Django + Uwsgi + Nginx(IO多路复用epel)

     uwsgi介绍

uWSGI是一个Web服务器,它实现了WSGI协议、uwsgi、http等协议。Nginx中HttpUwsgiModule的作用是与uWSGI服务器进行交换。
要注意 WSGI / uwsgi / uWSGI 这三个概念的区分。
1.WSGI是一种Web服务器网关接口。它是一个Web服务器(如nginx,uWSGI等服务器)与web应用(如用django\Flask\tornado\nodejs\..\框架写的程序)通信的一种规范。
2.uwsgi是一种线路协议而不是通信协议,在此常用于在uWSGI服务器与其他网络服务器的数据通信。(uWSGI和Nginx一样属于WEB服务器,而uwsgi线路协议是为uWSGI服务的)
3.而uWSGI是实现了uwsgi和WSGI两种协议的Web服务器。
4.uwsgi协议是一个uWSGI服务器自有的协议,它用于定义传输信息的类型(type of information),每一个uwsgi packet前4byte为传输信息类型描述,它与WSGI相比是两样东西。

web访问顺序:用户访问--->Nginx---->uWSGI---->django

从上面看nginx +uWSGI+django一台机器可以每秒处理并发2000+

uWSGI的主要特点如下
1.超快的性能
2.低内存占用(实测为apache2的mod_wsgi的一半左右)
3.多app管理(终于不用冥思苦想下个app用哪个端口比较好了-.-)
4.详尽的日志功能(可以用来分析app性能和瓶颈)
5.高度可定制(内存大小限制,服务一定次数后重启等)

 

    让Django并发多少都不是问题

除了部署nginx +uWSGI+django一台机器可以每秒处理并发2000+
我们还需要配合服务器集群
如果你懂linux服务器集群,下面是以前写的用户到网站的集群内部流程(意味你有多少台web服务器,并发随之增长)

linux实战部署Django+uwsgi+nginx

    1.环境准备

服务器:
    负载均衡服务器 ip:10.0.0.6(使用了niginx工具实现负载均衡,同时使用了keeplive做了冗余,所以IP是10.0.0.3)(这里不详解,牵涉Linux服务器集群,以后会写)
    web服务器ip:10.0.0.150 (部署Django+uwsgi+nginx)
    用户IP(本地机器):10.0.0.1

正常访问流程:

1.10.0.0.1(本地用户)访问10.0.0.3(负载均衡服务器ip10.0.0.6做了keeplife所以是10.0.0.3)---->
2.把请求交由负载均衡服务器(10.0.0.6)的web池随机的一个web服务器(由于是实验所以该池只指定一个web 服务器10.0.0.150(部署Django+uwsgi+nginx))------>
3.把请求交由web服务器ip10.0.0.150:80端口(uwsgi+django+nginx该服务器)----->
4.然后80端口的server里的locathon把请求交本地的8001端口(nginx和uswgi互通的端口)指向端口8001----->
5.8001在把请求转交给10.0.0.150:9000(该9000端口是通过uwsgi启动我们的Django程序))

    2.部署uswgi并测试

10.0.0.150

[root@python ~]# pip install uwsgi  #安装uwsgi
[root@python ~]# mkdir uwsgi_test
[root@python ~]# cd uwsgi_test/
[root@python uwsgi_test]# vim test.py

def application(env, start_response):
    start_response('200 OK', [('Content-Type','text/html')])
    return [b"Hello World"] # python3
    #return ["Hello World"] # python2
#这里相当于一个处理函数(视图)

 

#加入环境变量并且启动

[root@python uwsgi_test]# find / -name uwsgi 
/usr/local/python/bin/uwsgi 
[root@python uwsgi_test]# ln -sv /usr/local/python/bin/uwsgi /usr/bin/uwsgi 
[root@python uwsgi_test]# uwsgi --http :8000 --wsgi-file test.py

#启动了一个进程

10.0.0.150(克隆窗口1)

[root@python ~]# ps -ef |grep uwsgi
root      44820  44643  0 02:26 pts/4    00:00:00 uwsgi --http :8000 --wsgi-file test.py
root      44821  44820  0 02:26 pts/4    00:00:00 uwsgi --http :8000 --wsgi-file test.py
root      44879  44857  0 02:27 pts/3    00:00:00 grep --color=auto uwsgi

#看起来多个进程,但是其实是一个一个进程执行过程中启动了子进程

浏览器访问

    3.部署Django程序并测试

10.0.0.150

[root@python ~]# cd /
[root@python /]# mkdir project
[root@python project]# rs –y
[root@python project]# cd MyPerfectCRM/
[root@python MyPerfectCRM]# py manage.py runserver 0.0.0.0:9000

浏览器访问

10.0.0.150

 [root@python MyPerfectCRM]# uwsgi --http :9000 --module MyPerfectCRM.wsgi   #通过uwsgi启动我们的Django

浏览器访问

问题:静态文件看不到是因为没配置让uwsgi去找你的静态文件(但是我们一般不这样做,因为我们不需要用uwsgi去处理你的静态文件(不用理会)。而是niginx去处理,所以不理)

    4.usgi与nginx之间的线路通讯配置

10.0.0.150

[root@python MyPerfectCRM]# vim uwsgi.ini

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

通过uwsgi 启动uwsgi的配置文件方式启动django

[root@python MyPerfectCRM]# uwsgi uwsgi.ini

插入:每个请求耗时 30ms,一个 process 一秒可以处理 30 多个左右的请求,4 个 process 可以处理 120 个请求,差不多。4 核 8G,IO 型应用,process 至少可以写到 50,你先写个 32,不够再加

10.0.0.150(克隆窗口1)

[root@python ~]# ps -ef|grep uwsgi

     5.监控uwsgi的负载

10.0.0.150(克隆窗口2)

[root@python ~]# pip install uwsgitop
[root@python ~]# find / -name uwsgitop
[root@python ~]# ln -sv /usr/local/python/bin/uwsgitop /usr/bin/
[root@python ~]# uwsgitop :9191 

这个时候如果同时4个用户并发访问,不同进程进行平均接收处理

自定义做个压力512并发访问测试

    6.安装NGINX

10.0.0.150(克隆窗口1)

[root@python ~]# yum install nginx
[root@python ~]# systemctl start nginx.service #启动nginx
[root@python ~]# netstat -lntup|grep nginx

可以把参数写到配置文件里

浏览器访问

[root@python ~]# cd /etc/nginx/
[root@python nginx]# ls

根据nginx.conf配置文件找到返回给用户的html

[root@python nginx]# ls /usr/share/nginx/html/

以后写静态网站的html就可以扔到这里

    7.配置nginx和uwsgi直接的通讯配置并测试

[root@python nginx]# ls

#Nginx自身就已经和uwsgi建立了协议

把nginx的uwsgi_params该配置文件拷贝到Django项目下

[root@python nginx]# cp uwsgi_params /root/MyPerfectCRM/  
[root@python nginx]# cd conf.d/

[root@python conf.d]# vim myperfectcrm_nginx.conf 

# mysite_nginx.conf
# the upstream component nginx needs to connect to
upstream django {
    # server unix:///path/to/your/mysite/mysite.sock; # for a file socket
    server 127.0.0.1:8001; # for a web port socket (we'll use this first)
}
 
# configuration of the server
server {
    # the port your site will be served on
    listen      8000;
    # the domain name it will serve for
    server_name 10.0.0.150; # substitute your machine's IP address or FQDN
    charset     utf-8;
 
    # max upload size
    client_max_body_size 75M;   # adjust to taste
 
    # Django media
    location /media  {
        alias /path/to/your/mysite/media;  # your Django project's media files - amend as required
    }
 
    location /static {
        alias /project/MyPerfectCRM/statics; # 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/MyPerfectCRM/uwsgi_params; # the uwsgi_params file you installed
    }
} 

10.0.0.150

[root@python MyPerfectCRM]# uwsgi uwsgi.ini #重启uwsgi

10.0.0.150(克隆窗口1)

[root@python nginx]# systemctl restart nginx.service #重启nginx

浏览器访问

访问无效的url

#注意:生产环境不可以这样,这样用户都知道你有什么url,绝对不允许

#在django的setting把debug设置成Falsh

[root@python MyPerfectCRM]# cd MyPerfectCRM/
[root@python MyPerfectCRM]# vim settings.py

#生产环境setting的debug一定要该成False

[root@python nginx]# systemctl restart nginx.service #重启nginx
[root@python MyPerfectCRM]# uwsgi uwsgi.ini #重启uwsgi

浏览器访问

浏览器访问Django的admin

#上面配置静态目录指向了project/statics目录,但是admin的静态文件不在我们django的statics目录下,所以nginx找不到

解决:把django所有app的静态文件全部copy到一个目录下

[root@python MyPerfectCRM]# cd ..
[root@python MyPerfectCRM]# py manage.py collectstatic  
    #会把Django项目下,所有的html都拷贝到指定的目录)
    #输入:yes 然后报错,原因是需要在django的setting下设置所有静态文件存放的目录

[root@python MyPerfectCRM]# vim MyPerfectCRM/settings.py

[root@python MyPerfectCRM]# py manage.py collectstatic 

[root@python MyPerfectCRM]# ls all_static_files/

 

[root@python nginx]# vim conf.d/myperfectcrm_nginx.conf  #修改静态目录路径


[root@python MyPerfectCRM]# vim uwsgi.ini  #修改静态目录路径

[root@python nginx]# systemctl restart nginx.service #重启nginx
[root@python MyPerfectCRM]# uwsgi uwsgi.ini #重启uwsgi

    8.配合负载均衡

10.0.0.6(负载均衡服务器)

[root@lb02 ~]# cd /application/nginx/conf
[root@lb02 conf]# ls

[root@lb02 conf]# cat nginx.conf

10.0.0.150(克隆窗口1)

该nginx与uwsgi通讯配置 ,可以直接直接配置入nginx.conf(然后把conf.d下的myperfectcrm_nginx.conf删除掉)

[root@python nginx]# vim 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;


    # mysite_nginx.conf
    # the upstream component nginx needs to connect to
    upstream django {
        # server unix:///path/to/your/mysite/mysite.sock; # for a file socket
        server 127.0.0.1:8001; # for a web port socket (we'll use this first)
    }
 
    # configuration of the server
    server {
        # the port your site will be served on
        listen      80;
        # the domain name it will serve for
        server_name 10.0.0.150; # substitute your machine's IP address or FQDN
        charset     utf-8;
 
       # max upload size
       client_max_body_size 75M;   # adjust to taste
 
        # Django media
        location /media  {
            alias /path/to/your/mysite/media;  # your Django project's media files - amend as required
        }
 
        location /static {
            alias /project/MyPerfectCRM/all_static_files; # 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/MyPerfectCRM/uwsgi_params; # the uwsgi_params file you installed
        }
    }


# Settings for a TLS enabled server.
#
#    server {
#        listen       443 ssl http2 default_server;
#        listen       [::]:443 ssl http2 default_server;
#        server_name  _;
#        root         /usr/share/nginx/html;
#
#        ssl_certificate "/etc/pki/nginx/server.crt";
#        ssl_certificate_key "/etc/pki/nginx/private/server.key";
#        ssl_session_cache shared:SSL:1m;
#        ssl_session_timeout  10m;
#        ssl_ciphers HIGH:!aNULL:!MD5;
#        ssl_prefer_server_ciphers on;
#
#        # Load configuration files for the default server block.
#        include /etc/nginx/default.d/*.conf;
#
#        location / {
#        }
#
#        error_page 404 /404.html;
#            location = /40x.html {
#        }
#
#        error_page 500 502 503 504 /50x.html;
#            location = /50x.html {
#        }
#    }

}

    9.最终测试

10.0.0.6(负载均衡服务器)

[root@lb02 conf]# ../sbin/nginx -s  reload  #nginx

10.0.0.150(克隆窗口1)

[root@python nginx]# systemctl restart nginx.service #重启nginx
[root@python MyPerfectCRM]# uwsgi uwsgi.ini #重启uwsgi

通过访问10.0.0.3(负载均衡由于做了kepplive所以是虚拟IP)

使用域名访问

    10.查看nginx访问日志看用户访问流程

[root@python nginx]# vim nginx.conf

[root@python nginx]# cat /var/log/nginx/access.log

正常访问流程:

1.10.0.0.1(本地用户)访问10.0.0.3(负载均衡服务器ip10.0.0.6做了keeplife所以是10.0.0.3)---->
2.把请求交由负载均衡服务器(10.0.0.6)的web池随机的一个web服务器(由于是实验所以该池只指定一个web 服务器10.0.0.150(部署Django+uwsgi+nginx)。。。意味如果有多台web服务器那么再多的并发也可以承受)------>
3.把请求交由web服务器ip10.0.0.150:80端口(uwsgi+django+nginx该服务器)----->
4.然后80端口的server里的locathon把请求交本地的8001端口(nginx和uswgi互通的端口)指向端口8001----->
5.8001在把请求转交给10.0.0.150:9000(该9000端口是通过uwsgi启动我们的Django程序))


目录篇:Django总目录篇 点击跳转

猜你喜欢

转载自blog.csdn.net/Burgess_zheng/article/details/86760527
今日推荐