> For the complete documentation index, see [llms.txt](https://yangsx95.gitbook.io/notes/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://yangsx95.gitbook.io/notes/distributed/web-fu-wu-qi/nginx/fu-zai-jun-heng.md).

# 负载均衡

软负载均衡用来替代F5负载均衡的一种方式，现有的软负载均衡策略，除了nginx之外，Lvs、Apache、HAproxy都可以实现： ![1555162942998](/files/8Iie9kBBDgM6v2X1QcPM)、

## GSLB 与 SLB

负载均衡根据影响范围可以分为两类：

* GSLB：全局负载均衡，范围较大，与地域有关，如下图

  ![1556098097138](/files/tfd2zCVtcYZvU4Tvy9EM)
* SLB：Nginx是一个SLB，通常范围较小，有可能是一个机房，如下图

  ![1556098121571](/files/iLWPiDaJ85ba4Dk960ff)

## 四层与七层负载均衡

按照使用的网络层划分，可以分为：

* 四层负载均衡
* 七层负载均衡 （Nginx是典型的七层负载均衡）

这里的层代表的是OSI七层协议，其中四层代表网络层(IP)，七层代表应用程(HTTP,FTP)。

## nginx实现负载均衡的原理

nginx负载均衡的实现，主要使用代理模块的 `proxy_pass`，将请求代理通过特定的算法转发到一组虚拟服务池(upstream server)上，如下图：

![1556156371946](/files/TxM5eVKqR2vCtW85iqwB)

## 示例配置

```nginx
Syntax: upstream name {}
Default: 
Context: http
```

```nginx
# 此配置位于http块中, 需要再http块中引入
# blog 服务具有三台服务器集群
upstream blog {
    server 192.168.0.159:8001;
    server 192.168.0.159:8002;
    server 192.168.0.159:8003;
}

server {
    listen       80;
    server_name  localhost blog.com;

    #charset koi8-r;
    access_log  /var/log/nginx/test_proxy.access.log  main;
    
    location / {
        # 符合匹配规则的都会被转发到upstream blog中
        proxy_pass http://imooc;
        # 当某台服务器出现error、timout、500状态等情况时，就跳过此台服务器
        proxy_next_upstream error timout invalid_header http_500 http_502 http_503 http_504;
        include proxy_params;
    }

    #error_page  404              /404.html;
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
}
```

> 默认的负载均衡策略为轮询

## 后端服务器在负载均衡调度的配置

| 状态            | 说明                           |
| ------------- | ---------------------------- |
| weight        | 设置权重，值越大，权重越大，分配到此的概率就越大     |
| down          | 当前server不参与负载均衡              |
| backup        | 预留的备份服务器，热备，当其他服务挂了，此服务才会被使用 |
| max\_fails    | 允许请求失败的次数                    |
| fail\_timeout | 经过max\_fails失败后，服务器的暂停时间     |
| max\_conns    | 限制最大的接收连接数                   |

```nginx
upstream backend {
    server backend1.test.com weight=5 max_fail=1 fail_timeout=10s;  
    server backend1.test.com:8080 down;
    server unix:/tmp/backend3;
    
    server backup1.test.com:8080 backup;
    server backup2.test.com:8080 backup; 
}
```

## 负载均衡调度策略

nginx默认是以轮询作为负载均衡策略，但是Nginx包含多种策略：

* **(时间)轮询**：按照时间顺序分配到不同的后端服务器，默认方式，无需配置
* **加权轮询**：weight值越大，分配访问的几率就越大 `server backend1.test.com weight=5;` 5代表，当有10个请求到达时，理论上当前服务器会命中五个请求
* **least\_conn**：最少连接数，优先选择连接数少的服务器，分发请求。
* **ip\_hash**：每个请求按照访问IP的hash值分配，那么同一IP的访问总是落到同一台服务器，可以解决分布式session共享的问题。缺陷，如果用户具有IP代理，那么IP就不是真实的IP，代理发生变化时，请求可能落到其他服务器上，解决办法：`url_hash`。
* **url\_hash**：按照访问的URL的hash结果来分配请求，让每个URL定向到同一个后端服务器
* **hash关键数值**：如果ip和url都不能满足需求，可以使用自定义key的方式

```nginx
# 示例配置
upstream blog {
    # url_hash, 一般是针对url中某个参数值进行hash，比如token
    hash $request_uri;
    
    server backup1.test.com;
    server backup2.test.com; 
}
```
