Linux实战教学笔记30:Nginx反向代理与负载均衡应用实践 4年前

1.1 集群简介

1.2 为什么要使用集群

(1)高性能

假如你配一个LNMP环境,每次只需要服务10个并发请求,那么单台服务器一定会比多个服务器集群要快。只有当并发或总请求数量超过单台服务器的承受能力时,服务器集群才会体现出优势。

(2)价格有效性

(3)可伸缩性

当服务负载,压力增长时,针对集群系统进行较简单的扩展即可满足需求,且不会降低服务质量。

(4)高可用性

  • 集群架构技术可以使得系统在若干硬件设备故障发生时仍可以继续工作,这样就将系统的停机时间减少到了最小。集群系统在提高系统可靠性的同时,也大大减小了系统故障带来的业务损失,目前几乎100%的互联网网站都要求7*24小时提供服务。

(5)透明性

(6)可管理性

(7)可编程性

1.3 集群的常见分类

1.3.1 集群的常见分类

计算机集群架构按功能和结构可以分成以下几类:

  • 负载均衡集群,简称LBC或者LB
  • 高可用性集群,简称HAC
  • 高性能计算集群,简称HPC
  • 网格计算集群

提示:
负载均衡集群和高可用性集群是互联网行业常用的集群架构模式,也是我们要学习的重点。

1.3.2 不同种类的集群介绍

(1)负载均衡集群

负载均衡集群的作用为:

  • 分摊用户访问请求及数据流量(负载均衡)
  • 保持业务连续性,即7*24小时服务(高可用性)。
  • 应用于Web业务及数据库从库等服务器的业务

负载均衡集群典型的开源软件包括LVS,Nginx,Haproxy等。如下图所示:

提示:
不同的业务会有若干秒的切换时间,DB业务明显长于Web业务切换时间。

(2)高可用性集群

高可用性集群的作用为:

  • 当一台机器宕机时,另外一台机器接管宕机的机器的IP资源和服务资源,提供服务。
  • 常用于不易实现负载均衡的应用,比如负载均衡器,主数据库,主存储对之间。

高可用性集群常用的开源软件包括Keepalived,Heartbeat等,其架构图如下图所示:

(3)高性能计算集群

(4)网格计算集群

特别提示:
在互联网网站运维中,比较常用的就是负载均衡集群和高可用性集群

1.4 常用的集群软硬件介绍及选型

1.4.1 企业运维中常见的集群软硬件产品

互联网企业常用的开源集群软件有:Nginx,LVS,Haproxy,Keepalived,heartbeat。

互联网企业常用的商业集群硬件有:F5,Netscaler,Radware,A10等,工作模式相当于Haproxy的工作模式。

淘宝,赶集网,新浪等公司曾使用过Netscaler负载均衡产品。集群硬件Netscaler的产品图如下图所示:

集群硬件F5产品如下图所示:

1.4.2 对于集群软硬件产品如何选型

下面是我对同学们的基本选择建议,更多的建议等大家学完负载均衡内容后再细分讲解。

  • 当企业业务重要,技术力量又薄弱,并且希望出钱购买产品及获取更好的服务时,可以选择硬件负载均衡产品,如F5,Netscaler,Radware等,此类公司多为传统的大型非互联网企业,如银行,证券,金融业及宝马,奔驰公司等
  • 对于门户网站来说,大多会并用软件及硬件产品来分担单一产品的风险,如淘宝,腾讯,新浪等。融资了的企业会购买硬件产品,如赶集等网站。
  • 中小型互联网企业,由于起步阶段无利润可赚或者利润很低,会希望通过使用开源免费的方案来解决问题,因此会雇佣专门的运维人员进行维护。例如:51CTO等

1.4.3 如何选择开源集群软件产品

1.5 Nginx负载均衡集群介绍

1.5.1 搭建负载均衡服务的需求

负载均衡集群提供了一种廉价,有效,透明的方法,来扩展网络设备和服务器的负载,带宽和吞吐量,同时加强了网络数据处理能力,提高了网络的灵活性和可用性。

搭建负载均衡服务的需求如下:

(1)把单台计算机无法承受的大规模并发访问或数据流量分担到多台节点设备上,分别进行处理,减少用户等待响应的时间,提升用户体验。
(2)单个重负载的运算分担到多台节点设备上做并行处理,每个节点设备处理结束后,将结果汇总,返回给用户,系统处理能力得到大幅度提高。
(3)7*24小时的服务保证,任意一个或多个有限后面节点设备宕机,不能影响业务。

1.5.2 Nginx负载均衡集群介绍

(1)反向代理与负载均衡概念简介

(2)实现Nginx负载均衡的组件说明

实现Nginx负载均衡的组件主要有两个,如下表:

1.6 快速实践Nginx负载均衡环境准备

上图是快速实践Nginx负载均衡的逻辑架构图

在上图中,所有用户的请求统一发送到Nginx负载均衡器,然后由负载均衡器根据调度算法来请求Web01和Web02

