2.2.0Nginx代理与负载均衡

TOC

Nginx代理proxy_pass与负载均衡upstream

参考:

Nginx代理服务

代理语法:

Syntax: proxy_pass URL;
Default:-
Context:location,if in location,limit_except

正向代理:

案例1

code文件夹中的html:jesonc.html

<html>
<head>
    <meta charset="utf-8">
    <title>jeson1</title>
</head>
<body >
    <h1>Jeson<h1>
</body>
</html>

配置

server {
    listen       80;
    server_name  localhost jeson.t.imooc.io;

    #charset koi8-r;
    access_log  /var/log/nginx/host.access.log  main;

    location / {
        # http_x_forwarded_for放的是所有d代理的ip信息
        if ( $http_x_forwarded_for !~* "^192.168.0.173") { # 192.168.0.173 是我准备的地址
            return 403;
        }
        root   /usr/share/nginx/html/code;
        index  index.html index.htm;
    }

    #error_page  404              /404.html;

    # redirect server error pages to the static page /50x.html
    #
    error_page   500 502 503 504 404  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
}

直接访问 http://jeson.t.imooc.io/jesonc.html 提示403

在192.168.0.173 上配置正向代理:

192.168.0.173上的nginx配置

server {
    listen       80;
    server_name  localhost jeson.t.imooc.io;

    #charset koi8-r;
    access_log  /var/log/nginx/test_proxy.access.log  main;
    resolver 8.8.8.8;   # 添加进行域名解析
    location / {
        proxy_pass http://$http_host$request_uri; # 将请求专区转到对应的 主机名,url
    }

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
}

浏览器设置代理:将 192.168.0.173 80 设置上

这是访问http://jeson.t.imooc.io/jesonc.html 就会自动调用代理,就能访问到了

在这里插入图片描述

案例2

Nginx正向代理只需要配置 location 中配置proxy_pass 属性即可。其指向代理的服务器地址。正如我们上一篇文章配置的百度的代理:
在这里插入图片描述

这是一个经典的正向代理的例子。

Nginx的反向代理

案例1

html页面

<html>
<head>
    <meta charset="utf-8">
    <title>imooc1</title>
</head>
<body style="background-color:red;">
    <h1>Welcome to jeson.t.imooc.io</h1>
</body>
</html>

host设置

192.168.179.128 jeson.t.imooc.io

配置1:realserver.conf

监听了8080端口

server {
    listen       8080;
    server_name  localhost jeson.t.imooc.io;

    #charset koi8-r;
    access_log  /var/log/nginx/server.access.log  main;

    location / {
        root   /usr/share/nginx/html/code2;
        index  index.html index.htm;
    }

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }

}

配置2:反向代理fx_proxy.conf

监听了80端口

当匹配 /test_proxy.html$ 的时候,会用 proxy_pass,转为请求 http://127.0.0.1:8080;

server {
    listen       80;
    server_name  localhost jeson.t.imooc.io;

    #charset koi8-r;
    access_log  /var/log/nginx/test_proxy.access.log  main;

    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }

    location ~ /test_proxy.html$ {
        proxy_pass http://127.0.0.1:8080;
    }

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }

}

在服务器/容器 查看nginx的端口

在这里插入图片描述

由于nginx服务/nginx容器只开发了80端口,所以在访问8080端口的时候 http://jeson.t.imooc.io:8080/test_proxy.html ,会无法找到页面

在这里插入图片描述

若是访问80端口 http://jeson.t.imooc.io/test_proxy.html 进入的就是默认的 fx_proxy.conf /设置的/test_proxy.html$配置,进而调用了http://127.0.0.1:8080 --> realserver.conf-->默认的/

http://jeson.t.imooc.io域名改为了 http://127.0.0.1:8080 域名

小例子

首先启动两个应用,端口分别是8010和8020,访问/hello:

在这里插入图片描述

img

然后我们在nginx中,首先反向代理一个地址:

server {
    listen 80;
    server_name www.demo.com;
    location / {
        proxy_pass http://127.0.0.1:8080;
    }
}

可以看到,监听80端口,代理的是8010的端口地址,路径是/hello。然后在配置一下本地

host

192.168.168.129 www.demo.com

然后访问可以看到反向代理成功:

可以看到正向代理和反向代理在配置上区别不大,主要区别是被代理的服务的位置,一个是远程(百度),一个是局域网内部(本机8010)。

案例3

反向代理还有一个用途就是在多个站点配置多个二级域名,比如百度的搜索引擎是 www.baidu.com,百度图片是 image.baidu.com,百度翻译是 fanyi.baidu.com,可以看到,一级域名一样,二级域名不同,代表了不同的系统。这种方式利用nginx的反向代理也可以实现,

