什么是负载均衡

通过反向代理服务器【Nginx等】进行路由转发到不同的上游服务器,解决服务的高可用,即即使一台服务器宕机也还有其他服务器的支撑,保证不会因为一台服务器的宕机而使整体业务出现异常

java负载均衡线程_服务器

nginx简单负载均衡配置

http {
        upstream backend {
            server backend1.example.com;
            server backend2.example.com;
            server 192.0.0.1 backup;
        }
        
        server {
            location / {
                proxy_pass http://backend;
            }
        }
    }

负载均衡路由算法

轮询【Round Robin】:请求在服务器上平均分配,与服务器权重有关,默认权重为1,即平均分配

upstream backend {
   server backend1.example.com;
   server backend2.example.com;
}

最小连接【least_conn】:将请求发送到活动连接最少的服务器

upstream backend {
    least_conn;
    server backend1.example.com;
    server backend2.example.com;
}

IP散列【ip_hash】:在这种情况下,使用IPv 4地址的前三个八进制或整个IPv 6地址来计算哈希值。该方法确保来自同一地址的请求到达同一台服务器,除非不可用

upstream backend {
    ip_hash;
    server backend1.example.com;
    server backend2.example.com;
}

如果其中一台服务器需要暂时从负载平衡旋转中移除,则可以将其标记为down参数,以保留客户端IP地址的当前散列。将由此服务器处理的请求自动发送到组中的下一个服务器:

upstream backend {
    server backend1.example.com;
    server backend2.example.com;
    server backend3.example.com down;
}

一致性Hash-发送请求的服务器由用户定义的密钥确定,该密钥可以是文本字符串、变量或组合。例如,密钥可以是配对的源IP地址和端口,也可以是URI,如本例所示:

upstream backend {
	#hash指定为一致性hash
    hash $request_uri consistent;
    server backend1.example.com;
    server backend2.example.com;
}

任选consistent参数的hash指令启用一致-哈希负载平衡。根据用户定义的散列密钥值,请求均匀分布在所有上游服务器上。如果上游服务器被添加到上游组或从上游组中移除,则只有几个密钥被重新映射,在负载平衡缓存服务器或其他累积状态的应用程序中,这将最大限度地减少缓存丢失。

最少时间(仅适用于Nginx Plus)-对于每个请求,Nginx Plus选择的服务器具有最低的平均延迟和最低的活动连接数,其中最低的平均延迟是根据以下哪一个来计算的参数到least_time指令包括:

header-从服务器接收第一个字节的时间
last_byte-从服务器接收全部响应的时间
last_byte inflight-在考虑到不完整请求的情况下,从服务器接收全部响应的时间

upstream backend {
    least_time header;
    server backend1.example.com;
    server backend2.example.com;
}

随机-每个请求将传递给随机选择的服务器。如果two参数指定,首先,Nginx在考虑服务器权重的情况下随机选择两个服务器,然后使用指定的方法选择其中一个服务器:

least_conn-有效连接最少
least_time=header(Nginx Plus)-从服务器接收响应头的最短平均时间($upstream_header_time)
least_time=last_byte(Nginx Plus)-从服务器接收完整响应的最短平均时间($upstream_response_time)

upstream backend {
    random two least_time=last_byte;
    server backend1.example.com;
    server backend2.example.com;
    server backend3.example.com;
    server backend4.example.com;
}

这个随机在多个负载平衡器将请求传递到同一组后端的分布式环境中,应该使用负载平衡方法。对于负载均衡器具有所有请求的完整视图的环境,请使用其他负载平衡方法,例如循环、最少的连接和最少的时间。

注:在配置除RoundRobin以外的任何方法时,放置相应的指令(hash, ip_hash, least_conn, least_time,或random)的清单上server中的指令upstream {}快

服务器权重

默认情况下,Nginx使用RoundRobin【轮询】方法根据服务器的权重在组中的服务器之间分发请求。这个weight参数的server指令设置服务器的权重;缺省值【默认】为1:

upstream backend {
    server backend1.example.com weight=5;
    server backend2.example.com;
    server 192.0.0.1 backup;
}

在这个例子中,backend1.example.com权重为5;其他两个服务器具有默认权重(1),但是有IP地址的192.0.0.1标记为backup【备份】服务器,除非其他两台服务器不可用,否则不会接收请求。有了这种重量的配置,每六个请求,5个访问backend1.example.com1个访问backend2.example.com.

