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

本文涉及的产品
传统型负载均衡 CLB,每月750个小时 15LCU
网络型负载均衡 NLB,每月750个小时 15LCU
日志服务 SLS,月写入数据量 50GB 1个月
简介:

0.说明


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

wKiom1i8K-6hUk3bAAA4KDrPhKQ340.png

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

    下面介绍的是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的方式进行上网时虚拟机、宿主机之间的网络连接关系可如下所示:

wKioL1i8uLvBJKr4AABzByftaZ4557.png

    

    关于为什么网络拓扑结构是这样的,这里不展开说明,可以参考博主的另一篇博文《在实践中深入理解VMware虚拟机的上网模式NAT模式》,这篇文章深入地分析了VMware虚拟机使用NAT模式上网时的网络结构细节,相信看完这篇文章后,这里搭建Nginx的实验环境也就很容易理解了。

    所以首先,应该是自己先配置好网络环境,让宿主机跟我们的虚拟机可以通信,实际上,如果理解了VMware虚拟机上网方式的原理,同时对CentOS的网络配置也很熟悉,这一步是可以很轻松完成的,这里就不给出过程了,这里所用的IP地址跟上面的图示是一样的。

    这里,对于Nginx的负载均衡,希望达到的效果逻辑如下:

wKiom1i8uWmSSgZLAABNqTHI_cs056.png

    当用户访问我们的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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
[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;
     }
}
  • 添加相应的站点目录和内容