1.6.1 软硬件准备

(1)硬件准备

准备4台VM虚拟机(有物理服务器更佳),两台做负载均衡,两台做RS,如下表:

HOSTNAME

IP

说明

lb01

192.168.0.221

Nginx主负载均衡器

lb02

192.168.0.222

Nginx副负载均衡器

web01

192.168.0.223

Web01服务器

web02

192.168.0.224

Web02服务器

(2)软件准备

系统:CentOS6.5 x86_64
软件:nginx-1.10.2.tar.gz

1.6.2 安装Nginx软件

(1)安装依赖软件包命令集合。

[root@localhost ~]# yum -y install openssl openssl-devel pcre pcre-devel
[root@localhost ~]# rpm -qa openssl openssl-devel pcre pcre-devel

(2)安装Nginx软件包命令集合

[root@localhost ~]# tar xf nginx-1.10.2.tar.gz -C /usr/src/
[root@localhost ~]# cd /usr/src/nginx-1.10.2/
[root@localhost nginx-1.10.2]# useradd -M -s /sbin/nologin nginx [root@localhost nginx-1.10.2]# ./configure --user=nginx --group=nginx --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module && make && make install [root@localhost nginx]# ln -s /usr/local/nginx/sbin/* /usr/local/sbin/

1.6.3 配置用于测试的Web服务

[root@localhost nginx]# cat conf/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.yunjisuan.com; location / { root html/bbs; index index.html index.htm; } access_log logs/access_bbs.log main; } server { listen 80; server_name www.yunjisuan.com; location / { root html/www; index index.html index.htm; } access_log logs/access_www.log main; } } #提示: 这里故意将www虚拟主机放在下面,便于用后面的参数配置测试效果

配置完成后检查语法,并启动Nginx服务

[root@localhost nginx]# /usr/local/nginx/sbin/nginx 
[root@localhost nginx]# netstat -antup | grep nginx
tcp        0      0 0.0.0.0:80 0.0.0.0:* LISTEN 4100/nginx

然后填充测试文件数据,如下:

[root@localhost nginx]# mkdir /usr/local/nginx/html/{www,bbs}
[root@localhost nginx]# echo "`hostname -I `www" >> /usr/local/nginx/html/www/index.html
[root@localhost nginx]# cat /usr/local/nginx/html/www/index.html
192.168.0.223 www
[root@localhost nginx]# echo "`hostname -I `bbs" >> /usr/local/nginx/html/bbs/index.html [root@localhost nginx]# cat /usr/local/nginx/html/bbs/index.html 192.168.0.223 bbs #提示: 以上操作命令,在Web01上和Web02上是一样的

配置解析Web01的IP和主机名后,用curl测试一下

[root@localhost nginx]# tail -2 /etc/hosts
192.168.0.223 www.yunjisuan.com
192.168.0.223 bbs.yunjisuan.com
[root@localhost nginx]# curl www.yunjisuan.com 192.168.0.223 www [root@localhost nginx]# curl bbs.yunjisuan.com 192.168.0.223 bbs

配置解析Web02的IP和主机名后,用curl测试一下

[root@localhost nginx]# vim /etc/hosts
[root@localhost nginx]# tail -2 /etc/hosts
192.168.0.224 www.yunjisuan.com 192.168.0.224 bbs.yunjisuan.com [root@localhost nginx]# curl www.yunjisuan.com 192.168.0.224 www [root@localhost nginx]# curl bbs.yunjisuan.com 192.168.0.224 bbs

提示:
(1)不同Web测试节点,返回的结果是不同的,这是为了方便测试演示!
(2)通过上面配置就实现了两台Web服务器基于域名的虚拟主机配置。

1.6.4 实现一个简单的负载均衡

HOSTNAME

IP

说明

lb01

192.168.0.221

Nginx主负载均衡器