服务器慢速启动

服务器慢启动功能防止最近恢复的服务器被连接羁绊,这可能会导致服务器再次被标记为失败。
在nginx 中, 缓慢启动允许上游服务器逐渐从0到它被恢复或可用之后【防止启动失败】,可以通过slow_start参数指定:

upstream backend {
    server backend1.example.com slow_start=30s;
    server backend2.example.com;
    server 192.0.0.1 backup;
}

时间值(这里,30(秒)设置Nginx Plus将到服务器的连接数量增加到全部值的时间。

注意,如果组中只有一台服务器,则max_fails, fail_timeout,和slow_start参数到server指令被忽略,并且服务器从未被认为不可用。

启用会话持久性

会话持久性意味着Nginx标识用户会话并将给定会话中的所有请求路由到相同的上游服务器。
Nginx支持三种会话持久性方法。方法设置为sticky指令。(对于使用Nginx开源的会话持久性,请使用hash或ip_hash如所述指令上边.)

粘性cookie【sticky cookie】-Nginx 将会话cookie添加到上游组的第一个响应中,并标识发送响应的服务器。客户端的下一个请求包含cookie值,Nginx 将请求路由到响应第一个请求的上游服务器:

upstream backend {
    server backend1.example.com;
    server backend2.example.com;
    sticky cookie srv_id expires=1h domain=.example.com path=/;
}

在示例中,srv_id参数设置cookie的名称。任选expires参数设置浏览器保留cookie的时间(在这里,1小时)。任选domain参数定义为其设置cookie的域,以及可选的path参数定义设置cookie的路径。这是最简单的会话持久性方法。

粘性路由【Sticky route 】-Nginx在客户收到第一次请求时为其指定一条“路线”。所有后续请求都将与route参数的server指令来标识请求被代理到的服务器。路由信息来自cookie或请求URI。

upstream backend {
    server backend1.example.com route=a;
    server backend2.example.com route=b;
    sticky route $route_cookie $route_uri;
}

cookie学习方法-Nginx Plus首先通过检查请求和响应来查找会话标识符。然后“学习”哪个上游服务器对应于哪个会话标识符。通常,这些标识符是在HTTPcookie中传递的。如果请求包含已“学习”的会话标识符,则Nginx Plus将请求转发给相应的服务器:

upstream backend {
   server backend1.example.com;
   server backend2.example.com;
   sticky learn
       create=$upstream_cookie_examplecookie
       lookup=$cookie_examplecookie
       zone=client_sessions:1m
       timeout=1h;
}

在本例中,一个上游服务器通过设置cookie创建会话。EXAMPLECOOKIE在回应中。

强制性create参数指定一个变量,该变量指示如何创建新会话。在本例中,新会话是从cookie创建的。EXAMPLECOOKIE由上游服务器发送。

强制性lookup参数指定如何搜索现有会话。在我们的示例中,在cookie中搜索现有会话。EXAMPLECOOKIE是客户送的。

强制性zone参数指定一个共享内存区域,其中保存有关粘性会话的所有信息。在我们的示例中,区域名为客户会话而且是1兆字节大小。

这是一个比前两个更复杂的会话持久性方法,因为它不需要在客户端保留任何cookie:所有信息都保存在共享内存区域的服务器端。

如果集群中有几个使用“粘滞学习”方法的Nginx实例,则可以在以下条件下同步它们的共享内存区域的内容:

这些区域具有相同的名称。
这个zone_sync每个实例都配置了功能。
这个sync参数指定

sticky learn
       create=$upstream_cookie_examplecookie
       lookup=$cookie_examplecookie
       zone=client_sessions:1m
       timeout=1h
       sync;
}

限制连接数

使用Nginx Plus,可以通过使用max_conns参数。

如果max_conns达到限制后,请求将放置在队列中以供进一步处理,条件是queue还包括用于设置队列中可同时出现的最大请求数的指令:

upstream backend {
    server backend1.example.com max_conns=3;
    server backend2.example.com;
    queue 100 timeout=70; #设置队列最大请求数与超时时间
}

与多个工作进程共享数据

如果upstream块不包括zone指令时,每个工作进程保留自己的服务器组配置副本,并维护自己的一组相关计数器。计数器包括组中每个服务器的当前连接数和向服务器传递请求的失败尝试次数。因此,无法动态修改服务器组配置。

