<服务>Nginx负载均衡

时间:Nov. 20, 2016 分类:

目录:

例子(摘自官方文档)

upstream backend {
    server backend1.example.com       weight=5;
    server backend2.example.com:8080;
    server unix:/tmp/backend3;

    server backup1.example.com:8080   backup;
    server backup2.example.com:8080   backup;
}

server {
    location / {
        proxy_pass http://backend;
    }
}

例子解析

访问负载均衡服务器,server指向backend反向代理服务器池,服务配置在upstream backend下。

配置Nginx负载均衡

配置文件

worker_processes  1;
events {
    worker_connections  1024;
}
http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    keepalive_timeout  65;
    upstream backend {
    server 192.168.0.201:80   max_fails=3 fail_timeout=30s;
    server 192.168.0.203:80   max_fails=3 fail_timeout=30s;
    }
    server {
        listen       80;
        server_name  www.why.com;
        location / {
        proxy_pass http://backend;
        }
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }
}

#  max_fails=3最大失败次数,请求失败超过该次数,剔除该服务器。
(如何知道那个被剔除了呢,经过调研,并非本质上的剔除,依然会转发到坏的服务器,可以用第三方的检测模块)
#  fail_timeout=30s

用户访问www.why.com,把这个请求抛给proxy_pass,由proxy_pass抛给backend中的ip地址

proxy_pass算法

proxy_pass的算法有很多种,默认为rr(轮询),其他的例如ip hash(同一个ip的请求只会落在同一个服务器上,可以做到回话保持),weight(轮询+权重,可以解决新老服务器性能不均的问题)

重新载入配置文件

[root@why-2 conf]# ../sbin/nginx -t [root@why-2 conf]# ../sbin/nginx 启动的话就用nginx -s reload

检测Nginx负载均衡

通过IP

把201和203的index.php文件改为对应ip地址

[root@why-2 sbin]# for i in `seq 100`;do curl 192.168.0.202;sleep 2;done
192.168.0.203
192.168.0.201
192.168.0.203
192.168.0.201
192.168.0.203
192.168.0.201

通过域名

如果用域名的话配一下hosts

127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.0.202 www.why.com

[root@why-2 sbin]# for i in `seq 100`;do curl www.why.com;sleep 2;done
192.168.0.201
192.168.0.203
192.168.0.201
192.168.0.203
192.168.0.201

可以看出默认为轮询方式

关闭其中一个节点Nginx服务

在过程中在201节点killall nginx
[root@why-2 sbin]# for i in `seq 100`;do curl 192.168.0.202;sleep 2;done
192.168.0.203
192.168.0.201
192.168.0.203
192.168.0.201
192.168.0.203
192.168.0.203
192.168.0.203
192.168.0.203
192.168.0.203

业务不受影响

关闭另一节点Nginx服务

把203也关闭就会报

<!DOCTYPE html>
<html>
<head>
<title>Error</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>An error occurred.</h1>
<p>Sorry, the page you are looking for is currently unavailable.<br/>
Please try again later.</p>
<p>If you are the system administrator of this resource then you should check
the <a href="http://nginx.org/r/error_log">error log</a> for details.</p>
<p><em>Faithfully yours, nginx.</em></p>
</body>
</html>

重新启动Nginx服务

如果重新开启服务,nginx可以自动把服务器加载进来

关于登陆

如果用轮询算法,使用登录功能,在web服务器1上登录,刷新的话就在web服务器2上,就会提示没有登录,推荐用ip_hash 用法在upstream backend{}中添加

    upstream backend {
    ip_hash;
    server 192.168.0.201:80   max_fails=3 fail_timeout=30s;
    server 192.168.0.203:80   max_fails=3 fail_timeout=30s;
    }

在两台节点Nginx正常服务的情况下

[root@why-1 ~]# lsof -i :80
COMMAND  PID  USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
nginx   2352  root    6u  IPv4  14400      0t0  TCP *:http (LISTEN)
nginx   2353 nginx    6u  IPv4  14400      0t0  TCP *:http (LISTEN)
[root@why-3 html]# lsof -i :80
COMMAND  PID  USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
nginx   2270  root    6u  IPv4  14186      0t0  TCP *:http (LISTEN)
nginx   2271 nginx    6u  IPv4  14186      0t0  TCP *:http (LISTEN)

检测ip_hash

[root@why-2 sbin]# for i in `seq 100`;do curl 192.168.0.202;sleep 2;done
192.168.0.203
192.168.0.203
192.168.0.203
192.168.0.203
192.168.0.203

这样同一个ip就会只访问一个web服务器. 登录信息一般都是存在本地的tmp目录下的

一般这个session同步方式

  1. lvs -p,nginx ip_hash等,会产生负载不均
  2. 软件层session复制,例如recouchbase
  3. session共享,例如memcache等,这个也是用的最多的
  4. 门户网站会通过cookies缓存到用户本地的方式

多域名负载均衡

这是单域名的情况下,如果有很多域名需要进行负载均衡需要制定参数

proxy_set_header Host $host;通过header区分反向代理主机名
proxy_set_header X-Forwarded-For $remove_addr;

配置

worker_processes  1;
events {
    worker_connections  1024;
}
http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    keepalive_timeout  65;
    upstream backend {
    server 192.168.0.201:80   max_fails=3 fail_timeout=30s;
    server 192.168.0.203:80   max_fails=3 fail_timeout=30s;
    }
    server {
        listen       80;
        server_name  www.why.com;
        location / {
        proxy_pass http://backend;
        proxy_set_header Host $host;
        }
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }
    server {
        listen       80;
        server_name  www.why2.com;
        location / {
        proxy_pass http://backend;
        proxy_set_header Host $host;
        }
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }
}

在/etc/hosts中配置

127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.0.202 www.why.com www.why2.com

检测多域名Nginx负载均衡

[root@why-2 sbin]# for i in `seq 100`;do curl www.why2.com;sleep 2;done
203:why2
201:why2
203:why2
201:why2
203:why2
^C
[root@why-2 sbin]# for i in `seq 100`;do curl www.why.com;sleep 2;done
192.168.0.201
192.168.0.203
192.168.0.201
192.168.0.203
192.168.0.201
^C

这样就可以匹配多个虚拟主机了,不配置的话默认访问第一个。