Nginx的反向代理和负载均衡服务

Nginx (engine x) 是一个高性能的HTTP和反向代理服务,也是一款轻量级的Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,并在一个BSD-like 协议下发行。其特点是占有内存少,并发能力强,事实上nginx的并发能力确实在同类型的网页服务器中表现较好,在高连接并发的情况下,Nginx是Apache服务器不错的替代品,同时占用的资源很少,并兼容unix,linux,windows平台。中国大陆使用nginx网站用户有:百度、京东、新浪、网易、腾讯、淘宝等。

集群导语:

  简单地说,集群就是指一组(若干个)相互独立的计算机,利用高速通信网络组成的一个较大的计算机服务系统,每个集群节点(即集群中的每台计算机)都是运行各自服务的独立服器。这些服务器之间可以彼此通信,协同向用户提供应用程序、系统资源和数据,并以单一系统的模式加以管理。当用户客户机请求集群系统时,集群给用户的感觉就是一个单一独立的服务器,而实际上用户请求的是一组集群服务器。

  打开谷歌、百度的页面,看起来好简单,也许你觉得用几分钟就可以制作出相似的网页,而实际上,这个页面的背后是由成千上万台服务器集群协同工作的结果。而这么多的服务器维护和管理,以及相互协调工作也许就是读者你未来的工作职责了。

  若要用一句话描述集群,即一堆服务器合作做同一件事,这些机器可能需要整个技术团队架构、设计和统一协调管理,这些机器可以分布在一个机房,也可以分布在全国全球各个地区的多个机房。

集群的优势:高性能、价格有效性、可伸缩性、高可用性、透明性、可管理性、可编辑性

负载均衡软件:

L4:tcp负载均衡 1vs

Ll4-l7 Haproxy 反向代理

L7(http) Nginx

Nginx国内中小企业集群比较流行的负载均衡软件:严格来说叫反向代理。

反向代理:代替用户去请求内部服务器的节点

正向代理:代替内部用户去请求外部服务器的资源。

nginx反向代理负载均衡测试:

环境:centos 6.5 

nginx软件:nginx-1.6.3.tar

机器及ip规划:如下图 

主机 IP地址 作用
bqh-117 192.168.0.117 Web 01
bqh-118 192.168.0.118 Web 02
bqh-119 192.168.0.119 Web 03
bqh-lb-121 192.168.0.121 Nginx主.负载均衡器
bqh-lb-122 192.168.0.122 Nginx副.负载均衡器

现在我们需要在5台服务器上安装nginx:详情至 https://www.cnblogs.com/su-root/p/10177045.html

 下面以192.168.0.117机器上安装nginx软件为例:

[root@bqh-117 ~]# yum -y install make zlib zlib-devel gcc-c++ libtool  openssl openssl-devel pcre pcre-devel
[root@bqh-117 ~]# groupadd -r nginx
[root@bqh-117 ~]# useradd  –s /sbin/nologin -g nginx –M nginx
[root@bqh-117 ~]# wget -q http://nginx.org/download/nginx-1.6.3.tar.gz
[root@bqh-117 ~]# tar xf nginx-1.6.3.tar.gz
[root@bqh-117 ~]# cd nginx-1.6.3
[root@bqh-117 ~]#./configure --prefix=/application/nginx-1.6.3 --user=nginx --group=nginx --with-http_ssl_module --with-http_stub_status_module
[root@bqh-117 ~]# make
[root@bqh-117 ~]# make install
[root@bqh-117 ~]# ln -s /application/nginx-1.6.3/ /application/nginx

配置nginx.conf文件(3台Web服务器)以192.168.0.117机器为例:

[root@bqh-117 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"';

#nginx vhosts config
    include extra/bbs.conf;
    include extra/www.conf;
   } 

在/application/nginx/html目录下www和bbs静态文件 index.html

[root@bqh-117 nginx]# mkdir /application/nginx/html/ {www,bbs}
[root@bqh-117 nginx]# echo "`hostname -I` www web" >/application/nginx/html/www/index.html
[root@bqh-117 nginx]#echo "`hostname -I` bbs web" >/application/nginx/html/bbs/index.html
[root@bqh-117 nginx]# cat html/www/index.html html/bbs/index.html 
192.168.0.117 www web
192.168.0.117 bbs web

