Nginx反向代理与负载均衡(二)
1. 反向代理
1.1 什么是反向代理
反向代理(Reverse Proxy)实际运行方式是指以代理服务器来接受internet上的连接请求,然后将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给internet上请求连接的客户端,此时代理服务器对外就表现为一个服务器。(反向代理中,proxy和server同属一个LAN,对client透明。)
1.2 反向代理与数据转发的区别
就例如LVS,它纯纯是进行数据的转发,做一个负载分担的一个角色。虽然反向代理也可以充当负载分担的角色,但它是自愿的,就是来做这一项工作的,代处理用户的数据,再跟后端的服务器进行交互。
简单总结:
反向代理:对用户的请求进行代理,代替用户请求后端节点。
负载均衡:对用户的请求进行转发,转发到后端节点处理请求。(本身不产生流量,只做用户请求转发)
1.3 用途
- 隐藏服务器真实ip:使用反向代理,可以对客户端隐藏服务器的ip地址。
- 负载均衡:反向代理服务器可以做负载均衡,根据所有真实服务器的负载情况,将客户端请求分发到不同的真实服务器上。
- 提高访问速度:反向代理服务器可以对静态内容及短时间内有大量访问请求的动态内容提供缓存服务,提高访问速度。
- 提供安全保障:反向代理服务器可以作为应用层防火墙,为网站提供对基于web的攻击行为(例如DoS/DDoS)的防护,更容易排查恶意软件等。还可以为后端服务器统一提供加密和SSL加速(如SSL终端代理),提供HTTP访问认证等。
2. 正向代理
2.1 什么是正向代理
正向代理是一个位于客户端和目标服务器之间的代理服务器(中间服务器)。为了从目标服务器取得内容,客户端向代理服务器发送一个请求,并且指定目标服务器,之后代理向目标服务器转发请求,将获得的内容返回给客户端。
有时候,用户想要访问某国外网站,该网站无法在国内直接访问,但是我们可以访问到一个代理服务器,这个代理服务器可以访问到这个国外网站。这样呢,用户对该国外网站的访问就需要通过代理服务器来转发请求,并且该代理服务器也会将请求的响应再返回给用户。这个上网的过程就是用到了正向代理。
2.2 用途
- 突破访问显示:通过代理服务器,可以突破自身ip访问限制,访问国外网站等。
- 提高访问速度:通常代理服务器都设置一个较大的硬盘缓冲区,会将部分请求的响应保存到缓冲区中,当其他用户再访问相同的信息时,则直接由缓冲区中取出信息,传给用户,以提高访问速度。
- 隐藏客户端真实ip:上网者可以通过正向代理的方法隐藏自己的ip,免受攻击。
3. 反向代理极速配置上手指南
3.1 proxy模块
proxy模块指令 | |
---|---|
proxy_pass | 用于把请求传递给指定的ip/域名进行处理 |
proxy_pass指令 | |
---|---|
格式 | proxy_pass url地址即可 proxy_pass http://10.0.0.7:80; |
默认值 | |
放哪 | location , if in location |
3.2 环境准备
角色 | 主机 | ip | 服务 |
---|---|---|---|
反向代理 | lb01 | 10.0.0.5 | nginx |
web服务端 | web01 | 10.0.0.7 | nginx |
补充 | 域名 | 站点目录 | 首页文件 |
---|---|---|---|
proxy.yinjay.com | /app/code/proxy/ | index.html |
#web01 lb01安装
yum install nginx -y
#启动nginx,并设置开机自启
systemctl start nginx
systemctl enable nginx
3.3 修改配置
#web01 lb01删除该配置底下的server指令
[root@web01 ~]# vim /etc/nginx/nginx.conf
web01
#创建网站目录和测试文件
[root@web01 ~]# mkdir -p /app/code/proxy
[root@web01 ~]# echo proxy.yinjay.com > /app/code/proxy/index.html
#配置文件
[root@web01 ~]# cat /etc/nginx/conf.d/default.conf
server {
listen 80;
server_name proxy.yinjay.com;
access_log /var/log/nginx/proxy.yinjay.com-access.log main;
error_log /var/log/nginx/proxy.yinjay.com-error.log notice;
root /app/code/proxy;
location / {
index index.html;
}
}
#重新加载配置
[root@web01 ~]# systemctl reload nginx
lb01
#修改配置
[root@lb01 conf.d]# cat /etc/nginx/conf.d/defalut.conf
server {
listen 80;
server_name proxy.yinjay.com;
access_log /var/log/nginx/proxy.yinjay.com-access.log main;
error_log /var/log/nginx/proxy.yinjay.com-error.log notice;
location / {
proxy_pass http://10.0.0.7:80;
}
}
#重新加载配置
[root@web01 ~]# systemctl reload nginx
3.4 测试并抓包
在window宿主机上添加host记录10.0.0.5 proxy.yinjay.com
,进行浏览器访问并抓包,能看到有两个请求,宿主机请求proxy.yinjay.com,lb01进行代请求,web01返回给lb01,lb01再返回给宿主机。
这里抓包没有分两个网段主要为了方便抓包查看!
3.5 查看日志
3.6 修改请求头
为什么要修改请求头?因为后端服务器通过刚才的日志分析并不能得知客户的真实访问IP,所以需要进行修改请求头。
利用proxy_set_header模块指令,http请求header项传给后端服务器节点时,可实现让代理后端的服务器节点获取访问客户端用户的真实IP地址。
proxy_set_header指令 | 用于修改代理到后端节点的请求头 |
---|---|
让后端web服务器记录用户真实ip地址 | proxy_set_header X-Forwarded-For $remote_addr; |
在lb01进行修改
[root@lb01 ~]# vim /etc/nginx/conf.d/defalut.conf
server {
listen 80;
server_name proxy.yinjay.com;
access_log /var/log/nginx/proxy.yinjay.com-access.log main;
error_log /var/log/nginx/proxy.yinjay.com-error.log notice;
location / {
proxy_pass http://10.0.0.7:80;
proxy_set_header X-Forwarded-For $remote_addr;
}
}
3.6.1 查看日志
访问后查看日志信息,已经成功记录了用户访问的真实IP。
3.6.2 查看抓包信息
代理服务器会在代请求的时候在请求头插入X-Forwarded-For来记录用户真实的IP
日志为什么会记录呢?因为定义了日志的格式已经包含。
3.7 案例:多虚拟主机使用代理故障
重新修改web01的两个配置文件,内容如下:
[root@web01 conf.d]# cat /etc/nginx/conf.d/default.conf
server {
listen 80 default_server;
server_name "";
charset utf8;
default_type text/plain;
return 200 "访问出错啦!";
}
[root@web01 conf.d]# cat /etc/nginx/conf.d/proxy.yinjay.com.conf
server {
listen 80;
server_name proxy.yinjay.com;
access_log /var/log/nginx/proxy.yinjay.com-access.log main;
error_log /var/log/nginx/proxy.yinjay.com-error.log notice;
root /app/code/proxy;
location / {
index index.html;
}
}
#重新加载配置
[root@web01 conf.d]# systemctl reload nginx
3.7.1 访问测试
3.7.2 故障原因与解决
代理节点向后端节点发出请求的时候,Host部分因为proxy_pass被修改为了ip地址。后端节点接收请求后Nginx进行处理,根据Nginx的处理流程匹配不到server_name proxy.yinjay.com;
这个虚拟主机,自然就匹配默认的虚拟主机server指令。
解决方法就是让代理节点不更改请求头的Host字段
proxy_set_header指令 | 用于修改代理到后端节点的请求头 |
---|---|
不修改Host请求头 | proxy_set_header Host $http_host; |
lb01上修改
[root@lb01 ~]# vim /etc/nginx/conf.d/defalut.conf
server {
listen 80;
server_name proxy.yinjay.com;
access_log /var/log/nginx/proxy.yinjay.com-access.log main;
error_log /var/log/nginx/proxy.yinjay.com-error.log notice;
location / {
proxy_pass http://10.0.0.7:80;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $http_host;
}
}
#重新加载配置文件
[root@lb01 ~]# systemctl reload nginx
再次访问,已经没有问题
4. 负载均衡极速配置上手指南
4.1 upstream模块
upstream指令 | |
---|---|
格式 | upstream name |
默认值 | |
放哪 | http |
4.2 环境准备
主机 | ip | 域名 | 站点目录 | 首页文件及内容 |
---|---|---|---|---|
lb01 | 10.0.0.5 | lb.yinjay.com | ||
web01 | 10.0.0.7 | lb.yinjay.com | /app/code/lb | index.html web01 lb.yinjay.com |
web02 | 10.0.0.8 | lb.yinjay.com | /app/code/lb | index.html web02 lb.yinjay.com |
4.3 修改配置
web01
#创建目录、文件
[root@web01 conf.d]# mkdir -p /app/code/lb
[root@web01 conf.d]# [root@web01 conf.d]#
systecho "`hostname` lb.yinjay.com" > /app/code/lb/index.html
#配置内容如下:
[root@web01 conf.d]# cat /etc/nginx/conf.d/lb.conf
server {
listen 80;
server_name lb.yinjay.com;
access_log /var/log/nginx/lb.yinjay.com-access.log main;
error_log /var/log/nginx/lb.yinjay.com-error.log notice;
root /app/code/lb;
location / {
index index.html;
}
}
#重新加载配置文件
[root@web01 conf.d]# systemctl reload nginx
web02
#创建目录、文件
[root@web02 ~]# mkdir -p /app/code/lb
[root@web02 ~]# echo "`hostname` lb.yinjay.com" > /app/code/lb/index.html
#配置内容如下:
[root@web02 ~]# cat /etc/nginx/conf.d/lb.conf
server {
listen 80;
server_name lb.yinjay.com;
access_log /var/log/nginx/lb.yinjay.com-access.log main;
error_log /var/log/nginx/lb.yinjay.com-error.log notice;
root /app/code/lb;
location / {
index index.html;
}
}
#重新加载配置文件
[root@web01 conf.d]# systemctl reload nginx
lb01
#配置内容如下:
[root@lb01 conf.d]# cat /etc/nginx/conf.d/defalut.conf
upstream lb_pools {
server 10.0.0.7:80;
server 10.0.0.8:80;
}
server {
listen 80;
server_name lb.yinjay.com;
access_log /var/log/nginx/lb.yinjay.com-access.log main;
error_log /var/log/nginx/lb.yinjay.com-error.log notice;
location / {
proxy_pass http://lb_pools;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $http_host;
}
}
#重新加载配置文件
[root@lb01 conf.d]# systemctl reload nginx
4.4 访问测试
在window宿主机上添加host记录10.0.0.5 lb.yinjay.com
,进行浏览器访问并抓包。下面通过抓包能看出负载的详细情况,由不同的后端服务器进行响应给lb01。
4.5 upstream模块参数
状态 | 概述 |
---|---|
down | 当前的server暂时不参与负载均衡 |
backup | 预留的备份服务器 |
max_fails | 允许请求失败的次数 |
fail_timeout | 经过max_fials失败后,服务暂停时间 |
max_conns | 限制最大的接收连接数 |
负载均衡调度算法 | 概述 |
---|---|
轮询 | 按时间顺序逐一分配到不同的后端服务器(默认的算法) |
weight | 加权轮询,weight值越大,分配到的访问几率越高 |
ip_hash | 每个请求按访问IP的hash结果分配,这样来自同一个IP的固定访问一个后端服务器 |
url_hash | 按照访问的URL的hash结果来分配请求,是每一个URL定向到同一个后端服务器 |
least_conn | 最少链接数,哪个机器链接数最少就分发 |
lb01上修改
[root@lb01 ~]# vim /etc/nginx/conf.d/defalut.conf
upstream lb_pools {
server 10.0.0.7:80 backup; #预留的备份服务器,只有其他主机挂了才会启用
server 10.0.0.8:80;
}
server {
listen 80;
server_name lb.yinjay.com;
access_log /var/log/nginx/lb.yinjay.com-access.log main;
error_log /var/log/nginx/lb.yinjay.com-error.log notice;
location / {
proxy_pass http://lb_pools;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $http_host;
}
}
----------下面是upstream的示例配置-----------
upstream lb_pools {
server 10.0.0.7:80 down; #例如需要进行临时维护,可以设置成down
server 10.0.0.8:80;
}
upstream lb_pools {
server 10.0.0.7:80 max_conns=3; #如果同时来了10个连接,web01最大接受连接数为3个,剩下的全都给web02处理
server 10.0.0.8:80;
}
upstream lb_pools {
server 10.0.0.7:80 max_fails=2 fail_timeout=10s; #最多允许客户端向服务端发送请求失败2次,超过2次,暂停服务10秒。
server 10.0.0.8:80;
}
upstream lb_pools {
#配置权重,用户端请求访问5次web01主机后,再访问1次web02主机
server 10.0.0.7:80 weight=5;
server 10.0.0.8:80 weight=1;
}
upstream lb_pools {
ip_hash;
# 根据来源的IP自动分配主机,记录在内存里面。
# 如果我们第一次用浏览器访问web服务器,请求发送给了web01主机,那么请求会一直发送给web01主机。
# 除非web01主机down掉了,才会把请求发送给web02主机。如果web01主机恢复运行了,那么请求还是会发送给web01主机。
server 10.0.0.7:80;
server 10.0.0.8:80;
}