Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

负载均衡

需要一台专门的proxy机器,安装和配置nginx

设置 upstream规则 分配负载的几种方式

  • 【默认】轮询

    • 每个请求按照时间顺序,轮流分配到后端服务器
      • 如果发现某个服务器挂机,能自动剔除
    • 配置
      upstream 规则名{
          server 192.168.1.11:8888;
          server 192.168.1.22:8888;
          server 192.168.1.33:8888;
      }
      
  • 权重(weight)

    • 每个请求根据指定的服务器权重(即处理能力),去轮询
    • 配置
      upstream 规则名 {
          server 192.168.1.11:8888 weight=1;
          server 192.168.1.22:8888 weight=2;
          server 192.168.1.33:8888 weight=3;
      }
      
  • 哈希(ip_hash)

    • 每个请求按照访问ip的hash结果分配
      • 每个访客会固定访问一个后端服务器,可以解决 session 一致问题
    • 配置
      upstream 规则名 {
          ip_hash;
          server 192.168.1.11:8888 weight=1;
          server 192.168.1.22:8888 weight=2;
          server 192.168.1.33:8888 weight=3;
      }
      
      • 可叠加权重
    • 注意
      • 如果配置了CDN,那对某个CDN的IP全部导向一台服务器就不对了
      • 这时就必须要获取 真正的用户原始IP
        map $http_x_forwarded_for $clientRealIp {  
            "" $remote_addr;
            ~^(?P<firstAddr>[0-9\.]+),?.*$$firstAddr; 
        }
        
        upstream 规则名 {
            hash $clientRealIp;
            server 192.168.1.11:8888 weight=1;
            server 192.168.1.22:8888 weight=2;
            server 192.168.1.33:8888 weight=3;
        }
        

设置 upstream规则的 keepalive

  • 参数含义

    • 允许的连接池中最大空闲连接数量
  • 偷懒设置

    upstream 规则名 {
    
    
        keepalive 1000;
    }
    
  • 解释

    • 假设 keepalive 设置成100

      • 这时第1秒要来1000个请求
        • 那nginx就会用连接池建立1000个连接,并分配出去,一个请求对应一个连接
        • 处理完之后,这些连接就会回到连接池,变成空闲连接,等待下一秒的1000个请求
      • 如果第2秒还来1000个请求,那所有连接都不会空闲,不会触发此最大值
      • 如果第3秒只来500个请求,那还剩500个空闲,超过最大值100,所以400个要被释放
        • 处理完之后,回到连接池,只剩600个
      • 如果第4秒突然来1500个请求,600个就不够用了,又要紧急分配900个出来
    • 流量就是会像上面那样,震荡不均匀

      • 所以 keepalive决不能设置太小,否则就会频繁触发 释放 和 分配,造成资源浪费
  • 精打细算设置

    • 如果要求 10000 QPS 和 100毫秒响应时间
      • 就可以推算出需要的长连接数量大概是1000
      • 然后将keepalive设置为这个长连接数量的10%到30%(波动率)

使用 upstream规则

server {

    location / {
        proxy_pass http://规则名;
    }
}