Nginx负载均衡服务
标签:Nginx

Nginx负载均衡服务

GSLB:

全局的负载均衡由中心节点和边缘的节点组成。

SLB:

调度节点和服务节点在一个逻辑单元里面。对部分服务的响应性和实时性很好。Nginx是一个典型的SLB。

四层负载均衡:

在传输层(TCP/IP)控制,在客户端请求进行TCP/IP包转发,好处是速度快,在底层进行处理,不需要复杂的逻辑处理。

也就是主要通过报文中的目标地址和端口,再加上负载均衡设备设置的服务器选择方式,决定最终选择的内部服务器。
以常见的TCP为例,负载均衡设备在接收到第一个来自客户端的SYN 请求时,即通过上述方式选择一个最佳的服务器,并对报文中目标IP地址进行修改(改为后端服务器IP),直接转发给该服务器。TCP的连接建立,即三次握手是客户端和服务器直接建立的,负载均衡设备只是起到一个类似路由器的转发动作。在某些部署情况下,为保证服务器回包可以正确返回给负载均衡设备,在转发报文的同时可能还会对报文原来的源地址进行修改。

七层负载均衡:

在应用层,可以实现度http头信息的改写,安全控制,更加复杂,实现功能更多,Nginx是典型的七层负载均衡。

也称为“内容交换”,也就是主要通过报文中的真正有意义的应用层内容,再加上负载均衡设备设置的服务器选择方式,决定最终选择的内部服务器。

以常见的TCP为例,负载均衡设备如果要根据真正的应用层内容再选择服务器,只能先代理最终的服务器和客户端建立连接(三次握手)后,才可能接受到客户端发送的真正应用层内容的报文,然后再根据该报文中的特定字段,再加上负载均衡设备设置的服务器选择方式,决定最终选择的内部服务器。负载均衡设备在这种情况下,更类似于一个代理服务器。负载均衡和前端的客户端以及后端的服务器会分别建立TCP连接。所以从这个技术原理上来看,七层负载均衡明显的对负载均衡设备的要求更高,处理七层的能力也必然会低于四层模式的部署方式。

应用场景
七层应用负载的好处,是使得整个网络更智能化。例如访问一个网站的用户流量,可以通过七层的方式,将对图片类的请求转发到特定的图片服务器并可以使用缓存技术;将对文字类的请求可以转发到特定的文字服务器并可以使用压缩技术。当然这只是七层应用的一个小案例,从技术原理上,这种方式可以对客户端的请求和服务器的响应进行任意意义上的修改,极大的提升了应用系统在网络层的灵活性。很多在后台,例如Nginx或者Apache上部署的功能可以前移到负载均衡设备上,例如客户请求中的Header重写,服务器响应中的关键字过滤或者内容插入等功能。
另外一个常常被提到功能就是安全性。网络中最常见的SYN Flood攻击,即黑客控制众多源客户端,使用虚假IP地址对同一目标发送SYN攻击,通常这种攻击会大量发送SYN报文,耗尽服务器上的相关资源,以达到Denial of Service(DoS)的目的。从技术原理上也可以看出,四层模式下这些SYN攻击都会被转发到后端的服务器上;而七层模式下这些SYN攻击自然在负载均衡设备上就截止,不会影响后台服务器的正常运营。另外负载均衡设备可以在七层层面设定多种策略,过滤特定报文,例如SQL Injection等应用层面的特定攻击手段,从应用层面进一步提高系统整体安全。
现在的7层负载均衡,主要还是着重于应用HTTP协议,所以其应用范围主要是众多的网站或者内部信息平台等基于B/S开发的系统。 4层负载均衡则对应其他TCP应用,例如基于C/S开发的ERP等系统。

1. 原理

客户请求Nginx,proxy_pass转发到一组虚拟的服务池(upstream server),里面可以定义它的服务器单元,他们可以提供相同服务,请求可以分发到不同的服务上。

2. 配置

语法:

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

