(1)lb配置


配置文件内容


[root@lb conf]# cat nginx.conf

worker_processes  ;

events {

    worker_connections  ;

}

http {

    include       mime.types;

    default_type  application/octet-stream;

    sendfile        on;

    keepalive_timeout  ;

    upstream bbs_server_pools {

        server ...: weight=;

        server ...: weight=;

    }

    server {

        listen ;

        server_name bbs.xpleaf.org;

        location / {

        proxy_pass http://bbs_server_pools;

        }

    }

}

配置hosts解析


[root@web bbs]# echo "... bbs.xpleaf.org">>/etc/hosts

[root@web bbs]# tail - /etc/hosts

... bbs.xpleaf.org

检查配置文件与启动


[root@web bbs]# /application/nginx/sbin/nginx -t      

nginx: the configuration file /application/nginx-..//conf/nginx.conf syntax is ok

nginx: configuration file /application/nginx-..//conf/nginx.conf test is successful

[root@web bbs]# /application/nginx/sbin/nginx -s reload


(2)Nginx负载均衡效果测试


    可以通过命令行的方式在lb上进行测试,如下:


[root@lb conf]# curl bbs.xpleaf.org

bbs.xpleaf.org node ...

[root@lb conf]# curl bbs.xpleaf.org

bbs.xpleaf.org node ...

[root@lb conf]# curl bbs.xpleaf.org

bbs.xpleaf.org node ...

[root@lb conf]# curl bbs.xpleaf.org

bbs.xpleaf.org node ...

[root@lb conf]# curl bbs.xpleaf.org

bbs.xpleaf.org node ...

[root@lb conf]# curl bbs.xpleaf.org

bbs.xpleaf.org node ...

    通过上面的测试可以知道,访问请求都被分担到两台节点服务器上,也可以通过在windows 的浏览器上输入地址来进行测试(需要先把"... bbs.xpleaf.org"添加到windows 的hosts文件中):

wKiomiwwXAcmqBAABBwpak.png

wKiomiwwWSoVoRAABphWSidw.png



.进阶:记录访问用户的实际IP地址


(3)原理

    上面我们通过windows 进行访问时,查看web服务器的日志:


[root@web bbs]# tail - /application/nginx/logs/access_bbs.log   

... - - [/Mar/::: +] "GET / HTTP/."   "-" "Mozilla/. (Windows NT .; WOW) AppleWebKit/. (KHTML, like Gecko) Chrome/... Safari/." "-"

... - - [/Mar/::: +] "GET / HTTP/."   "-" "Mozilla/. (Windows NT .;

    因为在配置web服务器节点时,配置的日志格式是这样的:




    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '

                      '$status $body_bytes_sent "$http_referer" '

                      '"$http_user_agent" "$http_x_forwarded_for"';

    所以前面日志的第一个字段用来记录Nginx均衡服务器的地址,这没有问题,但是最后一个字段是'-',也就是没有记录,该字段是用来记录用户的实际IP的。


(4)配置Nginx携带用户实际IP


    为了能够让web服务器记录用户的实际IP,需要在Nginx负载均衡服务器上做如下配置:


[root@lb conf]# cat nginx.conf

worker_processes  ;

events {

    worker_connections  ;

}

http {

    include       mime.types;

    default_type  application/octet-stream;

    sendfile        on;

    keepalive_timeout  ;

    upstream bbs_server_pools {    # 定义节点资源池

        server ...: weight=;

        server ...: weight=;

    }

    server {

        listen ;

        server_name bbs.xpleaf.org;

        location / {

        proxy_pass http://bbs_server_pools;    # 把请求转发到节点资源池中指定的主机中

        proxy_set_header X-Forwarded-For $remote_addr;

        }

    }

}

    实际上就是多加了最后一行。


(5)测试


    这时再用windows 去访问bbs.xpleaf.org,然后在web服务器上查看日志信息:




[root@web bbs]# tail - /application/nginx/logs/access_bbs.log 

... - - [/Mar/::: +] "GET / HTTP/."   "-" "Mozilla/. (Windows NT .; WOW) AppleWebKit/. (KHTML, like Gecko) Chrome/... Safari/." "..."

... - - [/Mar/::: +] "GET / HTTP/."   "-" "Mozilla/. (Windows NT .; WOW) AppleWebKit/. (KHTML, like Gecko) Chrome/... Safari/." "..."

    可以看到日志的最后一个字段就记录了客户端的真实IP地址。



.进阶:节点服务器多虚拟机场景


    前面在每台web服务器上,只配置了一个站点bbs.xpleaf.org,所以上面的负载均衡是没有问题,但是如果再配置一个站点blog.xpleaf.org(即在bbs.xpleaf.org后面再增加一个server域),当去测试时就会发现,无论是访问bbs.xpleaf.org,还是访问blog.xpleaf.org,返回的内容都是站点bbs.xpleaf.org的内容。

    究其原因是当用户访问域名时确实是携带了blog.xpleaf.org主机头请求Nginx反向代理服务器,但是是反向代理服务器向下面节点重新发起请求时,默认并没有在请求头里告诉节点服务器要找哪台虚拟主机,所以web节点服务器接收到请求后发现没有主机头信息,因此,就把节点服务器的第一个 虚拟机发给了反向代理。

    解决方法是,当反向代理向后重新发起请求时,要携带主机头信息,以明确告诉节点服务器要找哪个虚拟机。只需要在Nginx负载均衡服务器上增加下面一行配置:


