zl程序教程

您现在的位置是:首页 >  后端

当前栏目

部署上线-部署Django项目

2023-06-13 09:12:34 时间

一、启动方式

项目配置文件settings.py

DEBUG = <span class="hljs-keyword">False</span> <span class="hljs-comment">#DEBUG为True时,django会自动为你静态文件代理,不过当DEBUG为False时,意味着你要进入生产环境,那么,你就必须使用STATIC_ROOT来指明你的静态文件在哪里</span>

ALLOWED_HOSTS = [<span class="hljs-string">"*"</span>]

runserver方式

启动命令:python manage.py runserver 0.0.0.0:8000

浏览器地址栏:http://39.107.226.105:8000/students/

问题:

  • runserver是一个纯python编写的轻量级服务器,且不稳定
  • 应用服务器直接对接客户,只能提供一台服务
  • 地址栏需要输入端口号

uwsgi方式

安装:pip install uwsgi

注意:在工程目录下创建名为uwsgi.ini的文件

[uwsgi]
#使用nginx连接时使用
#socket=0.0.0.0:8000
#直接做web服务器使用
http=0.0.0.0:8000
#项目目录
chdir=/home/sunck/project
#项目中wsgi.py文件的目录,相对于项目目录
wsgi-file=project/wsgi.py
processes=4
threads=2
master=True
pidfile=uwsgi.pid
daemonize=uwsgi.log

启动:uwsgi --ini uwsgi.ini

结束:uwsgi --stop uwsgi.pid

浏览器地址栏:http://39.107.226.105:8000/students/

问题:

  • 应用服务器直接对接客户,只能提供一台服务
  • 地址栏需要输入端口号

一个相对可以应用与开发的uwsgi.ini

[uwsgi]
listen = 100
master = true
socket-timeout = 30
stats =  127.0.0.1:1730
post-buffering =  100M
cpu-affinity = true

single-interpreter = true
socket = 0.0.0.0:9090
socket = /tmp/uwsgi.sock
# 缓存体系
cache = true
cache2 = name=mycache,items=100
lazy-apps = true
wsgi-disable-file-wrapper = true
memory-report = true
uid = root
master = true
vhost = true
no-stie = true
workers = 2
reload-mercy = 10
vacuum = true
max-requests = 3500
limit-as = 1024
buffer-sizi = 65535
pidfile = /var/run/uwsgi.pid
master-fifo = /tmp/uwsgififo
daemonize = /var/log/uwsgi/uwsgi.log
log-maxsize = 10000000000
enable-threads=true
die-on-term=true
wsgi-disable-file-wrapper=true
#env= LUFFY_ENV=Production
#pythonpath=/server/virtual/IronThrone/lib/python3.6/site-packages

解决静态文件问题

settings.py

STATIC_URL = <span class="hljs-string">'/static/'</span>
STATIC_ROOT = os.path.join(BASE_DIR, <span class="hljs-string">"collectedstatic"</span>)
STATICFILES_DIRS = [
    os.path.join(BASE_DIR, <span class="hljs-string">"static"</span>)
]

迁移静态文件到STATIC_ROOTpython manage.py collectstatic

project/urls.py

<span class="hljs-keyword">from</span> django.contrib <span class="hljs-keyword">import</span> admin
<span class="hljs-keyword">from</span> django.urls <span class="hljs-keyword">import</span> path, re_path, include

<span class="hljs-keyword">from</span> django.views <span class="hljs-keyword">import</span> static
<span class="hljs-keyword">from</span> django.conf <span class="hljs-keyword">import</span> settings 
<span class="hljs-keyword">from</span> django.conf.urls <span class="hljs-keyword">import</span> url 

urlpatterns = [
    path(<span class="hljs-string">'admin/'</span>, admin.site.urls),
    path(<span class="hljs-string">''</span>, include((<span class="hljs-string">"Axf.urls"</span>, <span class="hljs-string">"Axf"</span>), namespace=<span class="hljs-string">"Axf"</span>)),
    url(<span class="hljs-string">r'^static/(?P&lt;path&gt;.*)$'</span>, static.serve, {<span class="hljs-string">'document_root'</span>: settings.STATIC_ROOT}, name=<span class="hljs-string">'static'</span>),
]

二、代理