当zone指令包含在upstream块中,上游组的配置保存在所有工作进程之间共享的内存区域中。此方案是动态可配置的,因为工作进程访问组配置的相同副本并使用相同的相关计数器。

这个zone指令对积极健康检查和动态重构上游集团。然而,上游群体的其他特性也可以受益于这一指令的使用。

例如,如果未共享组的配置,则每个辅助进程都会维护自己的计数器,以防止向服务器传递请求的尝试失败(由max_fails参数)在这种情况下,每个请求只能访问一个辅助进程。当选择用于处理请求的辅助进程未能将请求传输到服务器时,其他辅助进程对此一无所知。虽然某些工作进程可以认为服务器不可用,但其他工作进程仍可能向此服务器发送请求。如果要确定地认为服务器不可用,则在由fail_timeout参数必须相等max_fails乘以辅助进程的数量。另一方面,zone指令可以保证预期的行为。

类似地,最小连接如果没有zone指令,至少在低负载下。此方法将请求传递给具有最小活动连接数的服务器。如果未共享组的配置,则每个辅助进程使用自己的计数器来表示连接的数量,并可能向另一个工作进程刚刚发送请求的同一台服务器发送请求。但是,可以增加请求数量以减少这种影响。在负载较高的情况下,工作进程之间平均分配请求,最小连接方法按预期工作。

设置区域大小
不可能推荐理想的内存区域大小,因为使用模式差异很大。所需的内存量取决于哪些特性(如会话持久性, 健康检查,或dns重解析)以及如何识别上游服务器。

例如,使用sticky_route会话持久化方法和启用的单一健康检查,256 KB区域可以容纳有关指定数量的上游服务器的信息:

128台服务器(每个服务器定义为IP地址:端口对)
88台服务器(每个服务器定义为主机名:端口对,其中主机名解析为一个IP地址)
12个服务器(每个服务器定义为主机名:端口对,其中主机名解析为多个IP地址)

使用DNS配置HTTP负载平衡

可以使用DNS在运行时修改服务器组的配置。

中使用域名标识的上游组中的服务器。server指令,Nginx Plus可以监视相应DNS记录中IP地址列表的更改,并自动将更改应用于上游组的负载平衡,而无需重新启动。这可以通过包括resolver指令中的http块以及resolve参数的server指令:

http {
    resolver 10.0.0.1 valid=300s ipv6=off;
    resolver_timeout 10s;
    server {
        location / {
            proxy_pass http://backend;
        }
    }
    upstream backend {
        zone backend 32k;###配置保存在所有工作进程之间共享的内存区域中
        least_conn;
        # ...
        server backend1.example.com resolve;###通过上面的DNS解析服务器定期解析域名为ip4地址
        server backend2.example.com resolve;
    }
}

在示例中,resolve参数的server指令告诉Nginx Plus定期重新解析backend1.example.com和backend2.example.com域名进入IP地址。

这个resolver指令定义Nginx Plus向其发送请求的DNS服务器的IP地址(此处为10.0.0.1)。默认情况下,nginx Plus重新解析dns记录的频率由记录中的time-to-live(Ttl)指定,也可以使用valid参数;在示例中为300秒,即5分钟。

任选ipv6=off参数表示只使用IPv 4地址进行负载平衡,但默认情况下支持IPv 4和IPv 6地址的解析。

如果一个域名解析为多个IP地址,则将这些地址保存到上游配置和负载平衡。在我们的示例中,服务器根据最小连接负载平衡法如果服务器的IP地址列表发生了更改,Nginx Plus将立即开始跨新地址集进行负载平衡。

MicrosoftExchange服务器的负载平衡

完整NTLM【NTLM是NT LAN Manager的缩写,这也说明了协议的来源。NTLM 是 Windows NT 早期版本的标准安全协议】示例

http {
    # ...
    upstream exchange {
        zone exchange 64k;
        ntlm;
        server exchange1.example.com;
        server exchange2.example.com;
    }
    
    server {
        listen              443 ssl;
        ssl_certificate     /etc/nginx/ssl/company.com.crt;
        ssl_certificate_key /etc/nginx/ssl/company.com.key;
        ssl_protocols       TLSv1 TLSv1.1 TLSv1.2;
       
        location / {
            proxy_pass         https://exchange;
            proxy_http_version 1.1;
            proxy_set_header   Connection "";
        }
    }
}