server {
    listen 80;
    server_name test1.demo.com;
    location / {
        proxy_pass http://127.0.0.1:8010;
    }
}
server {
    listen 80;
    server_name test2.demo.com;
    location / {
        proxy_pass http://127.0.0.1:8020;
    }
}

host

192.168.168.129 test1.demo.com
192.168.168.129 test2.demo.com

可以看到,两个不同的二级域名分别访问两个不同的端口地址,访问效果如下:

在这里插入图片描述

在这里插入图片描述

这样可以做到在一个服务器上部署多个项目,分别使用有意义的二级域名。

缓冲区:proxy_buffering

Syntax: proxy_buffering on | off;
Default:proxy_buffering on;
Context:http,server,location

扩展:proxy_buffer_size、proxy_buffers、proxy_busy_buffers_size

减少了包个数,减少了io损耗;

默认在内存里,内存不够在硬盘里

跳转重定向:proxy_redirect

Syntax: proxy_redirect default; proxy_redirect off;proxy_redirect redirect replacement;
Default:proxy_redirect default;
Context:http,server,location,

头信息

Syntax: proxy_set_header field value;
Default:proxy_set_header Host $proxy_host;
proxy_set_header Connection close;
Context:http,server,location

扩展:proxy_hide_header(隐藏一部分后,不让后端访问到)、proxy_set_body(在body中添加一些自定义字符)

新增一个头信息,记录代理前的准确的头信息

超时

Syntax:proxy_connect_timeout time; #请求连接的时间
Default:proxy_connect_timeout 60s;
Context:http,server,location

扩展:proxy_read_timeout(已经建立连接后,等待(处理)的时间)、proxy_send_timeout(向客户端发送的时间)

代理相关参数

proxy_pass   http://127.0.0.1:8080;       # 代理服务

proxy_redirect default|off;  # 是否允许重定向

proxy_set_header Host $host; # 传 header 参数至后端服务

proxy_set_header X-Forwarded-For $remote_addr; # 设置 即客户端IP 地址

proxy_connect_timeout 90; # 连接代理服务超时时间

proxy_send_timeout 90; # 请求发送最大时间

proxy_read_timeout 90;  # 读取最大时间

proxy_buffer_size 32k; # 缓冲区第一部分头信息大小

proxy_buffering on; #打开缓冲区

proxy_buffers 4 128k; #缓冲区,先用这个

proxy_busy_buffers_size 256k; # 再用这个

proxy_temp_file_write_size 256k; # 大文件或者上面满了用这个

使用 nginx -V,可以看到缓冲区配置:--http-proxy-temp-path=/var/cache/nginx/proxy_temp

这种配置一般是通用的,可以创建一个文件,然后在location中使用 include引入;

负载均衡

所有客户端的请求通过proxy_pass转发到一组虚拟的服务池(upstream server:这里面的服务是能够提供相同的服务的集合),请求轮询访问服务器

通过proxy_pass 可以把请求代理至后端服务,但是为了实现更高的负载及性能, 我们的后端服务通常是多个, 这个是时候可以通过upstream模块实现负载均衡。

语法:

Syntax: upstream name {...}
Default:一
Context:http

upstream

一个案例:

upstream backend{
    server backendl.example.com weight=5;
    server backend2.example.com:8080;
    server unix:/tmp/backend3;

    server backupl.example.com:8080 backup;
    server backup2.example.com:8080 backup;
}
  • upstream后面是组的名字
  • upstream里面是每一个server
    • server支持:
    • 域名
    • ip
    • 域名或者ip:端口
    • socket方式
    • server配置后面还可以加小的参数:
    • backup:这是一个备份结点
    • weight权重,越大,轮询分配的可能越高

案例1:开启负载均衡

启用两个服务器,其中一个启动三个服务

#服务1 server1.conf
server {
    listen       8001;
    server_name  localhost;

    access_log  /var/log/nginx/log/server1.access.log  main;

    location / {
        root   /opt/app/code1;
        index  index.html index.htm;
    }
    error_page   500 502 503 504 404  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
}

#服务2 server2.conf
server {
    listen       8002;
    server_name  localhost;

    access_log  /var/log/nginx/log/server2.access.log  main;

    location / {
        root   /opt/app/code2;
        index  index.html index.htm;
    }

    error_page   500 502 503 504 404  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
}

#服务3 server3.conf
server {
    listen       8003;
    server_name  localhost;
    #access_log  /var/log/nginx/log/server2.access.log  main;

    location / {
        root   /opt/app/code3;
        index  index.html index.htm;
    }
    error_page   500 502 503 504 404  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
}

