![](http://static.blog.csdn.net/images/category_icon.jpg)
版权声明:本文为博主原创文章,未经博主允许不得转载。
之前一直使用nginx 的upstream,今天有个哥们问我,upstream的调动算法是什么,我说我还真没注意过,使用Haproxy的时候倒是注意过,回来一查,原来也是round-robin,下面是nginx 官方文档给出的说明:
This module provides simple load-balancing (round-robin and client IP) across backend servers.
Example:
upstream backend {
server backend1.example.com weight=5;
server backend2.example.com:8080;
server unix:/tmp/backend3;
}
server {
location / {
proxy_pass http://backend;
}
}
轮询调度算法(Round-Robin Scheduling)
轮询调度算法的原理是每一次把来自用户的请求轮流分配给内部中的服务器,从1开始,直到N(内部服务器个数),然后重新开始循环。
算法的优点是其简洁性,它无需记录当前所有连接的状态,所以它是一种无状态调度。
轮询调度算法流程
假设有一组服务器N台,S = {S1, S2, …, Sn},一个指示变量i表示上一次选择的服务器ID。变量i被初始化为N-1。其算法如下:
- j = i;
- do
- {
- j = (j + 1) mod n;
- i = j;
- return Si;
- } while (j != i);
- return NULL;
当然nginx也不止round-robin 这一种策略还有ip_hash 一种,这种好处就是一个ip总是被转发同一server;
ip_hash
syntax: ip_hash
default: none
context: upstream
This directive causes requests to be distributed between upstreams based on the IP-address of the client.
The key for the hash is the class-C network address of the client. This method guarantees that the client request will always be transferred to the same server. But if this server is considered inoperative, then the request of this client will be transferred to another server. This gives a high probability clients will always connect to the same server.
It is not possible to combine ip_hash and weight methods for connection distribution. If one of the servers must be removed for some time, you must mark that server as *down*.
For example:
upstream backend {
ip_hash;
server backend1.example.com;
server backend2.example.com;
server backend3.example.com down;
server backend4.example.com;
}
模块官方介绍:
http://wiki.nginx.org/HttpUpstreamModule
http://www.howtocn.org/nginx:Nginx%E6%A8%A1%E5%9D%97%E5%8F%82%E8%80%83%E6%89%8B%E5%86%8C%E4%B8%AD%E6%96%87%E7%89%88
说说upstream里的server指令
server后面可以是域名格式,也可以是socket格式[ip:port],后面还可以带参数。参数有下面几个:
weight = NUMBER - 设置服务器的权重值,默认为1. 值越大,分配的请求越多。只适用于轮询这种LB策略。
max_fails = NUMBER -
在fail_timeout设置的时间内,尝试连接服务器失败的次数.默认为1,0表示关闭检查.错误类型在proxy_next_upstream
or fastcgi_next_upstream中定义,(除了404错误不计入max_fails).
fail_timeout = TIME - the time during which must occur *max_fails* number of unsuccessful attempts at communication with the server that would cause the server to be considered inoperative, and also the time for which the server will be considered inoperative (before another attempt is made). If not set the time is 10 seconds. fail_timeout has nothing to do with upstream response time, use proxy_connect_timeout and proxy_read_timeout for controlling this.
down - marks server as permanently offline, to be used with the directive ip_hash.
backup - (0.6.7 or later) only uses this server if the non-backup servers are all down or busy (cannot be used with the directive ip_hash)
nginx负载均衡的策略:
1.轮询(默认方式)
对于一级后端服务器群,形成一个环队列的形式,对于每个到达的请求按时间顺序顺次分配给这些后端服务器。在前端调度器与后端服务器之间采用“心跳”方式进行状态检查,如果发现后端服务器宕机,则将其删除。
这种方式为默认配置,优点是简洁,但缺点是无法进行最优化调度,有可能有的请求需要耗时较久,这样会带来一定的不平衡。
它的例子:在http区域里添加:
upstream lb {
server 10.10.57.122:80;
server 10.10.57.123:80;
}
在你的某个server里增加:
location / {
proxy_pass http://lb;
}
2. 加权轮询
这是一种对上述方式的改进,引入权值的概念,能够解决后端服务器性能不均的情况。
例如这样一个配置:
upstream lb {
server 10.10.57.122:80 weight=5;
server 10.10.57.123:80 weight=10;
}
ps:以上轮询负载均衡策略,我个人认为对于动态网站应用,这几乎就是形同摆设,没有人会采用。但一种情况例外:服务器端的session采用共享机制,如存储在数据库或者memcached内存里等。
3. ip_hash(基于ip的hash分配策略)
这是一种非轮询式方式,对于每个到达的请求,直接通过其请求IP进行哈希的映射,通过映射结果获得那一台后端服务器要处理这个请求,这种方式有一个明显的好处是能够保证session的唯一性。
它的配置例子:
upstream lb {
ip_hash;
server 10.10.57.122:80;
server 10.10.57.123:80;
}
在你的某个server里增加:
location / {
proxy_pass http://lb;
}
This directive causes requests to be distributed between upstreams based on the IP-address of the client.
The key for the hash is the class-C network address of the client. This method guarantees that the client request will always be transferred to the same server. But if this server is considered inoperative, then the request of this client will be transferred to another server. This gives a high probability clients will always connect to the same server.
It is not possible to combine ip_hash and weight methods for connection distribution. If one of the servers must be removed for some time, you must mark that server as *down*.
由这段英文解说知道,客户端只要来自同一网段的ip的request都会转发到相同的后端服务器上。这里的所谓的class-C
network这里作者并没有很详细地解释,我只能说,写这句话的人不懂网络。我个人的理解是:以ip地址的点分十进制格式的前3个字节进行hash。
其实这不是真正意义上的ip address hash,而只是network address hash。真正的ip address hash方式有不?其实可以通过下面介绍的url_hash来实现。关键指令:hash $remote_addr;
不过这里有个前提,$remote_addr必须是client的real ip address。
为什么这里能够实现真正意义上的ip address hash?很简单,就是这里整个ip address被当作一个字符串来对待,故只要ip地址(key)不同,hash必然也是不同的。
4. url_hash(基于URL的哈希方式)
这种方式与IP的哈希方式类似,是对客户机请求的URL进行哈希操作,这样的方式有一个明显的好处是,能够便于内容缓存的实现,对于经常性的资源访问,采
用这样的方式会获得非常好的质量。它目前不是nginx自带的功能,需要安装补丁方可使用。本指令的详细说明和安装见:(文章后面有附带详细安装实例)
http://wiki.nginx.org/HttpUpstreamRequestHashModule
它的配置方式为:
upstream lb {
server 10.10.57.122:80;
server 10.10.57.123:80;
hash $request_uri;
}
如果将这里的$request_uri换成$remote_addr便可实现上面我所说的真正基于ip地址的策略。
5. 基于服务响应式
这种方式是根据服务器端的动态响应,对每一个请求进行分配。 这种方式能够自动根据当前的后端实际负载来优化。
它的配置方式:
upstream lb {
server 10.10.57.122:80;
server 10.10.57.123:80;
fair;
}
这个没怎么测试,只是配起来用了下,机器差不多的话感觉就是轮询。
===============================
cd nginx-0.7.67;
patch -p0 < ../nginx_upstream_hash-0.3.1/nginx.patch
configure时:
./configure --prefix=/app/nginx -user=nobody -group=nobody \
--add-module=../nginx_upstream_hash-0.3.1/ \
--add-module=../gnosek-nginx-upstream-fair-2131c73/
========================================
upstream www.test1.com {
ip_hash;
server 172.16.125.76:8066 weight=10;
server 172.16.125.76:8077 down;
server 172.16.0.18:8066 max_fails=3 fail_timeout=30s;
}
-
down,表示当前的server暂时不参与负载均衡。
-
backup,预留的备份机器。当其他所有的非backup机器出现故障或者忙的时候,才会请求backup机器,因此这台机器的压力最轻。
-
max_fails,允许请求失败的次数,默认为1。当超过最大次数时,返回proxy_next_upstream 模块定义的错误。
-
fail_timeout,在经历了max_fails次失败后,暂停服务的时间。max_fails可以和fail_timeout一起使用。
1.轮询(默认)。每个请求按时间顺序逐一分配到不同的后端服务器,如果后端某台服务器宕机,故障系统被自动剔除,使用户访问不受影响。Weight 指定轮询权值,Weight值越大,分配到的访问机率越高,主要用于后端每个服务器性能不均的情况下
vim balance-http.conf
upstream balance{
server 127.0.0.1:81 weight=1 ;
server 172.16.8.100:81 weight=1 ;
server 127.0.0.1:81 backup;
}
在backup主机上定义默认页,echo "this is backup" > backup.html
当前两台机器出现故障无法访问时,我们可以定义backup主机来供用户访问,这样可以提高用户体验。
2.ip_hash。每个请求按访问IP的hash结果分配,这样来自同一个IP的访客固定访问一个后端服务器,有效解决了动态网页存在的session共享问题。
vim balance-http.conf
upstream balance{
ip_hash;
server 127.0.0.1:81 weight=1max_fails=2 fail_timeout=2;
server 172.16.8.100:81 weight=1max_fails=2 fail_timeout=2;
}
不断刷新页面后,会一直停留在某一页面。