服务端相关 / 15 Nginx 负载均衡(上)

Nginx负载均衡(上)

1. 什么是负载均衡

负载均衡,其英文简称Load Balancing,是一种计算机技术。用来在多个计算机(计算机集群)、网络连接、CPU、磁盘驱动器或其他资源中分配负载,以达到最优化资源使用、最大化吞吐率、最小化响应时间、同时避免过载的目的。宏观上的意思是将负载(工作任务,访问请求)进行平衡、分摊到多个操作单元(服务器,组件)上进行执行以解决高性能,单点故障(高可用),扩展性(水平伸缩)等高流量下常见的问题。

2. 负载均衡分类

由于载均衡技术是要对网络传输中的报文控制,因此会涉及到网络七层模型,因此负载均衡分类可以按照网络层次进行分类,比如二层、三层、四层、七层负载均衡。其中最常见的是四层和七层负载均衡。此外,还有其他方面进行分类的,有软件负载均衡、硬件负载均衡等。

2.1 二层负载均衡

负载均衡服务器对外依然提供一个VIP(虚IP),集群中不同的机器采用相同IP地址,但是机器的MAC地址不一样。当负载均衡服务器接受到请求之后,通过改写报文的目标MAC地址的方式将请求转发到目标机器实现负载均衡。

2.2 三层负载均衡

和二层负载均衡类似,负载均衡服务器对外依然提供一个VIP(虚IP),但是集群中不同的机器采用不同的IP地址。当负载均衡服务器接受到请求之后,根据不同的负载均衡算法,通过IP将请求转发至不同的真实服务器。

2.3 四层负载均衡

四层负载均衡工作在OSI模型的传输层,由于在传输层,只有TCP/UDP协议,这两种协议中除了包含源IP、目标IP以外,还包含源端口号及目的端口号。四层负载均衡服务器在接受到客户端请求后,以后通过修改数据包的地址信息(IP+端口号)将流量转发到应用服务器。

2.4 七层负载均衡

七层负载均衡工作在 OSI 模型的应用层,应用层协议较多,常用 http、dns 等。七层负载就可以基于这些协议来负载。这些应用层协议中会包含很多有意义的内容。比如同一个 Web 服务器的负载均衡,除了根据 IP 加端口进行负载外,还可根据七层的 URL、浏览器类别、语言来决定是否要进行负载均衡。

业界已经有很多开源的负载均衡工具,大部分是工作在第四层和第七层的。代表的开源工具有
Nginx/LVS/Haproxy。值得一提的是,LVS 是国内前淘宝网高级研究员章文嵩博士的作品。LVS 主要用来做四层负载均衡,Nginx 和 Haproxy 主要是做七层的负载均衡,但它们都支持四层的负载均衡,例如在 Nginx 中的 stream 模块除了支持四层的反向代理功能,也支持四层负载均衡功能。

3. 负载均衡算法

负载均衡算法可以分成两大类,一类是静态的负载均衡算法,常见的有轮询、权重等;另一大类动态的负载均衡算法,常见的有最少的连接、最快响应、服务类型、服务质量等等,还有很多策略,不同的软件会实现不同的负载均衡算法。

4. Nginx中的负载均衡配置

Nginx 的 stream 模块和 http 模块分别支持四层和七层模块的负载均衡。其用法和支持的负载均衡策略大致相同。首先使用 upstream 指令块 和 server 指令指定上游的服务,upstream 指令的用法如下:

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

官网示例如下:

upstream backend {
    server backend1.example.com weight=5;
    server 127.0.0.1:8080 max_fails=3 fail_timeout=30s;
    server unix:/tmp/backend3;
    server backup1.example.com  backup;
}

这里定义了4台上游服务器,分别用域名, ip+port、socket 形式指定地址,后面跟上若干配置参数。默认情况下,upstream 指令块中采用的是加权 Round-Robin 负载均衡算法。该算法通过加权轮询的方式访问 upstream 中 server 指令指定的上游服务。此时,在server 指令中我们可以添加一些关于服务的静态配置,比如指定服务的权重(weight)、server 的最大并发连接数(max_conns)、max_fails 和 fail_timeout 等。

除了默认的 Round-Robin 算法外,Nginx 中常用的负载均衡策略还有基于客户端 ip 地址的 Hash 算法。该算法以客户端的 ip 地址作为 hash 算法的关键字,映射到特定的上游服务器中,当然也可以根据客户段的其他 key 来进行 hash 算法。涉及的配置指令为 ip_hash 和 hash,用法如下:

Syntax:	ip_hash;
Default:Context: upstream

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

最后 Nginx 中一种常用的动态负载均衡算法是最少连接数算法。该算法会从所有的上游服务器中找到并发连接数最少的一个,然后将请求转发给它,如果出现多个最少连接数的服务器,则会在这些最少连接数的服务器中继续应用 Round-Robin 算法。配置该策略的指令为 least_conn,其指令格式如下:

Syntax:	least_conn;
Default:Context: upstream

当然, Nginx 中的负载均衡策略还有很多,就不在此一一介绍了。可以仔细研读官方文档进行进一步学习

5. 小结

本小节只是介绍了负载均衡的相关知识,以及对应 Nginx 中的配置指令,后面一节会实战 Nginx 的负载均衡功能,同时测试多种负载均衡算法。