proxy_set_header Host $host;

    此时配置文件内容如下:


[root@lb conf]# cat nginx.conf

worker_processes  ;

events {

    worker_connections  ;

}

http {

    include       mime.types;

    default_type  application/octet-stream;

    sendfile        on;

    keepalive_timeout  ;

    upstream bbs_server_pools {

        server ...: weight=;

        server ...: weight=;

    }

    server {

        listen ;

        server_name bbs.xpleaf.org;

        location / {

        proxy_pass http://bbs_server_pools;

        proxy_set_header X-Forwarded-For $remote_addr;

        proxy_set_header Host $host;

        }

    }

}

    由于原理比较简单,这里就不给出完整过程了,可以参考老男孩老师的书籍。



.进阶:根据URL中的目录地址实现代理转发


    根据HTTP的URL进行转发的应用情况,被称为第层(应用层)的负载均衡,而LVS的负载均衡一般用于TCP等的转发,因此被称为第层转发(传输层)的负载均衡。

    在上面的案例中,如果需要实现一个需求,希望bbs.xpleaf.org可以使用bbs.xpleaf.org/upload来提供上传服务,而bbs.xpleaf.org则保持默认提供网站的主页内容,这时就可以使用Nginx基于URL来实现代理转发了。

    可以把lb的Nginx配置修改为如下:


[root@lb conf]# cat nginx.conf

worker_processes  ;

events {

    worker_connections  ;

}

http {

    include       mime.types;

    default_type  application/octet-stream;

    sendfile        on;

    keepalive_timeout  ;

    upstream bbs_server_pools {

        server ...: weight=;

    }

    upstream bbs_upload_server_pools {

                server ...:  weight=;

        }

    server {

        listen ;

        server_name bbs.xpleaf.org;

        location / {

        proxy_pass http://bbs_server_pools;

        }

        location /static {

                proxy_pass http://bbs_upload_server_pools;

                }

    }

}

    这样,实际上就相当于bbs.xpleaf.org提供了两种不同的业务,一种是普通的bbs论坛内容业务,另外一种则是上传业务,上面我们定义了两个地址池,在每个地址池中,如果有多台节点服务器,就可以根据upstream的相关调度算法来实现不同业务的负载均衡了,总结来说就是,只使用一个域名对外提供服务,同时该域名对外提供不同的产品业务。

    当然,基于这种思想,通过location的正则匹配,可以根据用户不同的浏览器版本来访问不同的服务器群、根据设备的不同类型来访问不同的服务器群(PC端和移动端)、根据文件扩展名来访问不同的服务器群(实现动静分离),从而可以提升用户的体验。相关案例可以参考老男孩老师的书籍。



.原理解析:http proxy模块和upstream模块


    Nginx的反向代理功能和负载均衡功能是通过http proxy模块和upstream模块来实现的:

Nginx http功能模块 模块说明

ngx_http_proxy_module proxy代理模块,用于把请求后抛给服务器节点或upstream服务器池

ngx_http_upstream_module 负载均衡模块,可以实现网站的负载均衡功能及节点的健康检查


(1)http proxy模块


    配置方法可以参考上面的案例,实际上还有很多参数可以使用,这里不详细给出。


(2)upstream模块


    主要介绍一下upstream模块在实现负载均衡功能时的调度算法,其实关于upstream的调度算法,如果学习过QoS,看起来就会觉得很熟悉了。

静态调度算法:负载均衡器根据自身设定的规则进行分配,不需要考虑后端节点服务器的情况



主要有rr、wrr、ip_hash

()rr轮询

如果节点服务器不宕机,请求将会平均分发到各节点服务器上;

()wrr权重轮询

按照设置的weight权重,将请示按比例分发到各节点服务器上;

()ip_hash

按照客户端IP的hash结果分配;

可以解决动态网页的session共享问题(会话保持),但无法保证:的负载均衡;

动态调度算法:负载均衡器会根据后端节点的当前状态来决定是否分发请求


主要有fair、least_conn、url_hash、一致性hash算法

()fair

根据后端节点服务器的响应时间来分配请求,响应时间短的优先分配;

Nginx本身不支持该算法,需要下载相关模块upstream_fair;

()least_conn

根据后端节点的连接数来决定分配情况,哪个机器连接数少就分发;

()url_hash(第三方调度算法)

与ip_hash类似,根据访问URL来分配请求,让每个URL定向到同一个后端服务器;

后端服务器为缓存服务器时效果显著;

()一致性hash算法(第三方调度算法)

比较复杂,这里不做介绍。


.下一步做什么


    首先当然是要能够把Nginx负载均衡的环境搭建出来,否则是没有办法继续往下面学习的,然后就是继续加深Nginx负载均衡的理解,同时也在实际场景中多分析和尝试使用。