代理在网络中使用是比较常见的,比如大家去国外网站查找学习资料的时候就会用到代理。其原理也比较简单:

  • 用户将请求发给代理服务器
  • 代理服务器代用户去访问数据
  • 代理服务器将数据给用户

​ 正常没有代理情况上网

​ 代理服务器场景

说明:代理服务器扮演的就是一个中间人的角色

代理分为正向代理和反向代理两种类型:

  • 正向代理:代理用户访问其他网站,比如ss,蓝灯
  • 反向代理:用来发布服务器,比如nginx

正向代理

我是一个用户,我访问不了某网站,但是我能访问一个代理服务器,这个代理服务器呢,他能访问那个我不能访问的网站,于是我先连上代理服务器,告诉他我需要那个无法访问网站的内容,代理服务器去取回来,然后返回给我

概念:是一个位于客户端和原始服务器(origin server)之间的服务器,为了从原始服务器取得内容,客户端向代理发送一个请求并指定目标(原始服务器),然后代理向原始服务器转交请求并将获得的内容返回给客户端

作用:

  • 为在防火墙内的局域网客户端提供访问Internet的途径
  • 使用缓冲特性减少网络使用率

反向代理

概念:以代理服务器来接受internet上的连接请求,然后将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给internet上请求连接的客户端,此时代理服务器对外就表现为一个反向代理服务器

作用:

  • 堡垒机 堡垒机承担所有的外部访问,保护后端服务器的安全。就是将防火墙后面的服务器提供给Internet用户访问
  • 业务发布服务器 将多个服务器通过虚拟主机的方式发布到公网
  • 缓存服务器 CDN加速即内容分发网络,其基本思路是尽可能避开互联网上有可能影响数据传输速度和稳定性的瓶颈和环节,使内容传输的更快、更稳定

3、反向代理部署流程

服务器:39.107.226.105(Nginx服务器)、39.107.226.106(DJango应用服务器)

说明:DJango服务使用runserve启动python manage.py runserver 0.0.0.0:8000

