刨析django----Nginx反向代理与负载均衡

目录结构

  • Nginx是什么
  • 正向代理与反向代理
  • Nginx的安装
    • window安装
    • linux安装
  • 配置反向代理
    • Ubuntu1804下遇到的问题
    • Nginx反向代理案例
  • Ubuntu1804 配置Nginx的负载均衡
    • Nginx负载均衡案例
  • Nginx配置静态文件路径
  • 配置nginx的多个站点
  • 优美的404页面
  • 内建的发送邮件
    • 配置settings.py
    • 内建发邮件案例

Nginx是什么

  1. 轻量级、高性能web的服务器,支持http代理、反向代理、负载均衡等
  2. C语言编写,执行效率高
  3. 作用
    反向代理,将接收到的浏览器的http请求,转发给不同的服务器
    负载均衡,使浏览器的请求,均匀地转发给不同的服务器。

正向代理与反向代理

正向代理
刨析django----Nginx反向代理与负载均衡_第1张图片
反向代理
刨析django----Nginx反向代理与负载均衡_第2张图片
负载均衡
刨析django----Nginx反向代理与负载均衡_第3张图片
刨析django----Nginx反向代理与负载均衡_第4张图片
刨析django----Nginx反向代理与负载均衡_第5张图片
动静分离
刨析django----Nginx反向代理与负载均衡_第6张图片

Nginx的安装

nginx官网

window安装

下载压缩包,解压就可以直接使用nginx.exe
刨析django----Nginx反向代理与负载均衡_第7张图片
window10默认占用了80端口,可以更改nginx的监听端口,然后启动;或者注册表:regedit,找到HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\HTTP,在右边找到Start这一项,双击将其改为0,重启

配置项在文件nginx.conf

#配置用户 或者组
#user  lauf;
#允许生成的进程数
worker_processes  1;
#
#指定错误日志  路径 级别,可以放入全局块http 和局部块server
#级别有:debug | info | notice | warn |error | crit | alert | emerg
#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

#指定nginx进程运行文件   存放地址
#pid        logs/nginx.pid;

events {
    accept_mutex  on;   #网络连接的序列化, 防止  《惊群》  发生,
    multi_accept   on;    #一个进程 同时接受多个网络连接
    #use epoll;               #IO事件驱动模型 select | poll | epoll 

    worker_connections  1024;  #进程最大连接数,默认512
}

