Nginx负载均衡

负载均衡最重要的一个应用是利用多台服务器提供单一服务,负载均衡主要应用于 Web 网站,大型的 Internet Relay Chat 网络,高流量的文件下载网站等。

对于互联网服务,Nginx可以为用户提供单一的外部接口,隐藏内网细节这样阻止对服务器其它运行端口的攻击。当所有后台服务器出现故障时,有些负载均衡器会提供一些特殊的功能来处理这种情况。例如转发请求到一个备用的负载均衡器、显示一条关于服务中断的消息等。

Nginx的upstream模块的负载均衡算法目前支持6种。

upstream支持状态参数,表示每个服务器的用途与特性:

例子

因为我们手头没有多台服务器,所以就定义多个server模块,来模拟负载均衡的情况。

worker_processes  1;
error_log logs/error.log info;

events {
    worker_connections 512;
}

http {
    open_file_cache max=204800 inactive=20s;
    open_file_cache_min_uses 1;
    open_file_cache_valid 30s;

    gzip on;
    gzip_min_length 1k;
    gzip_buffers 4 16k;
    gzip_http_version 1.0;
    gzip_comp_level 2;
    gzip_types text/plain; 

    log_format myformat '$remote_addr $status $time_local';
    access_log logs/access.log myformat;

    upstream server_group {
        server localhost:8001 weight=1;
        server localhost:8002 weight=2;
    }

    server {
        listen 8080;
        charset utf-8;
        location = / {
            proxy_pass http://server_group;
        }
    }

    server {
        listen 8001;
        charset utf-8;
        location = / {
            echo server1;
        }
    }

    server {
        listen 8002;
        charset utf-8;
        location = / {
            echo server2;
        }
    }
}

首先,我们定义了两个server分别坚挺8001和8002端口,然后,我们使用upstream来定义server_group,并包含前面定义的两个server,最后,我们在主的server中定义反向代理到server_group。这样,均衡负载就完成了。需要说明的一点是,反向代理部分虽然使用的server_grpoup但仍需要以http开头。

健康状态检查

upstream还支持健康状态检查,配置如下:

upstream webservers {
    server 192.168.18.201 weight=1 max_fails=2 fail_timeout=2;
    server 192.168.18.202 weight=1 max_fails=2 fail_timeout=2;
}

参数的含义可以从上方介绍查到,标记了最大失败的次数,和一旦失败,停止服务的时间。

备份服务器

如果全部的服务集群都宕机,我们需要一台sorry服务器,用于返回sorry页面,这个责任一般由均衡负载服务器担任(如果你规模够大,也许需要一台单独的sorry服务器)。

upstream server_group {
    server localhost:8005 weight=1 max_fails=2 fail_timeout=2;
    server localhost:8006 weight=1 max_fails=2 fail_timeout=2;
    server localhost:8003 backup;
}

server {
    listen 8003;
    charset utf-8;
    location = / {
        echo sorry;
    }
}

我们看到我把端口改为我没定义的服务端口,这样正常的服务都停止了,这时使用curl访问,就会获取8003上的sorry内容。

#ip_hash

有时候我们需要将同一客户的请求放到同一台服务器上,这样增加缓存的命中,减少服务期间同步的性能损耗,这是就需要用到ip_hash方式的均衡负载。实现很简单,只需要加上一行。

upstream webservers {
    ip_hash;
    server 192.168.18.201 weight=1 max_fails=2 fail_timeout=2;
    server 192.168.18.202 weight=1 max_fails=2 fail_timeout=2;
    #server 127.0.0.1:8080 backup;
}

就这样实现了ip_hash方式的均衡负载。