[root@lb01 nginx]# cat conf/nginx.conf
worker_processes  1;
events {
    worker_connections  1024;
}
http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on; keepalive_timeout 65; upstream www_server_pools { #这里定义Web服务器池,包含了223,224两个Web节点 server 192.168.0.223:80 weight=1; server 192.168.0.224:80 weight=1; } server { #这里定义代理的负载均衡域名虚拟主机 listen 80; server_name www.yunjisuan.com; location / { proxy_pass http://www_server_pools; #访问www.yunjisuan.com,请求发送给www_server_pools里面的节点 } } }

现在检查语法并启动。命令如下:

[root@lb01 nginx]# nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
[root@lb01 nginx]# /usr/local/nginx/sbin/nginx
[root@lb01 nginx]# netstat -antup | grep nginx tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 4105/nginx

然后,检查负载均衡测试结果。Linux作为客户端的测试结果如下:

[root@lb01 nginx]# hostname -I
192.168.0.221 
[root@lb01 nginx]# tail -1 /etc/hosts 192.168.0.221 www.yunjisuan.com #这里是lb1负载均衡器IP [root@lb01 nginx]# curl www.yunjisuan.com 192.168.0.223 bbs [root@lb01 nginx]# curl www.yunjisuan.com 192.168.0.224 bbs [root@lb01 nginx]# curl www.yunjisuan.com 192.168.0.223 bbs [root@lb01 nginx]# curl www.yunjisuan.com 192.168.0.224 bbs [root@lb01 nginx]# curl www.yunjisuan.com 192.168.0.223 bbs [root@lb01 nginx]# curl www.yunjisuan.com 192.168.0.224 bbs [root@lb01 nginx]# curl www.yunjisuan.com 192.168.0.223 bbs [root@lb01 nginx]# curl www.yunjisuan.com 192.168.0.224 bbs
[root@lb01 nginx]# curl www.yunjisuan.com 192.168.0.223 bbs [root@lb01 nginx]# curl www.yunjisuan.com 192.168.0.223 bbs [root@lb01 nginx]# curl www.yunjisuan.com 192.168.0.223 bbs [root@lb01 nginx]# curl www.yunjisuan.com 192.168.0.223 bbs [root@lb01 nginx]# curl www.yunjisuan.com 192.168.0.223 bbs
root@lb01 nginx]# curl www.yunjisuan.com
<html>
<head><title>502 Bad Gateway</title></head> <body bgcolor="white"> <center><h1>502 Bad Gateway</h1></center> <hr><center>nginx/1.10.2</center> </body> </html> [root@lb01 nginx]# curl www.yunjisuan.com <html> <head><title>502 Bad Gateway</title></head> <body bgcolor="white"> <center><h1>502 Bad Gateway</h1></center> <hr><center>nginx/1.10.2</center> </body> </html> [root@lb01 nginx]# curl www.yunjisuan.com <html> <head><title>502 Bad Gateway</title></head> <body bgcolor="white"> <center><h1>502 Bad Gateway</h1></center> <hr><center>nginx/1.10.2</center> </body> </html>
[root@lb01 nginx]# curl www.yunjisuan.com 192.168.0.223 bbs [root@lb01 nginx]# curl www.yunjisuan.com 192.168.0.224 bbs [root@lb01 nginx]# curl www.yunjisuan.com 192.168.0.223 bbs [root@lb01 nginx]# curl www.yunjisuan.com 192.168.0.224 bbs [root@lb01 nginx]# curl www.yunjisuan.com 192.168.0.223 bbs [root@lb01 nginx]# curl www.yunjisuan.com 192.168.0.224 bbs

1.7 Nginx负载均衡核心组件介绍

1.7.1 Nginx upstream模块

1.7.1.1 upstream模块介绍

1.7.1.2 upstream模块语法

upstream模块的语法相当简单,这里直接上范例给同学们讲。

范例1:基本的upstream配置案例

