Nginx 的负载均衡是通过 upstream 模块实现的。 upsteam 是Nginx 编译安装的时候,默认会安装的,upstream 还有热备的功能,默认带健康检查功能。

负载均衡的基本架构,先上图:

nginx upstream 模块 nginx upsync module_nginx upstream 模块


测试使用三台机器,centos 7 环境(编译按安装 稍微有Linux 经验的朋友就不会在意,版本不要太 特别就行)

主机名

IP地址

LB

172.17.0.3

Web-1

172.17.0.4

Web-2

172.17.0.5

基本介绍

下面这段是官网的 ngx_http_upstream_module的介绍和示例,我进行一下注释

The ngx_http_upstream_module module is used to define groups of servers that can be referenced by the proxy_pass,
fastcgi_pass, uwsgi_pass, scgi_pass, and memcached_pass directives.
// ngx_http_upstream_module 模块,用来定义 被 proxy_pass, fastcgi_pass, uwsgi_pass, scgi_pass, and memcached_pass 直接引用 的服务组

Example Configuration
// 下面是一个例子
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;
    }
}

proxy_pass 使用的是 proxy_pass 模块

proxy_pass 参数说明:

参数

说明

proxy_pass http://blog_server_poll;

用于指定反向代理的服务器池。

proxy_set_header Host $HOST;

当后端Web服务器上也配置有多个虚拟主机时,需要用该Header 来区分反向代理哪个主机名。

proxy_set_header X-Forwarded-For $remote_addr;

如果后端Web服务器上的程序需要获取用户的IP,从该Header 头获取。

使用了负载均衡,访问的主机就是负载均衡的主机了;

1:负载均衡功能初试

一台机器进行测试的话,可以根据端口做负载均衡

upstream backend {
        server 172.17.0.3:81;
        server 172.17.0.3:82;
}

server {
        listen 66;
        server_name 172.17.0.3;
        location / {
                proxy_pass http://backend;
        }
}

nginx upstream 模块 nginx upsync module_nginx_02


再刷新一次

nginx upstream 模块 nginx upsync module_服务器_03


可看到,都是访问一个url,两次访问的却是两个网站。

2. upstream 模块基本调度算法

  测试负载均衡的分配模式,更改 上面配置的 81、82 端口的网站的index.html, 文件内容改成81 和 82

[root@LB nginx]# cat html/port_8{1,2}/index.html
81
82
1)rr 轮询(默认)

  按客户端请求顺序把客户端的请求逐一分配到不同的后端的服务器,这相当于LVS 中 rr 算法,如果后端服务器宕机(默认情况只检测80端口,如果后端报 502,404, 403,503,还是会直接返回给用户),宕机服务器会被自动剔除,使用户访问不受影响。请求会分配给正常的服务器。

rr时(上面配置的负载均衡就是rr模式):

[root@LB nginx]# for in in `seq 10`;do curl http://127.0.0.1:66;done
82
81
82
81
82
81
82
81
82
81

可以看到 81 和 82 端口的网站,轮着显示。

2)weight(权重)

  再轮询算法的基础上加上权重(默认是 rr + weight),权重轮询和访问成正比,权重越大,转发的请求也就越多,可以根据服务器的配置和性能指定权重值大小,可以有效解决新旧服务器性能不均请求分配问题。

weight 时:
就是在 server 列表后面添加 weight = n
upstream backend {
    server 172.17.0.3:81 weight=4;
    server 172.17.0.3:82 weight=1;
}
```    
[root@LB nginx]# for in in `seq 10`;do curl http://127.0.0.1:66;done
81
81
82
81
81
81
81
82
81
81

负载均衡的配置文档
http://nginx.org/en/docs/http/ngx_http_upstream_module.html

3,使用rr,weight上面两种算法的问题 1

  会出现session变了,用户会出现在第一台机器上登录了,又要在第二台上登录,因为session换了机子就不一样了,lamp服务器上的session在lamp服务器上,lnmp服务器的在lnmp服务器上【此处是说个例子,工作中是会分开的,不会混合做群集】

解决方法:

1,使用ip_hash算法【这种算发能保证一个ip地址的回话只在一台服务器上】
# 修改配置
upstream backend {
        ip_hash;
        server 172.17.0.3:81 weight=4;
        server 172.17.0.3:82 weight=1;
}
[root@LB nginx]# for in in `seq 10`;do curl http://127.0.0.1:66;done
81
81
81
81
81
81
81
81
81
81

由于篇幅有限,这个效果多换几个浏览器就看的出来,大家可以自己测试。
弊端:这种方法,负载并不是非常的均衡(有可能访问都到一台机器上,另一台机器空闲)

集群架构多服务器同步 session有很多方式 ,如:
1. LB 层可以做会话保持,
2. 软件层可以做 session 复制,例如 Tomcat, Resin, couchbase
3. 共享,例如memcached或者其他的nosql工具,php 常用这个
4. 门户网站会用cookies或cookies 配合session 把用户级会话信息缓存在用户本地。

4:自动检查功能

upstream backend {
        server 172.17.0.3:81 weight=4;
        server 172.17.0.3:82 weight=1;
}

nginx能做到检查这两个server能否工作,当81端口的down掉,只会转到82端口上,81端口的up了,就又分别转到81或82端口上

5. 动态网站负载配置

  上面的基本配置方法 对于静态网站是没有问题的。但是对于动态网站(jsp、php 网站的话 就会有问题)

动态网站 可以做下面的配置:

upstream backend {
#        server 192.168.1.68:9998;
#        server 192.168.48.11:82;
        server 192.168.1.33:80;
}

server {
        listen 80;
        server_name 192.168.1.69;
        access_log  logs/host.access.log;
        location / {
                proxy_pass http://backend;
                #把我们和 代理nginx 通信的 HTTP 头原封不动的发给了 目的服务器 
                proxy_redirect off ;            
                #对发送给客户端的URL进行修改,
  #详解请参考:  
                proxy_set_header X-Real-IP $remote_addr;
                #参考:
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

        }
}

配置nginx proxy_pass 建议看这篇博文:
http://www.ttlsa.com/nginx/nginx-proxy_pass-root/