Nginx反向代理与负载均衡:节点服务器单/多虚拟机配置+实验环境搭建+原理解析
0.说明
常见的集群架构及相关软件,可以参考下面的导图:
互联网企业常用的是负载均衡集群和高可用性集群,负载均衡集群强调“分担”,通过一定的调度算法 ,可以实现用多个节点服务器来分担用户的访问请求和数据流量;高可用性集群强调“高可用”,即一个节点失效了,它的任务可以立刻转移到另一个备份的节点上(即一般通过设置主备来实现)。显然因为负载均衡集群使用多个节点来分担服务,即使其中一个节点失效了,其它节点也可以继续工作,因此它也具有高可用性。
下面介绍的是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负载均衡的理解,同时也在实际场景中多分析和尝试使用。
8.参考资料
《跟老男孩学Linux运维:Web集群实战》

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
使用Powershell管理Linux 下的 SQL Server
使用Powershell管理Linux 下的 SQL Server 我们上一篇文章介绍了在Centos 7.3下安装及配置 SQL Server,今天我们主要介绍的是如何在Windows下使用Powershell来管理Linux下的SQL Server,其实说到Powershell大家都已经很熟悉了,Powershell不止是命令集合也是批量程序,可以很好的协助管理员提高日常的运维工作,但是微软的Powershell有一个毛病就是不同的服务需要安装不同的Powershell,对于Lync下的Shell、Exchange Shell和系统自带的Powershell就有很大的区别,另外还有今天我们介绍的内容使用Powershell管理SQL Server,需要安装单独的SSMS才可以使用powershell导出sql的模块,如果使用系统再带的Powershell导入sqlserver模块的话会提示错误,希望后期微软能彻底解决这个问题。好了不多说了,言归正传,开始我们今天的介绍; 我们首先得知,SQL Powershell 包含在 SQL Server Manager Studio上的,所以...
- 下一篇
如何做SQL Server性能测试?
对于DBA来讲,我们都会做新服务器的性能测试。我会从TPC的基准测试入手,使用HammerDB做整体性能评估(前身是HammerOra),跟厂商数据对比。再使用DiskSpd针对性的测试磁盘IO性能指标(前身是SQLIO),再到SQLIOSIM测试存储的完整性,再到ostress并发压力测试,对于数据库服务器迁移,我们还会收集和回放Profiler Trace,并收集期间关键性能计数器做对比。 下面我着重谈谈使用HammerDB的TPC-C来做SQL Server基准测试。 自己写负载测试代码很困难 为了模拟数据库的负载,你想要有多个应用程序用户和混合数据读写的语句。你不想总是对单一行更新相同的值,或者只是重复插入假的值。 自己动手使用Powershell、C#等语言写负载测试脚本也不是不可能,只是太消耗时间,你需要创建或者恢复数据库,并做对应的测试。 免费而简单的压测SQL Server:使用HammerDB模拟OLTP数据库负载 HammerDB是一个免费、开源的工具,允许你针对SQL Server、Oracle、MySQL和PostgreSQL等运行TPC-C和TPC-H基准测试...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- 2048小游戏-低调大师作品
- Mario游戏-低调大师作品
- Windows10,CentOS7,CentOS8安装MongoDB4.0.16
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
- CentOS8编译安装MySQL8.0.19
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7
- CentOS8安装Docker,最新的服务器搭配容器使用
- CentOS7,8上快速安装Gitea,搭建Git服务器
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池