upstream www_server_pools {

#       upstream是关键字必须有,后面的www_server_pools为一个Upstream集群组的名字,可以自己起名,调用时就用这个名字

server 192.168.0.223:80 weight=5; server 192.168.0.224:80 weight=10; server 192.168.0.225:80 weight=15; # server关键字是固定的,后面可以接域名(门户会用)或IP。如果不指定端口,默认是80端口。weight代表权重,数值越大被分配的请求越多,结尾有分号,别忘了。 }

范例2:较完整的upstream配置案例

upstream blog_server_pool {

server 192.168.0.223;   #这行标签和下行是等价的
server 192.168.0.224:80 weight=1 max_fails=1 fail_timeout=10s; #这行标签和上一行是等价的,此行多余的部分就是默认配置,不写也可以。 server 192.168.0.225:80 weight=1 max_fails=2 fail_timeout=20s backup; # server最后面可以加很多参数,具体参数作用看下文的表格 }

范例3:使用域名及socket的upstream配置案例

upstream backend {

server backend1.example.com weight=5;
server backend2.example.com:8080; #域名加端口。转发到后端的指定端口上 server unix:/tmp/backend3; #指定socket文件 #提示:server后面如果接域名,需要内网有DNS服务器或者在负载均衡器的hosts文件做域名解析。 server 192.168.0.223; server 192.168.0.224:8080; server backup1.example.com:8080 backup; #备份服务器,等上面指定的服务器都不可访问的时候会启动,backup的用法和Haproxy中用法一样 server backup2.example.com:8080 backup; }

1.7.1.3 upstream模块相关说明

**upstream模块的内容应放于nginx.conf配置的http{}标签内,其默认调度节点算法是wrr(weighted round-robin,即权重轮询)**。下图为upstream模块内部server标签部分参数说明

提示:
以上参数与专业的Haproxy参数很类似,但不如Haproxy的参数易懂。

来看个示例,如下:

upstream backend {

server backend1.example.com weight=5; #如果就是单个Server,没必要设置权重
server 127.0.0.1:8080 max_fail=5 fail_timeout=10s; #当检测次数等于5的时候,5次连续检测失败后,间隔10s再重新检测。 server unix:/tmp/backend3; server backup1.example.com:8080 backup; #热备机器设置 }
upstream backend {

ip_hash;
server backend1.example.com;
server backend2.example.com;
server backend3.example.com down;
server backend4.example.com;

}

下面是Haproxy负载均衡器server标签的配置示例。

#开启对后端服务器的健康检测,通过GET /test/index.php来判断后端服务器的健康情况
server php_server_1 192.168.0.223:80 cookie 1 check inter 2000 rise 3 fall 3 weight 2 server php_server_2 192.168.0.224:80 cookie 2 check inter 2000 rise 3 fall 3 weight 1 server php_server_bak 192.168.0.225:80 cookie 3 check inter 1500 rise 3 fall 3 backup

1.7.1.4 upstream模块调度算法

下面介绍一下常见的调度算法。

(1) rr轮询(默认调度算法,静态调度算法)

(2)wrr(权重轮询,静态调度算法)

(3)ip_hash(静态调度算法)(会话保持)

我们来看一个示例,如下:

upstream yunjisuan_lb{

ip_hash;
server 192.168.0.223:80; server 192.168.0.224:8080; } upstream backend{ ip_hash; server backend1.example.com; server backend2.example.com; server backend3.example.com down; server backend4.example.com; }

注意:
当负载调度算法为ip_hash时,后端服务器在负载均衡调度中的状态不能有weight和backup,即使有也不会生效。

(4)fair(动态调度算法)

示例如下:

upstream yunjisuan_lb{

server 192.168.0.223;
server 192.168.0.224;
fair;

}

(5)least_conn

(6)url_hash算法(web缓存节点)

url_hash(web缓存节点)和ip_hash(会话保持)类似。示例配置如下:

upstream yunjisuan_lb {

server squid1:3128;
server squid2:3128; hash $request_uri; hash_method crc32; }

(7)一致性hash算法

http {
upstream test {

consistent_hash $request_uri;
server 127.0.0.1:9001 id=1001 weight=3; server 127.0.0.1:9002 id=1002 weight=10; server 127.0.0.1:9003 id=1003 weight=20; } }

虽然Nginx本身不支持一致性hash算法,但Nginx得分支Tengine支持。详细可参考http://tengine.taobao.org/document\_cn/http\_upstream\_consistent\_hash\_cn.html

1.7.2 http_proxy_module模块

1.7.2.1 proxy_pass指令介绍

下面proxy_pass的使用案例:

(1)将匹配URI为name的请求抛给http://127.0.0.1/remote/.

location /name/ {

proxy_pass http://127.0.0.1/remote/;

}

(2)将匹配URI为some/path的请求抛给http://127.0.0.1

location /some/path/ {

proxy_pass http://127.0.0.1;

}

(3)将匹配URI为name的请求应用指定的rewrite规则,然后抛给http://127.0.0.1

location /name/ {

rewrite /name/( [^/]+ )  /username=$1 break;
proxy_pass http://127.0.0.1; }

1.7.2.2 http proxy模块参数

1.8 Nginx负载均衡配置实战(上接1.6节)

主机名

IP地址

角色说明

lb01

192.168.0.221

nginx主负载均衡

lb02

192.168.0.222

nginx从负载均衡

Web01

192.168.0.223

nginx web01服务器

Web02

192.168.0.224

nginx web02服务器

1.8.1 查看lb01的配置文件如下:

[root@lb01 nginx]# cat /usr/local/nginx/conf/nginx.conf
worker_processes  1;
events {
    worker_connections  1024;
}
http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on; keepalive_timeout 65; upstream www_server_pools { #默认调度算法wrr,即权重轮询算法 #虽然定义的www服务器池但是这个服务器池也可以作为BBS等业务的服务器池。因为节点服务器的虚拟主机都是根据访问的主机头字段区分的。 server 192.168.0.223:80 weight=1; server 192.168.0.224:80 weight=1; } server { listen 80; server_name www.yunjisuan.com; location / { proxy_pass http://www_server_pools; #通过proxy_pass功能把用过户的请求交给上面反向代理upstream定义的www_server_pools服务器池处理。 } } }

现在配置hosts解析到代理服务器lb01上,重新加载服务,访问测试:

[root@lb01 nginx]# tail -2 /etc/hosts
192.168.0.221 www.yunjisuan.com
192.168.0.221 bbs.yunjisuan.com [root@lb01 nginx]# /usr/local/nginx/sbin/nginx -s reload [root@lb01 nginx]# curl www.yunjisuan.com 192.168.0.223 bbs [root@lb01 nginx]# curl www.yunjisuan.com 192.168.0.224 bbs

1.8.2 反向代理多虚拟主机节点服务器企业案例

proxy_set_header host $host;

[root@lb01 nginx]# cat /usr/local/nginx/conf/nginx.conf
worker_processes  1;
events {
    worker_connections  1024;
}
http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    keepalive_timeout  65;
    upstream www_server_pools {

    server 192.168.0.223:80 weight=1; server 192.168.0.224:80 weight=1; } server { listen 80; server_name www.yunjisuan.com; location / { proxy_pass http://www_server_pools; proxy_set_header host $host; #在代理向后端服务器发送的http请求头中加入host字段信息,用于当后端服务器配置有多个虚拟主机时,可以识别代理的是哪个虚拟主机。这是节点服务器多虚拟主机时的关键配置。 } } }

此时,再重新加载Nginx服务,并用curl测试检查,结果如下:

[root@lb01 nginx]# /usr/local/nginx/sbin/nginx -s reload
[root@lb01 nginx]# curl www.yunjisuan.com
192.168.0.223 www [root@lb01 nginx]# curl www.yunjisuan.com 192.168.0.224 www

可以看到这次访问的结果和访问的域名就完全对应上了,这样代理多虚拟主机的节点服务器就不会出问题了

1.8.3 经过反向代理后的节点服务器记录用户IP企业案例

例如:使用任意windows客户端计算机,访问已经解析好代理IP的www.yunjisuan.com后,去节点服务器www服务日志查看,就会发现如下日志:

[root@web01 ~]# tail -2 /usr/local/nginx/logs/access_www.log
192.168.0.221--[27/Jul/2017:04:05:22 -0400]"GET / HTTP/1.0"200 18 "-""curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.14.0.0 zlib/1.2.3 libidn/1.18 libssh2/1.4.2""-" 192.168.0.221--[27/Jul/2017:04:33:06 -0400]"GET / HTTP/1.0"200 18 "-""curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.14.0.0 zlib/1.2.3 libidn/1.18 libssh2/1.4.2""-"
proxy_set_header X-Forwarded-For $remote_addr;
#这是反向代理时,节点服务器获取用户真实IP的必要功能配置

解决上述问题的整个Nginx代理配置为:

[root@lb01 nginx]# cat /usr/local/nginx/conf/nginx.conf
worker_processes  1;
events {
    worker_connections  1024;
}
http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    keepalive_timeout  65; upstream www_server_pools { server 192.168.0.223:80 weight=1; server 192.168.0.224:80 weight=1; } server { listen 80; server_name www.yunjisuan.com; location / { proxy_pass http://www_server_pools; proxy_set_header host $host; proxy_set_header X-Forwarded-For $remote_addr; #在代理向后端服务器发送的http请求头中加入X-Forwarded-For字段信息,用于后端服务器程序,日志等接收记录真实用户的IP,而不是代理服务器的IP } } }

重新加载Nginx反向代理服务:

[root@lb01 nginx]# /usr/local/nginx/sbin/nginx -s reload

[root@web01 ~]# cat /usr/local/nginx/conf/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"'; #就是这里的“$http_x_forwarded_for”参数,如果希望在第一行显示,可以替换掉第一行的$remote_addr变量。 server { listen 80; server_name bbs.yunjisuan.com; location / { root html/bbs; index index.html index.htm; } access_log logs/access_bbs.log main; } server { listen 80; server_name www.yunjisuan.com; location / { root html/www; index index.html index.htm; } access_log logs/access_www.log main; } } #注意:这里是客户端Web01的配置

此时,再去节点服务器WWW服务的访问日志里查看,会发现日志的结尾已经变化了:

[root@web01 ~]# tail -2 /usr/local/nginx/logs/access_www.log 
192.168.0.221--[27/Jul/2017:05:11:22 -0400]"GET / HTTP/1.0"200 18 "-""Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 10.0; WOW64; Trident/7.0; .NET4.0C; .NET4.0E; .NET CLR 2.0.50727; .NET CLR 3.0.30729; .NET CLR 3.5.30729)""192.168.0.110" 192.168.0.221--[27/Jul/2017:05:11:23 -0400]"GET / HTTP/1.0"200 18 "-""Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 10.0; WOW64; Trident/7.0; .NET4.0C; .NET4.0E; .NET CLR 2.0.50727; .NET CLR 3.0.30729; .NET CLR 3.5.30729)""192.168.0.110"

1.8.4 与反向代理配置相关的更多参数说明

相信同学们对这些参数有了一定了解了,由于参数众多,最好把这些参数放到一个配置文件里,然后用include方式包含到虚拟主机配置里,效果如下:

[root@lb01 conf]# cat /usr/local/nginx/conf/nginx.conf
worker_processes  1;
events {
    worker_connections  1024;
}
http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    keepalive_timeout  65;
    upstream www_server_pools {

    server 192.168.0.223:80 weight=1; server 192.168.0.224:80 weight=1; } server { listen 80; server_name www.yunjisuan.com; location / { proxy_pass http://www_server_pools; include proxy.conf; #这就是包含的配置,具体配置内容见下文 } } } [root@lb01 conf]# cat proxy.conf proxy_set_header host $host; proxy_set_header x-forwarded-for $remote_addr; proxy_connect_timeout 60; proxy_send_timeout 60; proxy_read_timeout 60; proxy_buffer_size 4k; proxy_buffers 4 32k; proxy_busy_buffers_size 64k; proxy_temp_file_write_size 64k;

更多Nginx反向代理参数说明
http://nginx.org/en/docs/http/ngx_http_proxy_module.html

1.8.3 根据URL中的目录地址实现代理转发

1.8.3.1 根据URL中的目录地址实现代理转发的说明

案例背景:
通过Nginx实现动静分离,即通过Nginx反向代理配置规则实现让动态资源和静态资源及其他业务分别由不同的服务器解析,以解决网站性能,安全,用户体验等重要问题。

下图为企业常见的动静分离集群架构图,此架构图适合网站前端只使用同一个域名提供服务的场景,例如,用户访问的域名是www.yunjisuan.com,然后,当用户请求www.yunjisuan.com/upload/xx地址时候,代理会分配请求到上传服务器池处理数据;当用户请求www.yunjisuan.com/static/xx地址的时候,代理会分配请求到静态服务器池请求数据;当用户请求www.yunjisuan.com/xx地址的时候,即不包含上述指定的目录地址路径时,代理会分配请求到默认的动态服务器池请求数据(注意:上面的xx表示任意路径)。

1.8.3.2 准备:案例配置实战

先进行企业案例需求梳理:

了解了需求后,就可以进行upstream模块服务器池的配置了。

#static_pools为静态服务器池,有一个服务器,地址为192.168.0.223,端口为80.

upstream static_pools {

server 192.168.0.223:80 weght=1; } #upload_pools为上传服务器池,有一个服务器地址为192.168.0.224,端口为80. upstream upload_pools { server 192.168.0.224:80 weight=1; } #default_pools为默认的服务器池,即动态服务器池,有一个服务器,地址为192.168.0.225,端口为80. upstream default_pools { server 192.168.0.225:80 weight=1; } #提示:需要增加一台测试Web节点Web03(ip:192.168.0.225),配置与Web01,Web02一样。

方案1:以location方案实现

#将符合static的请求交给静态服务器池static_pools,配置如下:
location /static/ {

proxy_pass http://static_pools;
include proxy.conf;

}

#将符合upload的请求交给上传服务器池upload_pools,配置如下: location /upload/ { proxy_pass http://upload_pools; include proxy.conf; } #不符合上述规则的请求,默认全部交给动态服务器池default_pools,配置如下: location / { proxy_pass http://default_pools; include proxy.conf; }

方案2:以if语句实现。

if ($request_uri ~* "^/static/(.*)$")
{
proxy_pass http://static_pools/$1; } if ($request_uri ~* "^/upload/(.*)$") { proxy_pass http://upload_pools/$1; } location / { proxy_pass http://default_pools; include proxy.conf; }

下面以方案1为例进行讲解,Nginx反向代理的实际配置如下:

[root@lb01 ~]# cat /usr/local/nginx/conf/nginx.conf
worker_processes  1;
events {
    worker_connections  1024;
}
http {
    include mime.types; default_type application/octet-stream; sendfile on; keepalive_timeout 65; upstream static_pools { server 192.168.0.223:80 weight=1; } upstream upload_pools { server 192.168.0.224:80 weight=1; } upstream default_pools { server 192.168.0.225:80 weight=1; } server { listen 80; server_name www.yunjisuan.com; location / { proxy_pass http://default_pools; include proxy.conf; } location /static/ { proxy_pass http://static_pools; include proxy.conf; } location /upload/ { proxy_pass http://upload_pools; include proxy.conf; } } }

重新加载配置生效,如下:

[root@lb01 ~]# /usr/local/nginx/sbin/nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful [root@lb01 ~]# /usr/local/nginx/sbin/nginx -s reload
[root@web01 ~]# cd /usr/local/nginx/html/www/
[root@web01 www]# mkdir static
[root@web01 www]# echo "static_pools" >> static/index.html
[root@web01 www]# curl http://www.yunjisuan.com/static/index.html      #这里的www.yunjisuan.com是解析过的Web01的本地IP
static_pools

#提示:测试的静态地址为http://www.yunjisuan.com/static/index.html,注意,是带static路径的地址。
[root@web02 ~]# cd /usr/local/nginx/html/www/
[root@web02 www]# mkdir upload
[root@web02 www]# echo "upload_pools" >> upload/index.html
[root@web02 www]# curl http://www.yunjisuan.com/upload/index.html      #这里的www.yunjisuan.com是解析过的Web02的本地IP
upload_pools

#提示:测试的上传地址为http://www.yunjisuan.com/upload/index.html,注意,是带upload路径的地址。
[root@web03 www]# cd /usr/local/nginx/html/www
[root@web03 www]# echo "default_pools" >> index.html
[root@web03 www]# curl http://www.yunjisuan.com
default_pools

节点

IP及端口

测试地址

字符串为代表业务

web01

192.168.0.223:80

http://www.yunjisuan.com/static/index.html

static_pools

web02

192.168.0.224:80

http://www.yunjisuan.com/upload/index.html

upload_pools

web03

192.168.0.225:80

http://www.yunjisuan.com

default_pools

1.8.3.3 根据URL目录地址转发的应用场景

1.8.4 根据客户端的设备(user_agent)转发实践需求

1.8.4.1 根据客户端的设备(user_agent)转发实践需求

(1)常规4层负载均衡解决方案架构

(2)第7层负载均衡解决方案

下面我们就来讲解此方案,下图描述了上述解决方案相应的架构逻辑图

1.8.4.2 根据客户端设备(user_agent)转发请求实践

location / {

if ($http_user_agent ~* "MSIE")
#如果请求的浏览器为微软IE浏览器(MSIE),则让请求由static_pools池处理 { proxy_pass http://static_pools; } if ($http_user_agent ~* "Chrome") #如果请求的浏览器为谷歌浏览器(Chrome),则让请求由upload_pools池处理 { proxy_pass http://upload_pools; } proxy_pass http://default_pools; #其他客户端,由default_pools处理 include proxy.conf; }

除了针对浏览器外,上述“$http_user_agent”变量也可针对移动端,比如安卓,苹果,Ipad设备进行匹配,去请求指定的服务器,具体细节配置如下:

location / {
if ($http_user_agent ~* "android")
{
proxy_pass http://android_pools; #这里是android服务器池 } if ($http_user_agent ~* "iphone") { proxy_pass http://iphone_pools; #这里是iphone服务器池 } proxy_pass http://pc_pools; #这里是默认的pc服务器池 include extra/proxy.conf; }
192.168.0.110--[28/Jul/2017:02:12:10 -0400]"GET / HTTP/1.1"200 18 "-""Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 10.0; WOW64; Trident/7.0; .NET4.0C; .NET4.0E; .NET CLR 2.0.50727; .NET CLR 3.0.30729; .NET CLR 3.5.30729)""-" #PCwindows访问日志 192.168.0.106--[28/Jul/2017:02:12:22 -0400]"GET / HTTP/1.1"200 18 "-""Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_3 like Mac OS X) AppleWebKit/603.3.8 (KHTML, like Gecko) Version/10.0 Mobile/14G60 Safari/602.1""-" #苹果iphone6手机设备访问的日志。

1.8.5 根据文件扩展名实现代理转发

1.8.5.1 相关server配置

#先看看location方法的匹配规则,如下:

location ~ .*\.(gif|jpg|jpeg|png|bmp|swf|css|js)$ {

proxy_pass http://static_pools;
include proxy.conf; } #下面是if语句方法的匹配规则: if ($request_uri ~* ".*\.(php|php5)$") { proxy_pass http://php_server_pools; } if ($request_uri ~* ".*\.(jsp|jsp*|do|do*)$") { proxy_pass http://java_server_pools; }

1.8.5.2 根据扩展名转发的应用场景

location ~ .*\.(gif|jpg|jpeg|png|bmp|swf|css|js)$ {

proxy_pass http://static_pools;
include proxy.conf;

}

location ~ .*\.(php|php3|php5)$ { proxy_pass http://dynamic_pools; include proxy.conf }

1.9 Nginx负载均衡检测节点状态

(1)安装nginx_upstream_check_module模块

#系统已经安装了nginx-1.10.2软件
[root@lb01 ~]# /usr/local/nginx/sbin/nginx -V
nginx version: nginx/1.10.2

#下载补丁包 [root@lb01 ~]# wget https://codeload.github.com/yaoweibin/nginx_upstream_check_module/zip/master [root@lb01 ~]# unzip master [root@lb01 ~]# ls anaconda-ks.cfg install.log install.log.syslog master nginx-1.10.2.tar.gz nginx_upstream_check_module-master [root@lb01 nginx-1.10.2]# mv ~/nginx_upstream_check_module-master /usr/src/ #因为是对源程序打补丁,所以还需要Nginx源程序 [root@lb01 ~]# cd /usr/src/nginx-1.10.2/ [root@lb01 nginx-1.10.2]# patch -p0 < /usr/src/nginx_upstream_check_module-master/check_1.9.2+.patch patching file src/http/modules/ngx_http_upstream_hash_module.c patching file src/http/modules/ngx_http_upstream_ip_hash_module.c patching file src/http/modules/ngx_http_upstream_least_conn_module.c patching file src/http/ngx_http_upstream_round_robin.c patching file src/http/ngx_http_upstream_round_robin.h #备份源安装程序 [root@lb01 nginx-1.10.2]# cd /usr/local/ [root@lb01 local]# ls bin etc games include lib lib64 libexec nginx sbin share src [root@lb01 local]# mv nginx{,.ori} [root@lb01 local]# ls bin etc games include lib lib64 libexec nginx.ori sbin share src [root@lb01 local]# cd /usr/src/nginx-1.10.2/ #重新进行编译,编译的参数要和以前一致,最后加上 --add-module=/usr/src/nginx_upstream_check_module-master/ [root@lb01 nginx-1.10.2]# ./configure --prefix=/usr/local/nginx --user=nginx --group=nginx --with-http_ssl_module --with-http_stub_status_module --add-module=/usr/src/nginx_upstream_check_module-master/ [root@lb01 local]# /usr/local/nginx/sbin/nginx -V nginx version: nginx/1.10.2 built by gcc 4.4.7 20120313 (Red Hat 4.4.7-4) (GCC) built with OpenSSL 1.0.1e-fips 11 Feb 2013 TLS SNI support enabled configure arguments: --prefix=/usr/local/nginx --user=nginx --group=nginx --with-http_ssl_module --with-http_stub_status_module --add-module=/usr/src/nginx_upstream_check_module-master/ #拷贝源配置文件到当前Nginx的安装目录下 [root@lb01 local]# pwd /usr/local [root@lb01 local]# cp nginx.ori/conf/nginx.conf nginx/conf/ cp: overwrite `nginx/conf/nginx.conf'? y [root@lb01 local]# cp nginx.ori/conf/proxy.conf nginx/conf/ [root@lb01 local]# /usr/local/nginx/sbin/nginx -t nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful

(2)配置Nginx健康检查,如下:

[root@lb01 local]# cat nginx/conf/nginx.conf
worker_processes  1;
events {
    worker_connections  1024;
}
http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on; keepalive_timeout 65; upstream static_pools { server 192.168.0.223:80 weight=1; server 192.168.0.224:80 weight=1; check interval=3000 rise=2 fall=5 timeout=1000 type=http; #对static服务器池开启健康监测 } upstream default_pools { server 192.168.0.225:80 weight=1; } server { listen 80; server_name www.yunjisuan.com; location / { proxy_pass http://default_pools; include proxy.conf; } location ~ .*\.(gif|jpg|jpeg|png|bmp|swf|css|js)$ { proxy_pass http://static_pools; include proxy.conf; } location /status { check_status; #启动健康检查模块 access_log off; #关闭此location的访问日志记录 } } }

重启lb1的nginx服务

[root@lb01 local]# /usr/local/nginx/sbin/nginx 
[root@lb01 local]# netstat -antup | grep nginx
tcp        0 0 0.0.0.0:80 0.0.0.0:* LISTEN 7008/nginx #注意此处必须重启Nginx,不能重新加载

访问页面时,显示如下图所示:

在lb1配置文件的upstream default_pools{}里也加入健康监测命令,如下:

[root@lb01 local]# cat nginx/conf/nginx.conf
worker_processes  1;
events {
    worker_connections  1024;
}
http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on; keepalive_timeout 65; upstream static_pools { server 192.168.0.223:80 weight=1; server 192.168.0.224:80 weight=1; check interval=3000 rise=2 fall=5 timeout=1000 type=http; #对static服务器池开启健康监测 } upstream default_pools { server 192.168.0.225:80 weight=1; check interval=3000 rise=2 fall=5 timeout=1000 type=http; #对default服务器池开启健康监测 } server { listen 80; server_name www.yunjisuan.com; location / { proxy_pass http://default_pools; include proxy.conf; } location ~ .*\.(gif|jpg|jpeg|png|bmp|swf|css|js)$ { proxy_pass http://static_pools; include proxy.conf; } location /status { check_status; #启动健康检查模块 access_log off; #关闭此location的访问日志记录 } } }

再次访问健康监测页面时,显示如下图所示:

关闭任意一个RS节点后(3个Web服务器任选一个关闭nginx服务)

#关闭Web02的nginx服务
[root@web02 ~]# /usr/local/nginx/sbin/nginx -s stop

再次访问健康监测页面时,显示如下图所示:

1.10 proxy_next_upstream 参数补充

server {

listen 80;
server_name www.yunjisuan.com;
location / { proxy_pass http://static_pools; proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504; include proxy.conf; } }

1.11 本章重点回顾

  1. 集群的概念,分类,软硬件知识。
  2. upstream负载均衡模块知识
  3. http_proxy代理模块知识及相关参数
  4. 基于URI路径,user_agent,扩展名规则知识及实践案例。
  5. 监测Nginx代理下面节点的健康状态。

金牌IT职业再教育培训机构,欢迎来校资源。QQ:215379068

image
mambh-
没有什么永远。其实大家都知道这个事实。所以才祈祷着永远。比起最终要来的结束,人们总是期望着不会改变的永远。
4
发布数
0
关注者
6466
累计阅读

热门教程文档

C++
73小节
Rust
84小节
Kotlin
68小节
MyBatis
19小节
Lua
21小节
广告