配置hosts来解析Web 01的IP和主机名,从新加载配置,然后用curl测试一下 www.bqh123.com和bbs.jyw.com

[root@bqh-117 nginx]# cat /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.0.117 www.bqh123.com bbs.jyw123.com
[root@bqh-117 nginx]# /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@bqh-117 nginx]# /application/nginx/sbin/nginx -s reload
nginx: [error] invalid PID number "" in "/application/nginx-1.6.3/logs/nginx.pid"  #原因是未启动nginx
[root@bqh-117 nginx]# /application/nginx/sbin/nginx
[root@bqh-117 nginx]# curl www.bqh123.com
192.168.0.117 www web
[root@bqh-117 nginx]# curl bbs.jyw123.com
192.168.0.117 bbs web

另外2台Web机器配置同步以上操作,curl测试结果如下:

[root@bqh-118 nginx]# curl www.bqh123.com
192.168.0.118 www web
[root@bqh-118 nginx]# curl bbs.jyw123.com
192.168.0.118 bbs web
[root@bqh-119 nginx]# curl www.bqh123.com
192.168.0.119 www web
[root@bqh-119 nginx]# curl bbs.jyw123.com
192.168.0.119 bbs web

现在我们开始配置一个简单的负载均衡服务:(以192168.0.121机器为例)

Nginx负载均衡配置,代理www.yunjisuan.com服务,节点为Web 01和Web 02机器的.nginx.conf配置文件如下:

