反向代理软件

Nginx:本身支持反向代理、负载均衡功能,属于L7层负载均衡。Nginx反向代理简单易用,受到大部分中小企业的青睐。
LVS:支持L4层负载均衡,
haproxy:支持L4、L7层负载均衡
L4、L7是指OSI模型中的第四层和第七层;L4:TCP负载均衡;L7:http负载均衡
nginx、lvs、haproxy区别参考资料
https://www.cnblogs.com/ahang/p/5799065.html
https://www.cnblogs.com/like-minded/p/5157659.html

实现Nginx负载均衡的两个主要模块
Nginx得负载均衡是基于反向代理之上实现的。
ngx_http_proxy_module: proxy代理模块,把请求后抛给服务器节点或upstream服务器池
ngx_http_upstream_module: 负载均衡模块,可以实现网站的负载均衡功能及节点的健康检查,定义节点池
具体语法可以参考官方文档:
http://nginx.org/en/docs/http/ngx_http_proxy_module.html
http://nginx.org/en/docs/http/ngx_http_upstream_module.html

Nginx反向代理软件安装
Nginx反向代理软件安装即安装Nginx软件。下面是安装Nginx自动化脚本

#系统环境
cat /etc/redhat-release 
uname -r
uname -m
#设置目录环境
mkdir /home/Ricky/tools -p
mkdir /application
mkdir /server/scripts -p
#安装所需的库
yum -y install pcre pcre-devel openssl-devel
rpm -qa pcre pcre-devel openssl-devel
#添加Nginx运行用户
useradd -u 501 -s /sbin/nologin -M www
id www
mkdir /application/nginx-1.12.2 -p
#安装Nginx
cd /home/Ricky/tools
wget -q http://nginx.org/download/nginx-1.12.2.tar.gz 
tar xf nginx-1.12.2.tar.gz
cd nginx-1.12.2
./configure --prefix=/application/nginx-1.12.2/ --user=www --group=www --with-http_ssl_module --with-http_stub_status_module 
echo $?
make
echo $?
make install
echo $?
ln -s /application/nginx-1.12.2/ /application/nginx
#开机启动
echo "/application/nginx/sbin/nginx" >>/etc/rc.local 
tail -1 /etc/rc.local

Nginx反向代理部署

#生成配置文件nginx.conf
cd /application/nginx/conf/
egrep -v "#|^$" nginx.conf.default >nginx.conf
#配置反向代理和upstream资源池
vim nginx.conf
upstream www_server_pools {
        server 10.0.0.7:80 weight=1;
        server 10.0.0.8:80 weight=1;#weight权重相等,实现负载均衡,轮询处理请求
}
    server {
        listen       80;
        server_name  www.ricky.com;
        location / {
            root   html;
            index  index.html index.htm;
            proxy_pass http://www_server_pools;#把请求抛向upstream资源池,让资源池的设备进行处理
            proxy_set_header Host  $host;#自定义http包的header的host字段,让代理服务器使用用户的host去访问web服务器(不改变http中host的信息);如果不自动以host字段,可能会导致返回400的报错
        }
    }
/application/nginx/sbin/nginx –t
/application/nginx/sbin/nginx -s reload
lsof -i :80

反向代理负载均衡测试结果
我配置了1台nginx反向代理服务器和两台web服务器(一台apache,一台nginx);实际生产中要统一使用apache或者nginx,我这里是因为我自己在家里的电脑搭建了一个集群架构研究集群,web服务器只搭建了一台apache和一台nginx,凑合着用。这里nginx proxy属于单点,可以增加一台结合keepalived做高可用,后续文章讲解。

Nginx实现反向代理负载均衡功能_第1张图片

for n in `seq 100`;do curl 10.0.0.6;sleep 1;done
apache www
nginx www
apache www
nginx www

如果web集群中的一台服务器宕机了,代理就会把所有请求转发到剩下的那台web服务器提供服务,不会造成用户因为单个节点坏了,而无法访问公司网站
upstream模块具备健康检查功能,所以能够及时发现集群中宕机的节点,从而轮询给正常工作的机器来处理,使用的是轮询原理。

400错误出现的可能
在实验的时候,客户端返回信息出现错误,只有一台web能正常返回内容,另一台返回400的报错信息。因为是以前的笔记,忘了把错误信息保留下来。
1、http报文缺失host字段
用户到反向代理服务器中的http报文header请求头中是有host字段的,而反向代理服务器到web服务器的http报文header请求头中是没有host字段的,所以导致apache服务器无法正常解析nginx代理转发的请求,所以返回400错误(400-499是客户端的问题)
在http 1.1中不能缺失host字段,如果缺失, 服务器返回400 bad request,http1.1中不能缺失host字段,但host字段可以是空值。
在http 1.0中可以缺失host字段。
参考资料:https://blog.csdn.net/s1234567_89/article/details/51139864
proxy_set_header Host $host;
#自定义http包的header的host字段,让代理服务器使用用户的host去访问web服务器(不改变http中host的信息)
位置:http,server,location
参考资料:
https://www.cnblogs.com/yanghj010/p/5980974.html
https://blog.csdn.net/a19860903/article/details/49914131
http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_set_header

反向代理原理

Nginx实现反向代理负载均衡功能_第2张图片
查看web服务器的访问日志
10.0.0.6 - - [13/Jun/2018:20:44:15 +0800] "GET / HTTP/1.0" 200 10 "-" "curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.13.6.0 zlib/1.2.3 libidn/1.18 libssh2/1.4.2"
客户端IP是10.0.0.61;
nginx反向代理服务器是10.0.0.6;
从这里可以看出,用户访问web是通过反向代理服务器完成的(用户访问反向代理服务器,然后由代理服务器去请求web集群,获取数据后,也是由代理服务器响应用户)

web端如何记录用户ip?
web节点服务器访问日志第一个字段记录的并不是客户端IP(10.0.0.61),而是反向代理服务器本身的IP(10.0.0.6);而很多时候,运维可能需要通过访问日志的用户IP来统计用户的访问情况,如何解决这个问题呢?
添加以下字段即可

proxy_set_header X-Forwarded-For  $remote_addr;
位置:http,server,location

反向代理时,节点服务器获取用户真实IP的必要功能配置
在反向代理请求后端节点服务器的请求头中增加获取的客户端IP的字段信息,然后节点后端可以通过程序或者相关的配置接收X-Forwared-For传过来的用户真实IP的信息。
web访问日志格式也得支持
配置nginx.conf配置文件中的log_format参数(http的Log模块)
访问日志显示X-Forward-For字段的用户真实IP
web日志格式配置如下

log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                  '$status $body_bytes_sent "$http_referer" '
                  '"$http_user_agent" "$http_x_forwarded_for"';
access_log  logs/access.log  main;
#位置:http,server,location

参考资料:http://nginx.org/en/docs/http/ngx_http_log_module.html

测试效果
10.0.0.6 - - [13/Jun/2018:21:47:59 +0800] "GET / HTTP/1.0" 200 10 "-" "curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.13.6.0 zlib/1.2.3 libidn/1.18 libssh2/1.4.2" "10.0.0.61"
最后一个字段就是客户端的IP