# 负载均衡

软负载均衡用来替代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; 
}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://yangsx95.gitbook.io/notes/distributed/web-fu-wu-qi/nginx/fu-zai-jun-heng.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