#全局配置http
http {
    include       mime.types;    #文件扩展名与文件类型映射表
    default_type  application/octet-stream;  #默认文件类型 ,默认为text/plain
	#
	#自定义log格式
    #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  logs/access.log  main;
    sendfile  on; #允许sendfile 方式传输文件  可以在http块、server块、location块
    #sendfile_max_chunk 100k   进程每次传输文件的上限
    #tcp_nopush     on;

	#连接超时时间 可在http/server/location块
    keepalive_timeout  65;
    #gzip  on;
	

	#配置负载均衡,并为所有的节点命名为lauf组,待选服务器列表
	upstream lauf{#默认轮询方式,一个一个地分发distribute request
		server 192.168.43.107:8000; # 公网内的局域网
		server 192.168.43.108:8000;
	}
	upstream lauf1{ #加权轮询 权重越大,被访问频率越高
		server 192.168.43.107:8000 weight=1 fail_timeout=30s;
		server 192.168.43.108:8000 weight=1;
	}	
	upstream lauf2{#ip hash
		ip_hash; #将同一个用户定位到同一个服务器上,可在应用服务端解决session问题
		server 192.168.43.107:8000;
		server 192.168.43.108:8000;
	}
	#nginx服务 运行的站点,客户端浏览器请求时,就请求该ip:port
    server {
        listen   80;   #nginx监听80端口
        server_name  127.0.0.1; #nginx监听的主机地址,为公网ip
        #keepalive_requests 120;  #单连接的请求上限
        #charset koi8-r;
        #access_log  logs/host.access.log  main;
		
		#该站点的nginx 转发 以 / 开始的请求
        location / {#匹配请求的url-->/   也可以正则,如~*^.+$     
        			#~区分大小写  ~*不区分大小写
            root   html;   #根目录
            index  index.html index.htm; # 设置默认页
            proxy_pass http://lauf;  #反向代理,lauf为反向代理的所有服务器列表
        }

        #error_page  404  /404.html;
        # redirect server error pages to the static page /50x.html
        #
        error_page   500 502 503 504  /50x.html; #错误代码对应的页面
        location = /50x.html {
            root   html;
        }


    # another virtual host using mix of IP-, name-, and port-based configuration
    #
    #server {
    #    listen       8000;
    #    listen       somename:8080;
    #    server_name  somename  alias  another.alias;

    #    location / {
    #        root   html;
    #        index  index.html index.htm;
    #    }
    #}


    # HTTPS server    是否配置https,取消注释即可
    #server {
    #    listen       443 ssl;
    #    server_name  localhost;

    #    ssl_certificate      cert.pem;
    #    ssl_certificate_key  cert.key;

    #    ssl_session_cache    shared:SSL:1m;
    #    ssl_session_timeout  5m;

    #    ssl_ciphers  HIGH:!aNULL:!MD5;
    #    ssl_prefer_server_ciphers  on;

    #    location / {
    #        root   html;
    #        index  index.html index.htm;
    #    }
    #}

}

nginx.exe服务进程启动后,在浏览器中输入地址http://127.0.0.1:port,就可以看到nginx返回的首页。

其他页面均放入root根目录(即html目录)
刨析django----Nginx反向代理与负载均衡_第8张图片
加载js/css/image等
在html根目录中创建static静态文件目录
html/static/js/
html/static/css/
html/static/image/
在页面中引用即可:

<script src='/static/js/jquery.min.js'>script>

然后就可以使用$.ajax()做跨域请求
重定向的地址也是nginx服务处理。

前后端分离的解决方案

  1. 后端服务器 Django
  2. 前端服务 Nginx+Html
    刨析django----Nginx反向代理与负载均衡_第9张图片
    sendfile 文件传输模式
    Nginx 是一个静态文件服务器(不配置转发)的时候,开启 sendfile 配置项能大大提高 Nginx 的性能。 但是当 Nginx 是作为一个反向代理(配置proxy_pass/uwsgi_pass等)来使用的时候,sendfile 则没什么用。

linux安装

以Ubuntu1804为例,nginx需安装在系统环境中

sudo apt-get install nginx
nginx -v #查看版本
nginx -t #检查配置文件是否有语法错误,每次配置完成后,执行测试

#慢则更新源 /etc/apt/sources.list
#sudo sed -i 's/xxxx/mirrors.ustc.edu.cn/g' /etc/apt/sources.list
#sudo apt-get update

也可以使用nginx压缩包的形式安装:

#解压,并进入目录
#./configure
#make
#make install
#cd sbin ---->./nginx  启动
#./nginx -s stop  强制退出
#./nginx -s quit  安全退出,关闭所有进程
#./nginx -s reload 重新加载配置文件

#注意关闭防火墙

配置反向代理

cd /etc/nginx/sites-enabled/

#默认的配置站点
sudo vim default
#gg到开头
#shift+g #跳到末尾

# Default server configuration
#!!!!!!!!!!!!配置这里
server {
        listen 80 default_server;
        listen [::]:80 default_server;
        root /var/www/html;   #静态资源根目录

        # Add index.php to the list if you are using PHP
        index index.html index.htm index.nginx-debian.html;
		
		#nginx监听的主机地址
        server_name localhost;

		#nginx转发请求的配置
        location / {
                # First attempt to serve request as file, then
                # as directory, then fall back to displaying a 404.
                #try_files $uri $uri/ =404;
                
                #所有以/开头的请求,使用uwsgi协议转发
                uwsgi_pass 192.168.245.201:8000; #只是配置一台应用服务器
                include /etc/nginx/uwsgi_params;
        }
}

启动Nginx服务

sudo /etc/init.d/nginx start
sudo /etc/init.d/nginx stop
sudo /etc/init.d/nginx restart

刨析django----Nginx反向代理与负载均衡_第10张图片
浏览器访问的ip–>为nginx服务运行的主机IP,端口为80
此时uWSGI服务为socket监听方式,启动时查看进程(只有两项),与http监听方式有所不同

socket=192,168.245.201:8000
其他参数同http监听方式

启动顺序:
1.启动uWSGI服务(django代码更新,则重启)
2.启动nginx
3.浏览器发送请求到nginx主机的地址

Ubuntu1804下遇到的问题

502问题:bad gateway, nginx配置成功,可能uWSGI服务未启动!
若明明启动了uWSGI,还报错,那就是nginx配置的uwsgi_pass 转发地址错误

原理:
刨析django----Nginx反向代理与负载均衡_第11张图片

  1. uWSGI服务未启动
    刨析django----Nginx反向代理与负载均衡_第12张图片
  2. Nginx 配置的uwsgi_pass 地址与uWSGI socket监听的地址不一致
    刨析django----Nginx反向代理与负载均衡_第13张图片
    Nginx+uWSGI+django后台启动
    具体排错:看日志!!!!!!!
    /etc/nginx/nginx.conf 基础配置
    /var/log/nginx/access.log
    /var/log/nginx/error.log
    uwsgi.log
    两端一起排查!!!!!

404问题

  1. django中路由不存在
  2. nginx配置未禁止try-files

Nginx反向代理案例

  1. 只需简单配置Nginx服务
    /etc/nginx/sites-enabled/default
    #Default Server Configure
    location / {
    uwsgi_pass 127.0.0.1:8000;
    include /etc/nginx/uwsgi_params;
    }
  2. 启动uWSGI + Nginx
  3. 浏览器访问 http://127.0.0.1:80/test_wsgi/
    ip -->本地loop / 局域网ip / 公网ip 能到达nginx就行

nginx+uwsgi+django
提取码:yt0b

Ubuntu1804 配置Nginx的负载均衡

配置文件的结构:
刨析django----Nginx反向代理与负载均衡_第14张图片

Nginx负载均衡案例

链接:测试项目代码
提取码:npmv

  1. 将该项目使用uwsgi方式部署在两台Ubuntu服务器上,注意修改如下:
#settings.py
DEBUG = False
ALLOWED_HOSTS = ['localhost', "master", '192.168.43.107', '192.168.43.108']

#uwsgi.ini ,监听的每一台主机地址
#server1部署的django
socket=192.168.43.107:8000
#server2部署的django
socket=192.168.43.108:8000

注意django&uwsgi 配置时,都没有 ;结尾
分别在部署的服务器上,使用uwsgi启动django应用

uwsgi --ini uwsgi.ini
#确认是否启动
ps -aux | grep -i "uwsgi"
  1. 配置nginx的反向代理、负载均衡
    方法参考以上理论内容
#/etc/nginx/nginx.conf
http{
	#添加负载均衡
	upstream django{
		server 192.168.43.107:8000;   #注意有分号 ip为对应的部署服务器地址
		server 192.168.43.108:8000;
	}
}

#/etc/nginx/sites-available/
sudo vim master
server {
        listen 80;
        listen [::]:80; #ipv6 
        root /var/www/master/html; #自己创建该目录
        # Add index.php to the list if you are using PHP
        index index.html index.htm index.nginx-debian.html;
        server_name master www.master; #nginx运行的本机域名,即192.168.43.107
        #dynamic file
        location / {
                uwsgi_pass django; #django为定义的负载均衡服务器列表
                include /etc/nginx/uwsgi_params;
        }
}

#创建软连接
sudo ln -s /etc/nginx/sites-available/master  /etc/nginx/sites-enabled/master

#检查配置是否有语法错误
nginx -t

启动nginx服务

sudo service nginx restart
  1. 浏览器访问http://192.168.43.107:80/lauf/test_mail/
    局域网内测试结果
    刨析django----Nginx反向代理与负载均衡_第15张图片
    局域网内,使用window 连接linux,请求到达192.168.43.107主机的80端口,即nginx运行的主机的80端口,nginx对请求做负载均衡。可以走如下两个地址:
    192.168.43.107:8000
    192.168.43.108:8000
    不管走哪个地址,uwsgi服务匹配完成后(gateway网关没问题),当前请求的Host: 192.168.43.107(地址栏) 必须是可以进入django应用的,即ALLOWED_HOSTS=[ ] 要包含该Host地址。否则请求无法到达django。
    可以尝试只在一个django应用服务器中配置ALLOWED_HOSTS = [‘192.168.43.107’],这时请求每次就只能分发给这一个应用服务器。因为另一个应用服务器,它无法到达

  2. 浏览器访问http://master:80/lauf/test_mail/
    局域网内测试结果
    通过域名解析,得到ip地址,同样请求到达nginx。负载均衡时,同样可以选择两个地址中的任意一个,
    192.168.43.107:8000
    192.168.43.108:8000
    uwsgi服务匹配完成后,当前请求(此时Host:master)要进入django应用,必须设置ALLOWED_HOSTS=[‘master’]

Nginx配置静态文件路径

上个项目尝试请求http://127.0.0.1:80/admin/
发生了什么?
刨析django----Nginx反向代理与负载均衡_第16张图片
很简陋的一个页面
静态文件未加载到

  1. 在linux创建一个目录,存储django的静态文件
    /home/lauf/project_static
  2. settings.py配置
STATIC_ROOT = "/home/lauf/project_static/static"
  1. 收集django静态文件,复制到linux目录
python3 manage.py collectstatic
#收集django的静态文件,复制到STATIC_ROOT
#查看project_static目录  有个static文件夹
  1. 配置nginx的静态路径
sudo vim /etc/nginx/sites-enabled/default

#default server configure
location /static {
	root /home/lauf/project_static;
}
  1. 重新访问127.0.0.1:80/admin/
    刨析django----Nginx反向代理与负载均衡_第17张图片
    刨析django----Nginx反向代理与负载均衡_第18张图片

配置nginx的多个站点

项目在部署时,通常放在多个应用服务器,然后通过nginx配置反向代理、负载均衡。
下面为nginx服务配置两个站点
192.168.43.107 master
192.168.43.108 slave1

  1. 在nginx主机上配置/etc/hosts
sudo vim /etc/hosts
192.168.43.107 master
192.168.43.108 slave1

#保存

在192.168.43.107、192.168.43.108应用服务器上配置自己的域名(/etc/hostname)
如下:

sudo vim /etc/hostname
master
  1. 在nginx主机/var/www目录下,创建root站点目录
cd /var/www
sudo mkdir -p master/html
sudo mkdir -p slave1/html

确保两个目录与nginx属于同一用户名:用户组

然后分别为两个目录创建index.html 入口文件

sudo vim /var/www/master/html/index.html

<html>
    <head>
        <title>Welcome to master!</title>
    </head>
    <body>
        <h1>Success!  The master server block is working!</h1>
    </body>
</html>

同样的方法处理slave1/html/index.html

  1. 配置nginx站点
    在安装完成nginx时,在/etc/nginx/sites-available/ 下有个默认的default配置文件,然后在sites-enabled下创建一个default软连接。这里需要分别为master、slave1配置一个配置文件。
cd /etc/nginx/sites-available
sudo cp default master
sudo cp default slave1
#删除default,或者可以将它备份到其他地方,然后删除当前目录的default
sudo rm -rf default

修改master

sudo vim master

#清空,并写入如下内容
server {
        listen 80;
        listen [::]:80;

        root /var/www/master/html;
        index index.html index.htm index.nginx-debian.html;

        server_name master www.master;

        location / {
                #try_files $uri $uri/ =404;
                uwsgi_pass 192.168.43.107:8000;
                include /etc/nginx/uwsgi_params;
        }
}

修改slave1

sudo vim slave1

#清空,并写入如下内容
server {
        listen 80;
        listen [::]:80;

        root /var/www/slave1/html;
        index index.html index.htm index.nginx-debian.html;

        server_name slave1 www.slave1;

        location / {
                #try_files $uri $uri/ =404;
                uwsgi_pass 192.168.43.108:8000;
                include /etc/nginx/uwsgi_params;
        }
}

创建软连接

sudo ln -s /etc/nginx/sites-available/master  /etc/nginx/sites-enabled/master
sudo ln -s /etc/nginx/sites-available/slave1  /etc/nginx/sites-enabled/slave1

检查nginx是否有配置错误

sudo nginx -t

#启动
sudo service nginx restart 

成功启动

优美的404页面

默认的404:
在这里插入图片描述
优化的404:–自定义/templates/404.html
DEBUG=False真实上线
在这里插入图片描述

内建的发送邮件

django内部异常时,自动发送邮件
基础配置+SERVER_EMAIL+ADMINS

过滤敏感变量
sensitive_variables
sensitive_post_parameters

配置settings.py

#必须基础配置,配置邮件服务器
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'smtp.qq.com'
EMAIL_PORT = 25
EMAIL_HOST_USER = '[email protected]'
EMAIL_HOST_PASSWORD = '授权码'
EMAIL_USE_TLS = False  

#视图异常时,自动发邮件配置,只需配置SERVER_EMAIL/ADMINS
DEBUG = False
#发件人
SERVER_EMAIL = "[email protected]"
#接收人列表
ADMINS = [("laufing","[email protected]")] #收件人列表

视图函数:

from django.views.decorators.debug import sensitive_variables,sensitive_post_parameters

@sensitive_variables("a","b",...)
def process_view(request):   
	raise ValueError("xxxx")   #发生异常,自动发送邮件,然后返回500的相应; 发邮件会阻塞后面的相应
	return HttpResponse("xxxx")
	
@sensitive_post_parameters
def process_data(request):
	pw = request.POST["pw"]
	raise ValueError("xxx")
	return HttpResponse("xxxx")

装饰器必须在所有装饰器的顶层
装饰的视图异常时,自动发送邮件,然后返回响应

内建发邮件案例

链接:自动发送邮件
提取码:u5y5

 
 
上一篇:刨析django----项目部署    下一篇:刨析django----阶段项目2

你可能感兴趣的:(后端django,nginx,django)