[root@bqh-lb-121 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 server_pools {
     server 192.168.0.117:80;
     server 192.168.0.118:80;
     server 192.168.0.119:80;
 } 
     server { 
       listen 80;
         server_name www.bqh123.com;
server_name bbs.jyw123.com; location / { proxy_pass http://server_pools; } } }

检测下语法是否正确,并从启nginx服务:

[root@bqh-lb-121 conf]# vim nginx.conf
[root@bqh-lb-121 conf]# /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@bqh-lb-121 conf]# /application/nginx/sbin/nginx -s reload

然后配置一下hosts解析并curl测试一下:

[root@bqh-lb-121 conf]# cat /etc/hosts
127.0.0.1    localhost.localdomain    localhost.localdomain    localhost4    localhost4.localdomain4    localhost     b
qh-121::1    localhost.localdomain    localhost.localdomain    localhost6    localhost6.localdomain6    localhost    bqh-121
192.168.0.121 www.bqh123.com bbs.jyw123.com
[root@bqh-lb-121 conf]# curl www.bqh123.com
192.168.0.117 bbs web
[root@bqh-lb-121 conf]# curl www.bqh123.com
192.168.0.118 bbs web
[root@bqh-lb-121 conf]# curl www.bqh123.com
192.168.0.119 bbs web
[root@bqh-lb-121 conf]# curl bbs.jyw123.com
192.168.0.117 bbs web
[root@bqh-lb-121 conf]# curl bbs.jyw123.com
192.168.0.118 bbs web
[root@bqh-lb-121 conf]# curl bbs.jyw123.com
192.168.0.119 bbs web

从上面的测试结果可以看出3个Web节点按照1:1的比例被访问,若over掉任意一个Web节点,看看测试结果:

可以看到,网站业务不受影响,访问请求都定位到了正常的两个Web节点上。若所有Web节点都挂了,看看测试结果:

[root@bqh-117 nginx]# /application/nginx/sbin/nginx -s stop
[root@bqh-118 nginx]# /application/nginx/sbin/nginx -s stop
[root@bqh-119 nginx]# /application/nginx/sbin/nginx -s stop
------------------------------------------------------------- [root@bqh-lb-121 conf]# curl www.bqh123.com
<html> <head><title>502 Bad Gateway</title></head> <body bgcolor="white"> <center><h1>502 Bad Gateway</h1></center> <hr><center>nginx/1.6.3</center> </body> </html> [root@bqh-lb-121 conf]# curl bbs.jyw123.com <html> <head><title>502 Bad Gateway</title></head> <body bgcolor="white"> <center><h1>502 Bad Gateway</h1></center> <hr><center>nginx/1.6.3</center> </body> </html>

由此可见,Nginx代理下面没有节点了,Nginx向用户报告了502错误。

============================================================= 

nginx负载均衡相关模块:

1、  upstream模块:ngx_http_upstream_module

upstream模块的内容须放在http{}标签内,其默认调度节点算法是wrr(weighted round-robin,即权重轮询,平均分配)

 模块调度算法: ①. 定义轮询调度算法-rr-默认调度算法   ②. 定义权重调度算法-wrr  ③. 定义静态调度算法-ip_hash  ④. 定义最小的连接数-least_conn

语法:

upstream backend {   #upstream是关键字必须有,后面的backend为一个Upstream集群组的名字,可自拟名,调用时就用这个名字
    server backend1.example.com       #weight=5; server关键字是固定的,后面可以接域名或IP。如果不指定端口,默认是80端口。weight代表权重,数值越大被分配的请求越多,结尾有分号,切记。
    server backend2.example.com:8080; #域名加端口。转发到后端的指定端口上
    server unix:/tmp/backend3;   #指定socket文件
    server backup1.example.com:8080   backup; #备份服务器,等上面指定的服务器都不可访问的时候会启动,backup的用法和Haproxy中用法一样
    server backup2.example.com:8080   backup;
}
#注:server后面如果接域名,需要内网有DNS服务器或者在负载均衡器的hosts文件做域名解析。
server { #这里定义代理的负载均衡域名虚拟主机 location
/ { proxy_pass http://backend; #访问www.yunjisuan.com,请求发送给www_server_pools里面的节点 } }
upstream参数说明

模块参数

              

解释
server 10.0.10.8:80                                                                             

负载均衡后面的RS配置,可以是IP或域名,如果端口不写,默认是80端口。

高并发场景下, IP可换成域名,通过 DNS做负载均衡。

weigth=1 代表服务器的权重,默认值是1。权重数字越大表示接受的请求比例越大。
max_fails=3

Nginx尝试连接后端主机失败的次数,这个值是配合 proxy_next_upstream、fastcgi_next_upstream和memcached_next_upstream 这三个参数来使用的。当nginx接收后端服务器返回这三个参数定义的状态码时,会将这个请求转发给正常工作的后端服务器,例如404、502、503、 Max_fails的默认值是1 ;

企业场景下建议2-3次。如京东1次,蓝汛10次,根据业务需求去配置

fail_timeout=10s max_fails定义的失败次数后,距离下次检查的间隔时间,默认是10s ;如果max_fails是5 ,它就检测5次,如果5次都是502,那么,它就会根据fail_timeout的值,等待10s再去检查,还是只检查一次,如果持续502,在不重新加载 Nginx配置的情况下,每隔10s都只检查一次。常规业务2~3秒比较合理,比如京东3秒,蓝汛3秒,可根据业务需求去配置。
backup

热备配置(RS节点的高可用),当前面激活的RS都失败后会自动启用热备RS这标志看这个服务器作为备份服务器,若主服务器全部宕机了,就会向它转发请求。

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

down 这标志着服务器永远不可用,这个参数可配合ip_hash使用;类似与注释。

weight :调节服务器的请求分配权重

  • check :开启对该服务器健康检查。
  • inter:设置连续两次的健康检查间隔时间,单位毫秒,默认值2000。
  • rise :指定多少次连续成功的健康检查后,即可认定该服务器处于可用状态。
  • fall :指定多少次不成功的健康检查后,即认为服务器为宕机状态,默认值3。
  • maxconn :指定可被发送到该服务器的最大并发连接数。

2、http_proxy模块:此模块负载请求的转发,发给定义好的指定upstream名字

转发有:proxy_pass, fastcgi_pass, uwsgi_pass, scgi_pass, memcached_pass, and grpc_pass directives

location / {
    proxy_pass       http://localhost:8000;
    proxy_set_header Host      $host;
    proxy_set_header X-Real-IP $remote_addr;
}

                          http proxy 模块相关参数说明

 http proxy 模块相关参数  解释
 proxy_set_header  设置http请求header项传给后端服务器节点,例如:可实现让代理后端的服务器节点获取访问客户端用户的真实IP地址
 client_body_buffer_size  用于指定客户端请求主体缓冲区大小
 proxy_connect_timeout  表示反向代理后端节点服务器连接的超时时间,即发起握手等候响应的超时时间
 proxy_send_timeout  表示代理后端服务器的数据回传时间,即在规定时间内后端服务器必须传完所有数据,否则nginx将断开这个连接
 proxy_read_timeout  设置nginx从代理的后端服务器获取信息的时间,表示连接建立成功后,nginx等待后端服务器的响应时间,其实是nginx已经进入后端的排队之中等候处理的时间
 proxy_buffer_size  设置缓冲区大小,默认该缓冲区大小等于指令proxy_buffers设置的大小
 proxy_buffers  设置缓冲区的数量和大小,nginx从代理的后端服务器获取的响应信息,会设置到缓冲区
 proxy_busy_buffers_size  用于设置相同很忙时可以使用的proxy_buffers大小,官方推荐的大小为proxy_buffers * 2
 proxy_trmp_file_write_size  指定proxy缓存临时文件的大小

 weight模块参数测试:

Nginx代理配置为:

[root@bqh-lb-121 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 server_pools {
     server 192.168.0.117:80 weight=1;
     server 192.168.0.118:80 weight=2;
server 192.168.0.119:80 weight=3;
} server { listen
80; server_name www.bqh123.com; server_name bbs.jyw123.com; location / { proxy_pass http://server_pools; } } }
注:这里是代理服务器

curl bbs.jyw.com测试如下:

[root@bqh-lb-121 nginx]# vim conf/nginx.conf
[root@bqh-lb-121 nginx]# /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@bqh-lb-121 nginx]# /application/nginx/sbin/nginx -s reload
[root@bqh
-lb-121 nginx]# curl bbs.jyw123.com 192.168.0.118 bbs web [root@bqh-lb-121 nginx]# curl bbs.jyw123.com 192.168.0.119 bbs web [root@bqh-lb-121 nginx]# curl bbs.jyw123.com 192.168.0.119 bbs web [root@bqh-lb-121 nginx]# curl bbs.jyw123.com 192.168.0.118 bbs web [root@bqh-lb-121 nginx]# curl bbs.jyw123.com 192.168.0.117 bbs web [root@bqh-lb-121 nginx]# curl bbs.jyw123.com 192.168.0.119 bbs web

 我们curl www.bqh123.com测试如下:

[root@bqh-lb-121 nginx]# curl www.bqh123.com
192.168.0.119 bbs web
[root@bqh-lb-121 nginx]# curl www.bqh123.com
192.168.0.118 bbs web
[root@bqh-lb-121 nginx]# curl www.bqh123.com
192.168.0.119 bbs web
[root@bqh-lb-121 nginx]# curl www.bqh123.com
192.168.0.119 bbs web
[root@bqh-lb-121 nginx]# curl www.bqh123.com
192.168.0.118 bbs web
[root@bqh-lb-121 nginx]# curl www.bqh123.com
192.168.0.117 bbs web

此时我们发现反向代理,负载均衡已实现,但有一个问题,那就是curl www.bqh123.com返回的结果不对,代理的www虚拟主机却返回bbs虚拟主机?

原因如下:

当用户访问域名时确实是携带了www.bqh123.com主机头请求Nginx反向代理服务器,但是反向代理向下面节点重新发起请求时,默认并没有在请求头里告诉节点服务器要找哪台虚拟主机,所以,Web节点服务器接收到请求后发现没有主机头信息,因此,就把节点服务

器的第一个虚拟主机发给了反向代理了(节点上第一个虚拟主机放置的是故意这样放置的bbs)。解决这个问题的方法,就是当反向代理向后重新发起请求时,要携带主机头信息,以明确告诉节点服务器要找哪个虚拟主机。具体的配置很简单,就是在Nginx代理www服务

虚拟主机配置里增加如下一行配置即可:

[root@bqh-lb-121 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 server_pools {
     server 192.168.0.117:80 weight=1;
     server 192.168.0.118:80 weight=2;
     server 192.168.0.119:80 weight=3;
 } 
     server { 
       listen 80;
         server_name www.bqh123.com;
         server_name bbs.jyw123.com;
         location / {
             proxy_pass http://server_pools;
             proxy_set_header host $host;     #在代理向后端服务器发送的http请求头中加入host字段信息,用于当后端服务器配置有多个虚拟主机时,可以识别代理的是哪个虚拟主机。这是节点服务器多虚拟主机时的关键配置
}
}
}
注:这里是代理服务器

 从新加载配置,测试如下:

[root@bqh-lb-121 nginx]# vim conf/nginx.conf
[root@bqh-lb-121 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@bqh-lb-121 nginx]# ./sbin/nginx -s reload
[root@bqh-lb-121 nginx]# curl www.bqh123.com
192.168.0.119 www web
[root@bqh-lb-121 nginx]# curl www.bqh123.com
192.168.0.118 www web
[root@bqh-lb-121 nginx]# curl www.bqh123.com
192.168.0.117 www web
[root@bqh-lb-121 nginx]# curl www.bqh123.com
192.168.0.119 www web
[root@bqh-lb-121 nginx]# curl www.bqh123.com
192.168.0.118 www web
[root@bqh-lb-121 nginx]# curl www.bqh123.com
192.168.0.119 www web

ok,访问返回结果正确。

反向代理ok后,我们查看一下访问日志记录,发现节点服务器对应的WWW虚拟主机的访问日志的第一个字段记录的并不是客户端的IP,而是反向代理服务器的IP,最后一个字段也是“-”!

测试:在任意windows客户端(IP192.168.0.105)访问已经解析好代理IP的www.bqh123.com或bbs.jyw123.com后,去节点服务器www/bbs服务日志查看,就会发现如下日志:

[root@bqh-117 ~]# tail -1 /application/nginx/logs/access_www.log 
192.168.0.121 - - [11/Jul/2019:22:39:46 +0800] "GET / HTTP/1.0" 200 22 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 SE 2.X MetaSr 1.0" "-"
[root@bqh-117 ~]# tail -1 /application/nginx/logs/access_bbs.log 
192.168.0.121 - - [11/Jul/2019:22:39:37 +0800] "GET / HTTP/1.0" 200 22 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 SE 2.X MetaSr 1.0" "-"

Web01节点服务器对应的WWW虚拟主机的访问日志的第一个字段记录的并不是客户端(windows)的IP而是反向代理服务器本身的IP(192.168.0.121),最后一个字段也是一个“-”,那么如何解决这个问题?其实很简单,同样是增加如下一行参数:

[root@bqh-lb-121 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 server_pools {
     server 192.168.0.117:80 weight=1;
     server 192.168.0.118:80 weight=2;
     server 192.168.0.119:80 weight=3;
 } 
     server { 
       listen 80;
         server_name www.bqh123.com;
         server_name bbs.jyw123.com;
         location / {
             proxy_pass http://server_pools;
             proxy_set_header host $host;
         proxy_set_header X-Forwarded-For $remote_addr; #在代理向后端服务器发送的http请求头中加入X-Forwarded-For字段信息,用于后端服务器程序,日志等接收记录真实用户的IP,而不是代理服务器的IP
    }
  }
} 
注:这里是代理服务器

如果想节点服务器的访问日志记录用户的真实IP,配置如下:

[root@bqh-117 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"'; #这里的“$http_x_forwarded_for”参数,如果希望在第一行显示,可以替换掉第一行的$remote_addr变量。

#nginx vhosts config
    include extra/bbs.conf;
    include extra/www.conf;
   } 
注:这里是Web01.117服务器

刷新配置,在任意windows客户端(IP192.168.0.105)访问已经解析好代理IP的www.bqh123.com或bbs.jyw123.com后,去节点服务器www/bbs服务日志查看:

[root@bqh-lb-121 nginx]# tail -1 /application/nginx/logs/access.log 
192.168.0.105 - - [11/Jul/2019:23:30:06 +0800] "GET / HTTP/1.1" 200 22 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 SE 2.X MetaSr 1.0"
注:代理服务器
[root@bqh-117 nginx]# tail -1 /application/nginx/logs/access_www.log 
192.168.0.121 - - [11/Jul/2019:23:30:06 +0800] "GET / HTTP/1.0" 200 22 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 SE 2.X MetaSr 1.0" "192.168.0.105"
注:Web01.117服务器

解释:日志里的192.168.0.121为反向代理的IP,对应Nginx日志格式里的$remote_addr变量,而日志结尾的192.168.0.105对应的时日志格式里的“$http_x_forwarded_for”变量,即接收了前面反向代理配置中“proxy_set_header X-Forwarded-For $remote_addr;”参数X-Forwarded-For的IP了。

Nginx反向代理重要参数
参数 解释说明
proxy.pass http://server_pools;  通过proxy_pass功能把用户的清求转向到反向代理定义的upstream服务器池
proxy_set_header Host $host 在代理向后端服务器发送的 http请求头中加入 host字段信息,用于当后端服务器配置有多个虚拟主机时,可以识别代理的是哪个虚拟主机。这是节点服务器多虚拟主机时的关键配置

proxy_set_header X-Forwarded-For $remote_addr;                                                             

在代理向后端服务器发送的 http请求头中加入 X-Forward-For字段信息,用于后端服务器程序、日志等接收记录真实用户的 IP ,而不是代理服务器的 IP这是反向代理时,节点服务器获取用户真实 IP的必要功能配置

让后端节点接收真实用户IP apache配置:

LogFormat "%h %l %u %t "%r " %>s %b   "% {X-Forwarded-For} i"" common

测试:基于url目录地址实现代理转发

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

机器及ip规划:如下图  

主机 IP地址 作用
bqh-117 192.168.0.117 upload上传服务器 Web 01
bqh-118 192.168.0.118 static静态服务器 Web 02
bqh-119 192.168.0.119 default默认服务器 Web 03
bqh-lb-121 192.168.0.121 Nginx主要载均衡器
bqh-lb-122 192.168.0.122 Nginx副负载均衡器

在nginx负载均衡服务器上实际配置:

[root@bqh-lb-121 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 upload_pools {
     server 192.168.0.117:80;
   }
    upstream static_pools {
     server 192.168.0.118:80;
   }
    upstream default_pools {
     server 192.168.0.119:80;
 } 
     server { 
       listen 80;
         server_name www.bqh123.com;
         server_name bbs.jyw123.com;
    
    location /upload/ {
             proxy_pass http://upload_pools;
             proxy_set_header host $host;
         proxy_set_header X-Forwarded-For $remote_addr;
    }
    location /static/ {
             proxy_pass http://static_pools;
             proxy_set_header host $host;
             proxy_set_header X-Forwarded-For $remote_addr;
    }       
    location / {
             proxy_pass http://default_pools;
             proxy_set_header host $host;
             proxy_set_header X-Forwarded-For $remote_addr;
    }       
  }
} 
[root@bqh-lb-121 conf]# ../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@bqh-lb-121 conf]# ../sbin/nginx -s reload
注:这里是在主/副负载服务器

配置web服务器环境

[root@bqh-117 www]# mkdir upload
[root@bqh-117 www]# echo "192.168.0.117 www Web01 upload" >upload/index.html
[root@bqh-117 www]# curl www.bqh123.com/upload/index.html
192.168.0.117 www Web01 upload

[root@bqh-118 www]# mkdir upload
[root@bqh-118 www]# echo "192.168.0.118 www Web01 upload" >upload/index.html
[root@bqh-118 www]# curl www.bqh123.com/upload/index.html
192.168.0.118 www Web01 upload

[root@bqh-119 www]# echo "192.168.0.119 www Web03 default" >index.html
[root@bqh-119 www]# curl www.bqh123.com
192.168.0.119 www Web03 default

浏览器测试结果如下:

我们查看一下日志情况以web 01服务器为例:

[root@bqh-117 www]# tail -1 /application/nginx/logs/access_www.log 
192.168.0.121 - - [13/Jul/2019:23:57:25 +0800] "GET /upload/index.html HTTP/1.0" 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 SE 2.X MetaSr 1.0" "192.168.0.105"

此时我们把主要负载均衡lb-121服务器over掉,访问试试,再查看日志情况:

[root@bqh-117 www]# tail -2 /application/nginx/logs/access_www.log 
192.168.0.121 - - [13/Jul/2019:23:57:25 +0800] "GET /upload/index.html HTTP/1.0" 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 SE 2.X MetaSr 1.0" "192.168.0.105"
192.168.0.122 - - [13/Jul/2019:23:57:30 +0800] "GET /upload/index.html HTTP/1.0" 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 SE 2.X MetaSr 1.0" "192.168.0.105"

ok,副负载均衡服务器已开始提供服务,不影响业务访问。

测试:基于客户端的设备实现转发(user_agent)

[root@bqh-lb-121 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 upload_pools {
     server 192.168.0.117:80;
   }
    upstream static_pools {
     server 192.168.0.118:80;
  }
    upstream default_pools {
     server 192.168.0.119:80;
 } 
     server { 
       listen 80;
         server_name www.bqh123.com;
    
    location / {
      if ($http_user_agent ~* "MSIE")   {
             proxy_pass http://upload_pools;
         }     
      if ($http_user_agent ~* "Chrome") {
             proxy_pass http://static_pools;
          }
             proxy_pass http://default_pools;
             proxy_set_header Host $host;
         proxy_set_header X-Forwarded-For $remote_addr;
    }       
  }
}
注:根据http_user_agent内容选择不同的服务器 [root@bqh
-lb-121 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@bqh-lb-121 nginx]# sbin/nginx -s reload

测试结果:curl -A 指定访问类型

[root@bqh-lb-121 nginx]# curl -A MSIE www.bqh123.com
192.168.0.117 www web
[root@bqh-lb-121 nginx]# curl -A Chrome www.bqh123.com
192.168.0.118 www web
[root@bqh-lb-121 nginx]# curl -A xx  www.bqh123.com
192.168.0.119 www Web03 default

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

[root@bqh-lb-121 nginx]# vim 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 android_pools {
     server 192.168.0.117:80;
   }
    upstream iphone_pools {
     server 192.168.0.118:80;
  }
    upstream pc_pools {
     server 192.168.0.119:80;
 } 
     server { 
       listen 80;
         server_name www.bqh123.com;
    
    location / {
      if ($http_user_agent ~* "android")   {
             proxy_pass http://android_pools;
         }     
      if ($http_user_agent ~* "iphone") {
             proxy_pass http://iphone_pools;
          }
             proxy_pass http://pc_pools;
             proxy_set_header Host $host;
         proxy_set_header X-Forwarded-For $remote_addr;
    }       
  }
}
[root@bqh-lb-121 nginx]# vim conf/nginx.conf
[root@bqh-lb-121 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@bqh-lb-121 nginx]# sbin/nginx -s reload
[root@bqh-lb-121 nginx]# curl -A android www.bqh123.com
192.168.0.117 www web
[root@bqh-lb-121 nginx]# curl -A xx www.bqh123.com
192.168.0.119 www Web03 default
[root@bqh-lb-121 nginx]# curl -A iphone www.bqh123.com
192.168.0.118 www web

我们来查看一下Web节点日志:

[root@bqh-117 ~]# tail -1 /application/nginx/logs/access_www.log 
192.168.0.121 - - [13/Jul/2019:10:40:07 +0800] "GET / HTTP/1.0" 200 22 "-" "android" "192.168.0.121"
[root@bqh-118 ~]# tail -1 /application/nginx/logs/access_www.log 
192.168.0.121 - - [13/Jul/2019:10:40:12 +0800] "GET / HTTP/1.0" 200 22 "-" "iphone" "192.168.0.121"
[root@bqh-119 ~]# tail -1 /application/nginx/logs/access_www.log 
192.168.0.121 - - [13/Jul/2019:10:40:10 +0800] "GET / HTTP/1.0" 200 32 "-" "xx" "192.168.0.121"

当然我们也可以基于扩展名来进行转发:

配置修改如下:

[root@bqh-lb-121 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 upload_server_pools { 
     server 192.168.0.117:80;
   }
    upstream php_server_pools {  
     server 192.168.0.118:80;
  }
    upstream java_server_pools {  
     server 192.168.0.119:80;
 } 
     server  { 
       listen 80;
         server_name www.bqh123.com;
    
    location /  {
      if ($request_uri ~* ".*.(gif|jgp|png|swf|css|js)$") { 
             proxy_pass http://upload_server_pools;
         }     
      if ($request_uri ~* ".*.(php|php5)$") {  
             proxy_pass http://php_server_pools;
          }
             proxy_pass http://java_server_pools;
             proxy_set_header Host $host;
         proxy_set_header X-Forwarded-For $remote_addr;
    }       
  }
}
原文地址:https://www.cnblogs.com/su-root/p/11144648.html