Nginx反向代理与负载均衡:节点服务器单/多虚拟机配置+实验环境搭建+原理解析

.说明
常见的集群架构及相关软件,可以参考下面的导图:


互联网企业常用的是负载均衡集群和高可用性集群,负载均衡集群强调“分担”,通过一定的调度算法 ,可以实现用多个节点服务器来分担用户的访问请求和数据流量;高可用性集群强调“高可用”,即一个节点失效了,它的任务可以立刻转移到另一个备份的节点上(即一般通过设置主备来实现)。显然因为负载均衡集群使用多个节点来分担服务,即使其中一个节点失效了,其它节点也可以继续工作,因此它也具有高可用性。
下面介绍的是Nginx负载均衡的配置,同时也给出了实验环境。


1.实验环境说明
本次实验的测试环境使用的宿主机操作系统为Windows 7,在Vmware虚拟机安装CentOS 6.5(3台),说明如下:

主机类型 操作系统 IP地址 作用
宿主机 Windows 7 10.0.0.1/24(VMnet8的IP地址) 远程3台虚拟机,进行配置,同时也作为后面测试使用的客户端
虚拟机1: lb01 CentOS 6.5 10.0.0.7/24 负载均衡服务器lb01,将请求分担到Web节点服务器中
虚拟机2: web01 CentOS 6.5 10.0.0.9/24 Web节点服务器web01
虚拟机3: web02 CentOS 6.5 10.0.0.10/24 Web节点服务器web02

而当使用NAT的方式进行上网时虚拟机、宿主机之间的网络连接关系可如下所示:


关于为什么网络拓扑结构是这样的,这里不展开说明,可以参考博主的另一篇博文《在实践中深入理解VMware虚拟机的上网模式NAT模式》,这篇文章深入地分析了VMware虚拟机使用NAT模式上网时的网络结构细节,相信看完这篇文章后,这里搭建Nginx的实验环境也就很容易理解了。
所以首先,应该是自己先配置好网络环境,让宿主机跟我们的虚拟机可以通信,实际上,如果理解了VMware虚拟机上网方式的原理,同时对CentOS的网络配置也很熟悉,这一步是可以很轻松完成的,这里就不给出过程了,这里所用的IP地址跟上面的图示是一样的。
这里,对于Nginx的负载均衡,希望达到的效果逻辑如下:


当用户访问我们的Web Server时,实际上请求是先到达Nginx负载均衡器,这就是一个反向代理的过程了,然后Nginx负载均衡器再将请求按照一定的调度算法分发给相应的节点服务器。
在整个实验环境中,我们假定web01和web02提供bbs.xpleaf.org的网站内容服务,Nginx在web01和web02前面作为反向代理服务器与负载均衡服务器,当用户访问bbs.xpleaf.org时,Nginx负载均衡器会把请求分发到web01和web02节点服务器上,由节点服务器返回实际的内容数据。


2.配置与测试实战:节点服务器单虚拟机场景


这里使用的Nginx的版本为:1.6.3,关于Nginx的安装与基本配置,这里不再做说明,可以参考博主前面关于Nginx的博文,同样也是给出了详细的实验环境,可以去实践一下。

下面在每台web服务器上,我们只配置了一个虚拟机,即bbs.xpleaf.org。

(1)web01配置与测试

  • web01作为节点服务器,配置它的虚拟机域名为bbs.xpleaf.org

[root@web01 conf]``# cat nginx.conf

worker_processes 1;

events {

worker_connections 1024;

}

http {

include mime.types;

default_type application``/octet-stream``;

sendfile on;

keepalive_timeout 65;

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

'$status $body_bytes_sent "$http_referer" '

'"$http_user_agent" "$http_x_forwarded_for"'``;

server {

listen 80;

server_name bbs.xpleaf.org;

location / {

root html``/bbs``;

index index.html index.htm;

}

access_log logs``/access_bbs``.log main;

}

}

|

  • 添加相应的站点目录和内容

[root@web01 conf]``# cd ../html/bbs/

[root@web01 bbs]``# echo "bbs.xpleaf.org node1 10.0.0.9">index.html

[root@web01 bbs]``# cat index.html

bbs.xpleaf.org node1 10.0.0.9

|

  • 配置hosts解析

[root@web01 bbs]``# echo "127.0.0.1 bbs.xpleaf.org">>/etc/hosts

[root@web01 bbs]``# tail -1 /etc/hosts

127.0.0.1 bbs.xpleaf.org

|

  • 检查配置文件与启动

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

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

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

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

|

  • 本机上进行测试

[root@web01 bbs]``# curl bbs.xpleaf.org

bbs.xpleaf.org node1 10.0.0.9

|

(2)web02配置与测试

  • web02作为节点服务器,配置它的虚拟机域名为bbs.xpleaf.org

[root@web02 conf]``# cat nginx.conf

worker_processes 1;

events {

worker_connections 1024;

}

http {

include mime.types;

default_type application``/octet-stream``;

sendfile on;

keepalive_timeout 65;

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

'$status $body_bytes_sent "$http_referer" '

'"$http_user_agent" "$http_x_forwarded_for"'``;

server {

listen 80;

server_name bbs.xpleaf.org;

location / {

root html``/bbs``;

index index.html index.htm;

}

access_log logs``/access_bbs``.log main;

}

}

|

  • 添加相应的站点目录和内容

[root@web01 conf]``# cd ../html/bbs/

[root@web01 bbs]``# echo "bbs.xpleaf.org node2 10.0.0.10">index.html

