Nginx之旅-Nginx作为负载均衡服务

所谓的负载均衡就是将前端的请求均分或者按照规则分配给后端不同的服务。并且能够减少宕机导致的请求无效。

负载均衡的分类:

按照地域广度:GSLB,SLB

GSLB, Global Server Load Balance, 即全局负载均衡。

image-20181211172228047

张三通过调度节点获取到最近的应用服务 成功访问 而不是直接访问应用服务中心节点

由于现实中存在各种不稳定因素,比如某个服务器集群所在的数据中心断电,洪水或者地震造成数据中心瘫痪等等。在一个数据中心内,无论采用怎样的技术,总可能存在一些不可抗因素,导致其瘫痪。所以通常会把服务器分散部署到多个数据中心,以最大程度减小灾害对服务质量产生影响的概率和程度。

另外,CDN系统总是希望用距离用户最近的设备为其提供服务,这也需要在不同地域部署多个节点。

GSLB系统就是针对这个问题的。它负责多个CDN节点之间相互协作,将各节点和设备的负载保持在一个有利于提供优质服务的水平。GSLB的负载均衡结果可能直接将用户分配到RS,也可能将用户交付到下一层次的负载均衡系统。

经过多年发展,已有多种调度机制可实现CDN的全局负载均衡。其中最常用的是基于DNS的GSLB。

参考阅读文章 全局负载均衡GSLB

SLB(Server Load Balance)负载均衡。

image-20181211173252614

图片中的VIP是指虚拟IP的意思:从图中可以看出,负载均衡设备可以在用户请求到达服务器之前将其截获,然后将其分发到合适的后端服务器。

也就是说,客户端发出的请求,首先会到负载均衡设备的IP地址上。因为该IP地址并不负责处理实际的业务,所以通常将该地址称为【虚拟IP】(Virtual IP, VIP)。

后端真正的业务服务器被称为【真实服务器】(Real Server, RS),其IP地址被称为【真实IP】(Real IP, RIP),负责处理业务。

举个例子,VIP 就像是前台招待,会告诉你办什么事该去哪个房间。而RIP是内部实际办业务的房间号。

利用负载均衡,很大程度上可以避免单个服务器过载或者闲置,前者会引起服务能力下降,后者则没有充分利用资源。因此,为了达到更好的系统处理能力,需要进行以下两个步骤:

  1. 在集群前端部署负载均衡设备
  2. 根据预先配置的均衡策略,在集群中智能分发用户请求

按照网络模型层:四层负载均衡,七层负载均衡

image-20181211173657613

四层负载均衡是在传输层上进行TCP, IP的包转发(不需要进行复杂的逻辑)来实现负载均衡。从底层控制,效率很高。

image-20181211181114882

七层负载均衡是在应用层上,能够对应用层数据做一些操作。Nginx就是一个七层负载均衡的SLB。

配置场景

Nginx作为负载均衡最重要的两点是proxy_passupstream server

image-20181211181517439

通过Nginx作为代理转发到真正运行服务的服务器上(由upstream指定的服务组)。

推荐阅读文章:使用nginx作为HTTP负载均衡

upstream的配置语法:

1
2
3
Syntax: upstream name {...}
Default: --
Context: http

需要配置在 http 层 server 外

下面的场景是两台云主机,在一台云主机上开启三个服务,不同的服务对于不同的端口。一台云主机做Nginx负载均衡。

1
2
3
4
5
6
7
8
9
10
11
12
13
upstream imooc {
server 116.62.103.228:8001;
server 116.62.103.228:8002;
server 116.62.103.228:8003;
}

server {
listen 80;
location / {
proxy_pass http://imooc; // 转发
include proxy_params;
}
}

上面我们给upstream起个名字为imooc,将所有的请求都转发到这个imooc

默认情况下是按照轮询来做负载均衡的。负载均衡能感知服务是否正常,不正常则不再轮询。

upstream举例:

1
2
3
4
5
6
7
8
upstream backend {
server backend1.example.com weight=5; # 域名
server backend2.example.com:8080; # 域名加端口
server unix:/tmp/backend3; # unix

server backup1.example.com:8080 backup;
server backup2.example.com:8080 backup;
}

上面是一个upstream的配置示例,我们看下有哪些具体参数。

参数名字 参数含义
down 当前的server暂时不参与
backup 预留的备份服务器
max_fails 允许请求失败的次数
fail_timeout 经过max_fails失败后,服务暂停的时间
max_conns 限制最大的接收的连接数

backup是指其他服务器不能正常提供服务的时候,会承担起提供服务的角色,当其他服务能够再次提供正常服务的时候,会再次变为预备状态

轮询策略与加权轮询

Nginx的默认轮询规则是基于请求来实现的,我们看看全部有哪些调度算法。

算法名 算法详情
轮询 按时间顺序逐一分配到不同的后端服务器
加权轮询 weight值越大,分配到的访问几率越高
ip_hash 每个请求按访问IP的hash结果分配,这样来自同一个IP的固定访问一个后端服务器
Url_hash 按照访问的URL的hash结果来分配请求,是每个URL定向到同一个后端服务器
least_conn 最少链接数,哪个机器链接数少
hash关键数值 hash自定义到的key

轮询和加权轮询都是基于请求来分配的。

配置ip_hash

1
2
3
4
5
6
upstream imooc {
ip_hash; # 直接添加这个配置即可 基于 remote_addrr
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;
}

如果走代理就会出现问题。

配置url_hash

如何自定义hash关键数值

1
2
3
4
Syntax: hash key [consistent];
Default: --
Context: upstream
在版本 1.7.2 之后才出现的。
1
2
3
4
5
6
upstream imooc {
hash $request_uri;
server 116.62.103.228:8001;
server 116.62.103.228:8002;
server 116.62.103.228:8003;
}

配置了请求urlurl_hash之后固定的url访问固定的服务器。

Nginx的resolver什么时候使用?

1
2
3
Syntax:	resolver address ... [valid=time] [ipv6=on|off];
Default: —
Context: http, server, location

Configures name servers used to resolve names of upstream servers into addresses, for example:

127.0.0.1 [::1]:5353;
1
2
> resolver 127.0.0.1 [::1]:5353;
>

反向代理的场景,upstream后端用域名时,配置resolver以便于nginx能够解析该域名。

知识就是财富
如果您觉得文章对您有帮助, 欢迎请我喝杯水!