nginx负载均衡常见问题

  1. 客户端 IP 地址获取问题
  2. 域名携带问题
  3. 负载均衡导致 session 丢失问题
  4. 动态负载均衡问题
  5. 真实的 Realserver 状态检测

负载均衡的方式

  1. rr 轮询
  2. weight 代表权,权越高优先级越高。
  3. fair 按后端服务器的响应时间来分配请求,相应时间短的优先分配。
  4. ip_hash 每个请求按照访问 ip 的 hash 结果分配

后端服务器 在负载均衡调度中的状态

down : 不参与负载均衡
backup : 预留的备份服务器
max_fails : 允许请求失败的次数
fail_timeout : max_fails 后,服务暂停的时间
max_conns : 限制最大的接收的连接数

客户端 IP 地址获取问题

第一种方式的解决办法是在 Nginx 负载均衡的基础上添加了一个转发到后端的标准 head 信息,把用户的 IP 信息通过 X-Forwarded-For 方式传递过去

第二种方式是就是添加一个 X-Real 的自定义头,自定义头我们可以随意的命名,一般情况下命名为 X-Real_IP,把用户的真实四层 IPc地址赋值给它

域名携带问题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
http {
        …
        upstream app_servers {
                 server ip1:port1;
                 server ip2:port2;
                 server ip3:port3;
        }
        server {
         …
              location / {
     proxy_set_header Host $host ;
     proxy set_header Host www.test.com; 
     proxy_pass http://app_servers; 
              }
        ….
        }
}

通过 proxy_set_header 配置方式加入 Host 头部字段,如果用户的请求携带了域名,就把这个域名的 head 头以标准的 HTTP 方式将头信息传递到后端,然后让后端获取 Host 头信息

负载均衡导致 session 丢失问题

  1. Session 保持 : ip_hash、URL_hash 来解决
  2. Session 复制 : 让 Session 之间可以以传播的方式进行复制,每个 App 上都会有同样的 Session 信息,不至于因为轮询导致丢失会话失效
  3. Session 共享 : Session 信息不放在本地,通过应用程序把 Session 信息放入共享的 K/V 存储中,这样就不会产生 Session 丢失情况了

使用 ip_hash

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
http {
        …
        upstream app_servers {
                 ip_hash;
                 server ip1:port1;
                 server ip2:port2;
                 server ip3:port3;
        }
        server {
         …
              location / {
                  proxy_pass http://app_servers; 
              }
        ….
        }
}

使用 url_hash

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
http {
        …
        upstream app_servers {
            hash $request_uri;
                 server ip1:port1;
                 server ip2:port2;
                 server ip3:port3;
        }
        server {
         …
              location / {
                  proxy_pass http://app_servers;   
              }
        ….
        }
}

真实的 Realserver 状态检测

这个第三方模块 nginx_upstream_check_module

1
2
3
4
check interval=3000 rise=2 fall=5 timeout=1000 type=http;  //定义检查间隔、周期、时间
check_keepalive_requests 100;  //一个连接发送的请求数
check_http_send “HEAD / HTTP/1.1\r\nConnection: keep-alive\r\n\r\n”; //定义健康检查方式
check_http_expect_alive http_2xx http_3xx;  //判断后端返回状态码

通过这样的配置,我们定义了检测间隔、周期和超时时间;定义了一个连接发送的请求数;然后是定义健康检查方式,比如检查 head 头的请求信息;最后判断后端返回状态码,如果是非 200 或 300 的话,就认为后台服务不健康,需要把这个问题服务除掉,避免用户请求到问题节点

动态负载均衡问题

可以使用第三方工具