user nginx;
worker_processes 1;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
include /usr/share/nginx/modules/*.conf;
events {
    use epoll;
    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;
    include             /etc/nginx/conf.d/*.conf;
    server {
        listen       80 default_server;
        listen       [::]:80 default_server;
        server_name  _;
        charset      koi8-r;
        location / {
	          proxy_pass   http://39.107.226.106:8000;
        }
        error_page 404 /404.html;
            location = /40x.html {
        }
        error_page 500 502 503 504 /50x.html;
            location = /50x.html {
        }
    }
}

反向代理优化

location / {
    proxy_pass       http://39.107.226.105:8000;
    proxy_set_header X-real-ip $remote_addr;
    proxy_set_header Host $http_host;
    client_max_body_size 10m; #允许客户端请求的最大单文件字节数
    client_body_buffer_size 128k; #缓冲区代理缓冲用户端请求的最大字节数,
    proxy_connect_timeout 90; #nginx跟后端服务器连接超时时间(代理连接超时)
    proxy_send_timeout 90; #后端服务器数据回传时间(代理发送超时)
    proxy_read_timeout 90; #连接成功后,后端服务器响应时间(代理接收超时)
    proxy_buffer_size 4k; #设置代理服务器(nginx)保存用户头信息的缓冲区大小          
    proxy_buffers 4 32k; #proxy_buffers缓冲区,网页平均在32k以下的话,这样设置          
    proxy_busy_buffers_size 64k; #高负荷下缓冲大小(proxy_buffers*2)
    proxy_temp_file_write_size 64k; #设定缓存文件夹大小,大于这个值,将从upstream服务器传
}

浏览器地址栏:http://39.107.226.105/students/

4、uwsgi部署流程

服务器:39.107.226.105(Nginx服务器)、39.107.226.106(DJango应用服务器)

工程目录下创建uwsgi.ini文件

[uwsgi]
#使用nginx连接时使用
socket=0.0.0.0:8000
#直接做web服务器使用
#http=0.0.0.0:8000
#项目目录
chdir=/home/sunck/project
#项目中wsgi.py文件的目录,相对于项目目录
wsgi-file=project/wsgi.py
processes=4
threads=2
master=True
pidfile=uwsgi.pid
daemonize=uwsgi.log

启动DJango服务:uwsgi --ini uwsgi.ini

user nginx;
worker_processes 1;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
include /usr/share/nginx/modules/*.conf;
events {
    use epoll;
    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;
    include             /etc/nginx/conf.d/*.conf;
    server {
        listen       80 default_server;
        listen       [::]:80 default_server;
        server_name  _;
        charset      koi8-r;
        location / {
            include uwsgi_params;
            uwsgi_pass 39.107.226.106:8000;
        }
        error_page 404 /404.html;
            location = /40x.html {
        }
        error_page 500 502 503 504 /50x.html;
            location = /50x.html {
        }
    }
}

浏览器地址栏:http://39.107.226.105/students/

三、集群搭建

  1. 客户端通过浏览器 发起请求 代理服务器
  2. 代理服务器 接受请求
  3. 代理服务器 发起请求 业务服务器
  4. 业务服务器 接受请求
  5. 业务服务器 处理请求
  6. 业务服务器 响应请求 代理服务器
  7. 代理服务器 响应请求 客户端
  8. 客户端通过浏览器渲染请求并展示给用户

主机

  • 39.107.226.105(Nginx)
  • 10.107.226.1(Django应用)
  • 10.107.226.2(Django应用)
  • 10.107.226.3(Django应用)
  • 101.107.226.109(数据库)

Nginx负载均衡算法

概念:负载均衡是由多台服务器以对称的方式组成一个服务器集合,每台服务器都具有等价的地位,都可以单独对外提供服务而无须其他服务器的辅助。通过某种负载分担技术,将外部发送来的请求按照事先设定分配算法分配到对称结构中的某一台服务器上,而接收到请求的服务器独立地回应客户的请求

作用:均衡负载能够平均分配客户请求到服务器列阵,籍此提供快速获取重要数据,解决大量并发访问服务问题

算法

说明

轮询

每个请求按时间顺序逐一分配到不同的后端服务器,如果后端某台服务器宕机,故障系统被自动剔除,使用户访问不受影响

weight

指定轮询权值,weight的值越大分配到的访问概率越高,主要用于后端每台服务器性能不均衡的情况下。或者仅仅为在主从的情况下设置不同的权值,达到合理有效的地利用主机资源

ip_hash

根据获取客户端的IP地址,通过哈希函数计算得到的一个数值,用该数值对服务器列表的大小进行取模运算,得到的结果便是客服端要访问服务器的序号。采用源地址哈希法进行负载均衡,同一IP地址的客户端,当后端服务器列表不变时,它每次都会映射到同一台后端服务器进行访问,有效解决了动态网页存在的session共享问题

fair

比上面的更加智能的负载均衡算法。此种算法可以依据页面大小和加载时间长短智能地进行负载均衡,也就是根据后端服务器的响应时间来分配请求,响应时间短的优先分配。Nginx本身是不支持fair的,如果需要使用这种调度算法,必须下载Nginx的upstream_fair模块

url_hash

按访问url的hash结果来分配请求,使每个url定向到同一个后端服务器,可以进一步提高后端缓存服务器的效率。Nginx本身是不支持url_hash的,如果需要使用这种调度算法,必须安装Nginx 的hash软件包

Nginx负载均衡调度状态

在Nginx upstream模块中,可以设定每台后端服务器在负载均衡调度中的状态

状态参数

说明

down

表示当前的server暂时不参与负载均衡

weight

默认为1,weight越大,负载的权重就越大

max_fails

允许请求失败的次数,默认为1。当超过最大次数时,返回proxy_next_upstream 模块定义的错误

fail_timeout

在经历了max_fails次失败后,暂停服务的时间,默认为10s。max_fails可以和fail_timeout一起使用

backup

预留的备份机器,当其他所有的非backup机器出现故障或者忙的时候,才会请求backup机器,因此这台机器的压力最轻

注意:当负载调度算法为ip_hash时,后端服务器在负载均衡调度中的状态不能是weight和backup

upstream模块案例

基于轮询算法

    upstream web1 {
        server 10.107.226.1:8000 max_fails=1 fail_timeout=10s;
        server 10.107.226.2:8000 max_fails=1 fail_timeout=10s;
        server 10.107.226.3:8000 max_fails=1 fail_timeout=10s;
        server 10.107.226.4:8000 backup;
        server 10.107.226.5:8000 down;
    }

基于weight轮询

    upstream web2 {
        server 10.107.226.1:8000 weight=1 max_fails=1 fail_timeout=10s;
        server 10.107.226.2:8000 weight=2 max_fails=1 fail_timeout=10s;
        server 10.107.226.3:8000 weight=3 max_fails=1 fail_timeout=10s;
        server 10.107.226.4:8000 backup;
        server 10.107.226.5:8000 down;
    }

基于ip_hash

    upstream web3 {
        ip_hash;
        server 10.107.226.1:8000 max_fails=1 fail_timeout=10s;
        server 10.107.226.2:8000 max_fails=1 fail_timeout=10s;
        server 10.107.226.3:8000 max_fails=1 fail_timeout=10s;
        server 10.107.226.5:8000 down;
    }

Nginx服务上部署静态文件

        location /static {
            alias /var/www/ty/collectedstatic/;
        }

注意:DJango应用的settings.py文件中的STATIC_ROOT参数不是为了提供静态文件,而是为了迁移静态

STATIC_URL = <span class="hljs-string">'/static/'</span>
STATIC_ROOT = os.path.join(BASE_DIR, <span class="hljs-string">"collectedstatic"</span>)
STATICFILES_DIRS = [
    os.path.join(BASE_DIR, <span class="hljs-string">"static"</span>)
]

迁移静态文件到STATIC_ROOTpython manage.py collectstatic

project/urs.py文件无需使用url定位静态文件了,因为Nginx已经把这个活干了

<span class="hljs-keyword">from</span> django.contrib <span class="hljs-keyword">import</span> admin
<span class="hljs-keyword">from</span> django.urls <span class="hljs-keyword">import</span> path, re_path, include

<span class="hljs-comment">#from django.views import static</span>
<span class="hljs-comment">#from django.conf import settings </span>
<span class="hljs-comment">#from django.conf.urls import url </span>

urlpatterns = [
    path(<span class="hljs-string">'admin/'</span>, admin.site.urls),
    path(<span class="hljs-string">''</span>, include((<span class="hljs-string">"Axf.urls"</span>, <span class="hljs-string">"Axf"</span>), namespace=<span class="hljs-string">"Axf"</span>)),
    <span class="hljs-comment">#url(r'^static/(?P&lt;path&gt;.*)$', static.serve, {'document_root': settings.STATIC_ROOT}, name='static'),</span>
]

注意:将应用服务器上的collectedstatic静态目录拷贝到Nginx所在主机下规定的位置即可

user nginx;
worker_processes 1;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
include /usr/share/nginx/modules/*.conf;
events {
    use epoll;
    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;
    include             /etc/nginx/conf.d/*.conf;
    
    upstream web1 {
        server 10.107.226.1:8000 max_fails=1 fail_timeout=10s;
        server 10.107.226.2:8000 max_fails=1 fail_timeout=10s;
        server 10.107.226.3:8000 max_fails=1 fail_timeout=10s;
        server 10.107.226.4:8000 backup;
        server 10.107.226.5:8000 down;
    }

    server {
        listen       80 default_server;
        listen       [::]:80 default_server;
        server_name  _;
        charset      koi8-r;
        location / {
            include uwsgi_params;
            uwsgi_pass web1;
        }
	      location /static {
	          alias /var/www/ty/collectedstatic/;
	      }
        error_page 404 /404.html;
            location = /40x.html {
        }
        error_page 500 502 503 504 /50x.html;
            location = /50x.html {
        }
    }
}

四、HTTPS访问

Nginx配置

user nginx;
worker_processes 1;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
include /usr/share/nginx/modules/*.conf;
events {
    use epoll;
    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;
    include             /etc/nginx/conf.d/*.conf;
    server {
        listen       443 ssl http2 default_server;
        listen       [::]:443 ssl http2 default_server;
        server_name  _;
        charset      koi8-r;

        ssl_certificate "/etc/nginx/pki/server.crt";
        ssl_certificate_key "/etc/nginx/pki/private/server.key";
        ssl_session_cache shared:SSL:1m;
        ssl_session_timeout  10m;
        ssl_ciphers PROFILE=SYSTEM;
        ssl_prefer_server_ciphers on;

        location / {
            include uwsgi_params;
            uwsgi_pass 101.201.148.195:8000;
        }
        error_page 404 /404.html;
            location = /40x.html {
        }
        error_page 500 502 503 504 /50x.html;
            location = /50x.html {
        }
    }
}

注意:创建/etc/nginx/pki/目录与/etc/nginx/pki/private

购买SSL证书