什么是负载均衡?

负载均衡(load balancing)可以直接拆解开来理解,把当前服务器的负载(主要指客户端请求)平衡分摊到其他服务器,从而达到增加当前服务器吞吐量,提升请求性能, 提高容灾的目的。

可以用平台订单的分拨做类比。比如说一个淘宝商家本来是自营的,自己卖的的东西自己生产,生产好了之后,再从当地发货到全国。现在生意做打了,订单量多到工厂产能不足,且因为产品具有一定的时效性,快递运送时间太长客户就不愿意买了。这时候就需要根据平台的订单收货地做一个排名,排名在前的城市优先建立新的工厂和生产线,优先供给。然后将新建工厂的城市辐射区域的订单分拨到新厂生产。

这时候产能上来了,订单反倒不足了。是关闭工厂节约成本,还是扩大订单量呢?市场一片大好,当然是要扩大订单量。商户自己做这事,品牌推广有点慢,就开始招全国各地代理商。甚至会给零散个体户做一件代发服务(本地工厂,闲着也是闲着)。

这是一个沙漏模型,一边是客户和代理商,一边是商家和工厂。负载均衡做的就是类似商家跟工厂端的优化升级,当前服务器负载压力大,就把当前服务器作为一个代理服务器,将用户请求分发到其他的服务器,这个概念叫反向代理。点我查看正向代理与反向代理

Nginx 实现负载均衡的几种方式

Nginx 使用 upstream 定义虚拟服务池,就是请求可转发的服务器列表。一般为 IP 地址,可以加如 :80 的端口号。使用域名会自动将其转化为域名映射所在 IP 地址,然后转发请求(自己测试过,以为添加多个虚拟主机就可以访问实现这个负载均衡的概念,结果都指向到 IP 地址,也是服务器默认的虚拟主机地址)。

...
upstream backend_server {
    server 192.168.1.13;
    server 192.168.1.14;
}

server {
...
  • 轮询(默认)

每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器 down 掉,会自动跳过,当后端服务器再次响应时,会自动恢复。

  • 权重(weight)

给虚拟服务池中的每个服务器添加 weight 属性(默认为 1),然后按照权重分配访问比率。

upstream backend_server {
    server 192.168.1.13:9001 weight=1;
    server 192.168.1.14:9002 weight=2;
}
  • ip_hash

根据请求 ip 地址(包含端口号) hash 值分配。主要解决登录状态(即 Session)保持的问题。开启后,如果客户已经访问了某个服务器,当再次访问时,会将请求通过哈希算法,自动定位到该服务器。

ip_hash;
upstream backend_server {
    server 192.168.1.13:9001;
    server 192.168.1.14:9002;
}
  • fair

第三方 Nginx 模块,需要下载跟 Nginx 一起编译安装,用 nginx -V 查看当前版本是否已安装。直接使用,会报错,指令无法识别。

安装教程:已经安装Nginx的基础上增加新模块(例子nginx-upstream-fair)

按后端服务器的响应时间来分配请求,响应时间短的优先分配。

upstream backend_server {
    fair;
    server 192.168.1.13:9001;
    server 192.168.1.14:9002;
}
  • url_hash

按访问 url 的 hash 结果来分配请求,使每个 url 定向到同一个后端服务器,后端服务器为缓存时比较有效。主要应用在请求第三方资源上,服务器群会缓存这样的资源,然后返回给用户。但每个服务器都去缓存一遍相同的资源太浪费带宽和存储空间了,用 url_hash 可以将同一资源请求规整到同一个服务器上,增加命中率。

upstream backend_server {
    server 192.168.1.13:9001;
    server 192.168.1.14:9002;
    hash $request_uri;
    hash_method crc32;
}

每个服务器的状态设置:

  • down 表示单前的 server 暂时不参与负载
  • weight 默认为 1。weight 越大,负载的权重就越大。
  • max_fails 允许请求失败的次数,默认为 1。当超过最大次数时,返回 proxy_next_upstream 模块定义的错误
  • fail_timeout max_fails 次失败后,暂停的时间。
  • backup 其它所有的非 backup 机器 down 或者忙的时候,请求 backup 机器。所以这台机器压力会最轻。

完整的简易负载均衡方案

修改 nginx.conf 文件

...
# 一般会建议与代理服务器核心数一致
worker_processes  4;
events {
    # 最大并发数
    worker_connections  1024;
}
http{
    # 待选服务器列表
    upstream backend_server {
        # ip_hash指令,将同一用户引入同一服务器。
        ip_hash;
        server 192.168.1.13:9001;
        server 192.168.1.14:9002;
    }

    server{
        # 监听端口
        listen 80;
        server_name lb.seasidecrab.com;

        #root /usr/local/nginx/html;
        #index index.html index.htm index.php;

        # 根目录下
        location / {
            # 选择哪个服务器列表
            proxy_pass http://backend_server;
            proxy_set_header host $host;
        }
    }
}

查看 CPU 个数和核心数指令

查看 CPU 个数

cat /proc/cpuinfo | grep 'physical id' | sort | uniq | wc -l

查看 CPU 核数

cat /proc/cpuinfo | grep 'process' | sort | uniq | wc -l

参考:【Nginx】实现负载均衡的几种方式 - alterem - cnblogs