1
2
3
4
[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解析

1
2
3
[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
  • 检查配置文件与启动

1
2
3
4
[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
  • 本机上进行测试

1
2
[root@web01 bbs] # curl bbs.xpleaf.org
bbs.xpleaf.org node1 10.0.0.9


(2)web02配置与测试


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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
[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;
     }
}
  • 添加相应的站点目录和内容

1
2
3
4
[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解析

1
2
3
[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
  • 检查配置文件与启动

1
2
3
4
[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
  • 本机上进行测试

1
2
[root@web02 bbs] # curl bbs.xpleaf.org
bbs.xpleaf.org node2 10.0.0.10


(3)lb01配置


  • 配置文件内容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
[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解析

1
2
3
[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
  • 检查配置文件与启动

1
2
3
4
[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上进行测试,如下:

1
2
3
4
5
6
7
8
9
10
11
12
[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文件中):

wKiom1i8wwXAcmqBAAB8Bwp3a4k280.png

wKiom1i8wwWSoVoRAAB7phWSidw239.png




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


(1)原理

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

1
2
3
[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服务器节点时,配置的日志格式是这样的:

1
2
3
     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负载均衡服务器上做如下配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
[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服务器上查看日志信息:

1
2
3
[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负载均衡服务器上增加下面一行配置:

1
proxy_set_header Host $host;

    此时配置文件内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
[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配置修改为如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
[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,看起来就会觉得很熟悉了。

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

1
2
3
4
5
6
7
8
主要有rr、wrr、ip_hash
(1)rr轮询
如果节点服务器不宕机,请求将会平均分发到各节点服务器上;
(2)wrr权重轮询
按照设置的weight权重,将请示按比例分发到各节点服务器上;
(3)ip_hash
按照客户端IP的 hash 结果分配;
可以解决动态网页的session共享问题(会话保持),但无法保证1:1的负载均衡;
  • 动态调度算法:负载均衡器会根据后端节点的当前状态来决定是否分发请求

1
2
3
4
5
6
7
8
9
10
11
主要有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负载均衡的理解,同时也在实际场景中多分析和尝试使用。




本文转自 xpleaf 51CTO博客,原文链接:http://blog.51cto.com/xpleaf/1903565,如需转载请自行联系原作者

相关文章
|
1月前
|
应用服务中间件 Linux 网络安全
Centos 8.0中Nginx配置文件和https正书添加配置
这是一份Nginx配置文件,包含HTTP与HTTPS服务设置。主要功能如下:1) 将HTTP(80端口)请求重定向至HTTPS(443端口),增强安全性;2) 配置SSL证书,支持TLSv1.1至TLSv1.3协议;3) 使用uWSGI与后端应用通信(如Django);4) 静态文件托管路径设为`/root/code/static/`;5) 定制错误页面(404、50x)。适用于Web应用部署场景。
430 87
|
1月前
|
负载均衡 应用服务中间件 nginx
Nginx配置与命令
Nginx 是一款高性能的 HTTP 和反向代理服务器,其配置文件灵活且功能强大。本文介绍了 Nginx 配置的基础结构和常用指令,包括全局块、Events 块、HTTP 块及 Server 块的配置方法,以及静态资源服务、反向代理、负载均衡、HTTPS 和 URL 重写等功能实现。此外,还提供了常用的 Nginx 命令操作,如启动、停止、重载配置和日志管理等,帮助用户高效管理和优化服务器性能。
|
19天前
|
Linux
Linux下版本控制器(SVN) -服务器端环境搭建步骤
Linux下版本控制器(SVN) -服务器端环境搭建步骤
37 0
Linux下版本控制器(SVN) -服务器端环境搭建步骤
|
1月前
|
负载均衡 前端开发 应用服务中间件
Tomcat的负载均衡和动静分离(与nginx联动)
总的来说,负载均衡和动静分离是提高Web应用性能的两个重要手段。通过合理的配置和使用,我们可以让Web应用更好地服务于用户。
103 21
|
1月前
|
负载均衡 Java 应用服务中间件
Tomcat与Nginx的负载均衡与动静分离技巧
总的来说,Tomcat和Nginx各有各的优点,在负载均衡和动静分离这两方面它们都有很好的应用。灵活使用这两个工具能够让Web应用具有更好的扩展性和用户体验。
82 14
|
1月前
|
负载均衡 前端开发 JavaScript
LVS-DR模式、keepalived、Nginx与Tomcat合作,打造动静分离,高效负载均衡与高可用性
为了采用这样的架构,你需要对LVS-DR、Keepalived、Nginx与Tomcat有一定的理解和掌握,同时也需要投入一些时间去研究和配置,但是一旦你把它运行起来,你将会发现,这一切都是值得的。
92 11
|
3月前
|
应用服务中间件 nginx
Nginx进程配置指令详解
Nginx进程配置指令主要包括:`worker_processes`设置工作进程数;`worker_cpu_affinity`绑定CPU核心;`worker_rlimit_nofile`设置最大文件描述符数量;`worker_priority`设置进程优先级;`worker_connections`设置最大连接数;`daemon`控制守护进程模式;`master_process`启用主进程模式;`pid`设置PID文件路径;`user`指定用户和组;`error_log`配置错误日志。这些指令在`nginx.conf`中配置,用于优化和控制Nginx的运行行为。
183 10
|
3月前
|
Ubuntu 应用服务中间件 网络安全
Nginx伪流媒体服务器搭建详细说明以及案例
Nginx伪流媒体服务器搭建步骤如下:1. 安装Nginx,根据系统选择命令;2. 编辑配置文件(/etc/nginx/nginx.conf),添加mp4相关设置;3. 创建视频目录/usr/share/nginx/html/videos并上传视频;4. 重启Nginx应用更改;5. 通过浏览器访问视频,如http://your_server_ip/videos/example.mp4。注意启用mp4模块,确保视频格式支持伪流媒体播放。
119 7
|
3月前
|
负载均衡 算法 应用服务中间件
Nginx长连接负载均衡详细说明以及案例
本文详细介绍了Nginx长连接负载均衡的配置与原理。长连接(Keepalive)允许客户端和服务器保持连接,减少建立和关闭连接的开销。Nginx支持多种负载均衡算法,如轮询、IP哈希等。通过在Nginx配置文件中使用`upstream`模块和`keepalive`指令,可以实现长连接负载均衡,从而提高系统的性能和响应速度。示例配置展示了如何设置后端服务器组、长连接数及HTTP/1.1协议,确保连接复用,降低延迟。
222 5
|
3月前
|
负载均衡 应用服务中间件 nginx
如何使用nginx实现负载均衡?
如何使用nginx实现负载均衡?

热门文章

最新文章