2.1 测试

step 1:在我的阿里云服务器上新建三个页面,并且放在/opt/app目录下

[root@iZ2zehqhujir8jxqadc5a3Z app]# tree
.
├── code1
│   └── index.html
├── code2
│   └── index.html
└── code3
    └── index.html

Step 2:新建三个server.conf放在/etc/nginx/conf.d/目录下,并且执行不同的index.html

Server1.conf

server {
    listen       8001;
    server_name  localhost;

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

    location / {
        root   /opt/app/code1;
        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;
    }

}

Server2.conf:

server {
    listen       8002;
    server_name  localhost;

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

    location / {
        root   /opt/app/code2;
        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;
    }

}

Server3.conf:

server {
    listen       8003;
    server_name  localhost;

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

    location / {
        root   /opt/app/code3;
        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;
    }

}

上面分别使用了8001,8002,8003三个端口

Step 3:在iptables里面开启端口

iptables -I INPUT -p tcp --dport 8001:8003 -j ACCEPT 
systemctl restart iptables.service

Step 4:在阿里云官网开启端口

Step 5:在虚拟机里面配置相应的upstream_test.conf

    upstream myalicentos{
        server 47.94.254.242:8001;
        server 47.94.254.242:8002;
        server 47.94.254.242:8003;
    }

server {
    listen       80;
    server_name  localhost 192.168.91.136;

    #charset koi8-r;
    access_log  /var/log/nginx/test_proxy.access.log  main;
    resolver  8.8.8.8;
    
    location / {
        proxy_pass http://myalicentos;
        include proxy_params;
    }

    #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   /usr/share/nginx/html;
    }

}

上面的upstream的名字时自定义的但要和location中的要保持一致,把server全部转向到我的阿里云服务器上。

Step 6:结果

可见上面是对三个server进行轮询

现将服务器的8002端口关闭是它不能访问:

iptables -I INPUT -p tcp --dport 8002 -j DROP

则:

这个时候,负载均衡检查到8002无法访问,只有server1和server3显示,server2下线了。

2.2 server参数

参数 解释
down 当前的sever暂时不参与负载均衡
backup 预留的备份服务器,其他都不能提供服务时,
就需要提供服务了
max_fails 允许请求失败的次数
代理服务请向后端重试请求失败的最大次数
fail_timeout 经过max_fails失败后,服务暂停的时间
max_conns 限制每个server最大的接收的连接数

测试:

修改上面的upstream为:

    upstream myalicentos{
        server 47.94.254.242:8001 down;
        server 47.94.254.242:8002 backup;
        server 47.94.254.242:8003 max_fails=1 fail_timeout=10s;
    }

表示只有8003可以启用,当我们把8003端口关闭掉后,8001就启用了。

2.4 调度算法

算法 解释
轮询 按时间顺序逐一分配到不同的后端服务器
加权轮询 weight值越大,分配到的访问几率越高
ip_hash 每个请求按访问的IP的hash结果分配,
这样来自同一个IP的固定访问一个后端服务器,
这样登录信息就保留了下来
least_conn 最少连接数,那个机器连接数少就分发
url_hash 按照访问的URL的hash结果来分配请求,
是每个URL重定向到同一个后端服务器
hash关键数值 hash自定义的key

ip_hash:

    upstream myalicentos{
    	ip_hash;
        server 47.94.254.242:8001 ;
        server 47.94.254.242:8002 ;
        server 47.94.254.242:8003 ;
    }

但是用户走了代理就不能根据ip哈希到统一服务器上。

url_hash:

Syntax: hash key [consistent];
Default: ——
Context: upstream

这个策略是从1.7.2以后才有的

    upstream myalicentos{
    	hash $request_uri;
        server 47.94.254.242:8001 ;
        server 47.94.254.242:8002 ;
        server 47.94.254.242:8003 ;
    }

根据请求的uri再做hash。

  • 9 min read

CONTRIBUTORS


  • 9 min read