负载均衡配置:upstream_test.conf

    upstream imooc { #名字
        server 116.62.103.228:8001; #节点
        server 116.62.103.228:8002;
        server 116.62.103.228:8003;
    }

server {
    listen       80;
    server_name  localhost jeson.t.imooc.io;

    access_log  /var/log/nginx/test_proxy.access.log  main;
    resolver  8.8.8.8;

    location / {
        proxy_pass http://imooc; #把请求代理至后端服务,代理
        include proxy_params;
    }
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
}

另一台服务, 此时访问:http://jeson.t.imooc.io 访问的就是上面配置的三个服务的了,默认是轮询的

此时关闭一个服务

# 由于是使用的nginx配置的进程服务,若是关闭的话,只能三个一起关了,所以使用下面的
iptables -I INPUT -p tcp --dport 8002 -j DROP # 把所有请求8002的请求关掉--不对外提供8002端口

此时访问,请求就会在server1和server3之间轮询---server2挂掉之后,nginx就会自动处理,将server2服务下线了

案例3

下面来配置一个upstream:

upstream wwwdemocom{
    server 127.0.0.1:8010;
    server 127.0.0.1:8020;
}

可以看到把两个服务地址都定义到了一个upstream中,并起名为wwwdemocom,下面设置反向代理:

server {
    listen 80;
    server_name www.demo.com;
    location / {
        proxy_pass http://wwwdemocom;
    }
}

反向代理的配置中,只配置upstream的名字即可,刷新页面,可以看到同一个地址,不停的分别访问两个项目:

在这里插入图片描述

在这里插入图片描述

这样如果我们部署多个相同的系统,可以把所有的并发流量分到多个上面,从而达到提高并发的目的。

后端服务器在负载均衡调度中的状态

参数 定义
down 当前的server暂时不参与负载均衡
backup 预留的备份服务器
max_fails 允许请求失败的次数
fail_timeout 经过max_fails失败后,服务暂停的时间
max_conns 限制这个服务最大的接收的连接数
weight 权重

案例2:测试备份节点backup

配置服务:upstream_test.conf

    upstream imooc {
        server 116.62.103.228:8001 down; #不提供服务
        server 116.62.103.228:8002 backup; #备份结点
        server 116.62.103.228:8003 max_fails=1 fail_timeout=10s;
    }

server {
    listen       80;
    server_name  localhost jeson.t.imooc.io;

    access_log  /var/log/nginx/test_proxy.access.log  main;
    resolver  8.8.8.8;

    location / {
        proxy_pass http://imooc;
        include proxy_params;
    }

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
}

此时只有server3提供服务,刷新页面,也只显示了server3

此时关掉server3,此时刷新页面,服务会很慢,过段时间,就切换到了server2(备份结点)

若是此时开启server3,就又能继续访问server3了(server继续不能访问了)

备份服务

在服务器上再启动一个8030的服务

在这里插入图片描述

将此服务作为一个备份服务,有服务意外停止的时候,这个顶上去!

upstream wwwdemocom{
    server 127.0.0.1:8010 weight=1;
    server 127.0.0.1:8020 weight=2;
    server 127.0.0.1:8030 backup; # 不能加weight等参数
}

重启nginx,先刷新页面查看效果,发现还是配置的8010和8020两个在做负载均衡,现在停止8010和8020,可以看到8030顶上来了:

注意:关闭一个服务不会触发备用服务,只有8010和8020全都意外停止,8030才会顶上来!

如果再把8010重新启动,那么备份服务就不会起作用了

max_fails和fail_timeout

nginx在原来的8010服务器重新启动以后,能很快检测到原来的8010恢复了,并投入使用,是因为nginx和8010之间有类似心跳检测的机制,实时监控8010是否能用。

  • max_fails参数就是设置失败多少次后,认为已经挂了,就剔除
  • fail_timeout参数就是剔除后从新检测这个属性也是设置恢复时检测的时长间隔,比如设置一分钟,那么服务恢复后得隔一分钟才能检测到并投入使用。

可以想象,如果实时去检查的话,会很消耗性能,所以这两个参数非常有用。

下面我们把失败最大重试次数设置成10次,恢复检测时长设置成30秒:

upstream wwwdemocom{
    server 127.0.0.1:8010 weight=1 fail_timeout=30s max_fails=10;
    server 127.0.0.1:8020 weight=2 fail_timeout=30s max_fails=10;
    server 127.0.0.1:8030 backup;
}

重新加载,然后停止8010和8020,访问页面,可以看到加载了一会才会出现8030的结果,如果重试次数设置成100次,加载时间会更明显。我们把8010启动起来,可以看到前面三十秒左右还是8030,后面又开始访问8010:

这两个参数也是很重要的参数,在实际生成环境中会用到。要合理设置重试次数和等待时间

