文章目录

  • 一、概述
  • 二、将Http流量代理到一组服务
  • 三、选择一种负载均衡方式
  • 四、服务权重
  • 五、被动的健康检查


一、概述

将流量负载均衡到多个应用实例是一个优化资源利用率的常规技术,可以最大化吞吐量,减少延迟并且提高容错性。

二、将Http流量代理到一组服务

为了使用nginx将http流量负载均衡到一组服务,你首先需要通过 upstream 指令定义一组服务,该指令应放在http模块内。upstream内的单个服务通过server指令进行指定,指定的值可以是IP也可以是域名,例如以下配置定义了一个名为backend的一组服务,由三个服务组成:

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

一组服务定义好之后,便可以通过反向代理配置将一个请求代理到该组服务,如下所示:

server {
    location / {
        proxy_pass http://backend;
    }
}

三、选择一种负载均衡方式

nginx支持4种负载均衡方式:

1、循环分发
请求会根据每个服务的权重被均匀的分发到各个服务,权重越大,分发的时候就会被优先考虑,该方式也是默认方式,因此不需要在配置中明确指定使用此种方式。

2、最少连接
每次请求会结合权重分发给连接最少的服务,需要在upstream中使用least_conn进行指定使用此种方式:

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

3、IP哈希
此种方式下,请求分发给哪一个服务取决于请求客户端的IP地址,IP地址会被用来计算出一个hash值,根据hash值再决定分发给哪一个服务,因此该方式的特点是同一个客户端IP的请求会被分发到同一个服务,该方式需要在upstream中使用ip_hash进行指定:

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

如果服务组中的某一个服务需要临时下线,可以在最后将其标记一个down,请求就会跳过该服务而分发给下一个:

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

4、通用哈希
请求会分发给哪一个服务由用户定义的键确定,该键可以是文本字符串、变量或它们的组合。例如,键可以是成对的源 IP 地址和端口,或 URI,如本例所示:

upstream backend {
    hash $request_uri consistent;
    server backend1.example.com;
    server backend2.example.com;
}

上例中,指定将请求URI作为键,也就是说具体分发给哪一个服务,会由请求的URI经过hash后得到的值决定。hash 指令的可选参数consistent用于指定是否 启用ketama 一致性哈希负载平衡。如果启用,请求根据用户定义的散列键值均匀分发给所有服务。

四、服务权重

默认情况下,nginx在循环分发时,如果没有给服务指定权重,它们的权重都默认为1,要修改的话可以使用weight进行配置:

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

上例中,backend1.example.com的权重被配置为5,backend2.example.com为默认权重1,而192.0.0.1被标记为backup(不接受请求),意味着6次请求中,5次会分发给backend1.example.com,1次分发给backend2.example.com

五、被动的健康检查

对于被动的健康检查,Nginx通过监控每一次的请求转发,并且试图恢复失败的连接,如果转发仍然不能不恢复,Nginx就会将该服务标记为不可用,并且临时停止将新的请求转发给该服务,直到该服务被重新标记为active。对于一个upstream中的服务,要标记为不可用可以在服务定义时通过max_fails和fail_timeout参数进行配置:

  • fail_timeout:设置发生多次失败尝试才能将服务器标记为不可用的时间,默认为10秒
  • max_fails:设置在 fail_timeout 期间必须发生的失败尝试次数才能将服务器标记为不可用,默认为1次

例如下面的配置中,意为如果在30秒内尝试3次连接仍然失败,则将服务标记为30秒内不可用

upstream backend {
    server backend1.example.com;
    server backend2.example.com max_fails=3 fail_timeout=30s;
}

需要注意的是,如果upstream组中只有一个服务,则会忽略 fail_timeout 和 max_fails 参数,并且永远不会将服务标记为不可用