[root@web01 bbs]``# cat index.html

bbs.xpleaf.org node2 10.0.0.10

|

  • 配置hosts解析

[root@web01 bbs]``# echo "127.0.0.1 bbs.xpleaf.org">>/etc/hosts

[root@web01 bbs]``# tail -1 /etc/hosts

127.0.0.1 bbs.xpleaf.org

|

  • 检查配置文件与启动

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

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

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

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

|

  • 本机上进行测试

[root@web02 bbs]``# curl bbs.xpleaf.org

bbs.xpleaf.org node2 10.0.0.10

|

(3)lb01配置

  • 配置文件内容

[root@lb01 conf]``# cat nginx.conf

worker_processes 1;

events {

worker_connections 1024;

}

http {

include mime.types;

default_type application``/octet-stream``;

sendfile on;

keepalive_timeout 65;

upstream bbs_server_pools {

server 10.0.0.9:80 weight=1;

server 10.0.0.10:80 weight=1;

}

server {

listen 80;

server_name bbs.xpleaf.org;

location / {

proxy_pass http:``//bbs_server_pools``;

}

}

}

|

  • 配置hosts解析

[root@web01 bbs]``# echo "127.0.0.1 bbs.xpleaf.org">>/etc/hosts

[root@web01 bbs]``# tail -1 /etc/hosts

127.0.0.1 bbs.xpleaf.org

|

  • 检查配置文件与启动

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

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

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

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

|

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

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

[root@lb01 conf]``# curl bbs.xpleaf.org

bbs.xpleaf.org node1 10.0.0.9

[root@lb01 conf]``# curl bbs.xpleaf.org

bbs.xpleaf.org node2 10.0.0.10

[root@lb01 conf]``# curl bbs.xpleaf.org

bbs.xpleaf.org node1 10.0.0.9

[root@lb01 conf]``# curl bbs.xpleaf.org

bbs.xpleaf.org node2 10.0.0.10

[root@lb01 conf]``# curl bbs.xpleaf.org

bbs.xpleaf.org node1 10.0.0.9

[root@lb01 conf]``# curl bbs.xpleaf.org

bbs.xpleaf.org node2 10.0.0.10

|

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


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

(1)原理

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

[root@web01 bbs]``# tail -2 /application/nginx/logs/access_bbs.log

10.0.0.7 - - [04``/Mar/2017``:11:33:00 +0800] ``"GET / HTTP/1.0" 200 30 ``"-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36" "-"

10.0.0.7 - - [04``/Mar/2017``:11:33:29 +0800] ``"GET / HTTP/1.0" 304 0 ``"-" "Mozilla``/5``.0 (Windows NT 6.1;

|

因为在配置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的。

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

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

[root@lb01 conf]``# cat nginx.conf

worker_processes 1;

events {

worker_connections 1024;

}

http {

include mime.types;

default_type application``/octet-stream``;

sendfile on;

keepalive_timeout 65;

upstream bbs_server_pools { ``# 定义节点资源池

server 10.0.0.9:80 weight=1;

server 10.0.0.10:80 weight=1;

}

server {

listen 80;

server_name bbs.xpleaf.org;

location / {

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

proxy_set_header X-Forwarded-For $remote_addr;

}

}

}

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

(3)测试

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

[root@web01 bbs]``# tail -2 /application/nginx/logs/access_bbs.log

10.0.0.7 - - [04``/Mar/2017``:11:49:10 +0800] ``"GET / HTTP/1.0" 200 30 ``"-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36" "10.0.0.1"

10.0.0.7 - - [04``/Mar/2017``:11:49:11 +0800] ``"GET / HTTP/1.0" 200 30 ``"-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36" "10.0.0.1"

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


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

前面在每台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@lb01 conf]``# cat nginx.conf`

`worker_processes  1;`

`events {`

`worker_connections  1024;`

`}`

`http {`

`include       mime.types;`

`default_type  application``/octet-stream``;`

`sendfile        on;`

`keepalive_timeout  65;`

`upstream bbs_server_pools {`

`server 10.0.0.9:80 weight=1;`

`server 10.0.0.10:80 weight=1;`

`}`

`server {`

`listen 80;`

`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;`

`}`

`}`

`}`

 |

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


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

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

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

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


`[root@lb01 conf]``# cat nginx.conf`

`worker_processes  1;`

`events {`

`worker_connections  1024;`

`}`

`http {`

`include       mime.types;`

`default_type  application``/octet-stream``;`

`sendfile        on;`

`keepalive_timeout  65;`

`upstream bbs_server_pools {`

`server 10.0.0.9:80 weight=1;`

`}`

`upstream bbs_upload_server_pools {`

`server 10.0.0.10:80  weight=1;`

`}`

`server {`

`listen 80;`

`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端和移动端)、根据文件扩展名来访问不同的服务器群(实现动静分离),从而可以提升用户的体验。相关案例可以参考老男孩老师的书籍。


6.原理解析: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

(1)rr轮询

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

(2)wrr权重轮询

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

(3)ip_hash

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

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

|

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

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

(1)fair

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

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

(2)least_conn

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

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

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

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

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

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

|


7.下一步做什么

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

实际场景:给flume,elasticsearch,web应用做负载均衡

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,565评论 6 479
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,021评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,003评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,015评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,020评论 5 370
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,856评论 1 283
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,178评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,824评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,264评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,788评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,913评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,535评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,130评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,102评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,334评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,298评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,622评论 2 343

推荐阅读更多精彩内容