调度算法,轮询等

算法 定义
轮询 按时间顺序逐一分配到不同的后端服务器
加权轮询 (默认)weight值越大,分配到的访问几率越高,缺点是,其中一个连接满了,nginx还是会加连接过去导致连接越来越多,速度越来越慢,不够自动化和智能化
ip_hash 每个请求按访问IP的hash结果分配,这样来自同一个IP的固定访问一个后端服务器,用于保持session 一至性,解决分布式session同步问题,缺点是现在很多小区或者学校都是用的一根光纤,大部分人的ip是一样的,容易导致某个服务连接数量过多,出现负载不均衡的情况,而且机器挂掉,会话随着会丢失
url_hash 按照访问的URL的hash结果来分配请求,是每个URL定向到同一个后端服务器,静态资源缓存,节约存储,加快速度(第三方),和ip_hash的计算方法一样,应用场景不同,通过这种算法可以把一些静态资源平均分布到各个服务中,节省空间
least_conn 最少链接数,那个机器连接数少就分发,优先把请求分给和nginx连接最少的服务,最大化的利用资源
hash关键数值 hash自定义的key
least_time 最小的响应时间,计算节点平均响应时间,然后取响应最快的那个,分配更高权重(第三方),可以充分利用性能好的机器

权重

默认两个系统切换着访问,策略默认是轮训的,也就是无论几个系统都轮着循环访问。如果想让两台机器的访问数量按照1比2分配,那么可以设置权重:

upstream wwwdemocom{
    server 127.0.0.1:8010 weight=1;
    server 127.0.0.1:8020 weight=2;
}

刷新页面可以看到,8010访问一次,紧接着8020访问两次,这种是按照权重分流,改变了原来默认的轮训策略。这种适合机器性能有区别的情况。

ip_hash

若是使用轮询、加权、least_conn的方式,cookie等的会比较麻烦,所以可以使用ip_hash,自同一个IP的固定访问一个后端服务器

注意:除了把权重去掉,还有把backup的服务注释掉,两个不能同时用.

    upstream imooc {
        ip_hash; # 只需要设置一下这个参数
        server 116.62.103.228:8001;
        server 116.62.103.228:8002;
        server 116.62.103.228:8003;
    }

server {
    listen       80;
    server_name  localhost jeson.t.imooc.io;

    access_log  /var/log/nginx/test_proxy.access.log  main;
    resolver  8.8.8.8;

    location / {
        proxy_pass http://imooc;
        include proxy_params;
    }

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
}

此时,同一个ip,定位的就是一个固定的服务器了.

但是,若是客户走的是代理,那么获取的可能就不是客户的真实ip,可能无法做ip对应的轮询了,基于这个,出来了基于url的hash

url_hash

问题:

  • 我们想规定的IP请求固定的内容,让固定的IP按照IP来分配,往往无法取到用户端的IP
  • 缓存:服务器1缓存的一部分资源,服务器2缓存一部分的资源,那么当一个用户来先访问了服务器1以后,他会缓存住他返程的内容,再一次请求的时候,假设他如果跳到了服务器2,那么这样的话他又看到的是另外一部分内容,那么他看到的第1部分内容和第2部分内容是不一致的
Syntax: hash key [consistent];
Default:一
Context:upstream
This directive appeared in version 1.7.2. #发现版本

资源:Nginx从入门到实践projecty1k2wh3-25

静态资源html:code1、code2、code3三个文件夹,里面都有四个页面 index.html url1.html url2.html url3.html

三个服务配置

server {
    listen       8001; # 端口不同
    server_name  localhost;

    access_log  /var/log/nginx/log/server1.access.log  main;

    location / {
        root   /opt/app/code1;
        index  index.html index.htm;
    }

    error_page   500 502 503 504 404  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
}

负载均衡配置

    upstream imooc {
        hash $request_uri; # request_uri是请求的参数
        server 116.62.103.228:8001;
        server 116.62.103.228:8002;
        server 116.62.103.228:8003;
    }

server {
    listen       80;
    server_name  localhost jeson.t.imooc.io;

    access_log  /var/log/nginx/test_proxy.access.log  main;
    resolver  8.8.8.8;

    location / {
        proxy_pass http://imooc;
        include proxy_params;
    }

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
}

注释掉hash $request_uri;:此时访问 http://jeson.t.imooc.io/url1.html,是在三个服务之间轮询

开启hash $request_uri;:此时访问 http://jeson.t.imooc.io/url1.html,是在固定的服务器,换为url2.html,就会换一个固定的服务器了

url_hash是根据域名来分配的





原文地址:https://www.cnblogs.com/ziyue7575/p/22a55d8573fad9b5593de747916efc10.html