一、神马是反向代理
1、维基百科解释
反向代理是代理服务器的一种。服务器根据客户端的请求,从其关系的一组或多组后端服务器(如Web服务器)上获取资源,然后再将这些资源返回给客户端,客户端只会得知反向代理的IP地址,而不知道在代理服务器后面的服务器簇的存在。
反向代理在现时的互联网中并不少见,而另一些例子,像是CDN、SNI代理等,是反向代理结合DNS的一类延伸应用。
2、个人理解
反向代理主要用于将互联网上访问用户的请求代理分发给内部应用服务器,起到服务器负载均衡的效果,可以通过url重写,根据请求从负荷较低的服务器中响应用户请求。
反向代理与正向代理的最大区别是应用方向的不同,正向代理用于将内网用户代理上互联网,反向代理是将互联网访问用户的访问请求代理进内网服务器。
3、网络拓扑
4、nginx反向代理处理流程说明
假设互联网用户x1.x2.x3.x4需要访问一个门户网站,这个门户网站的首页域名对应的IP地址是192.168.99.10,首页在后端私有网络中有四台服务器组成,IP地址范围是172.16.0.11-172.16.0.14。
1、第一步用户x1.x2.x3.x4向nginx服务器ip192.168.99.10发起http请求;
2、nginx收到请求后将其转发至ngx_http_upstream_module模块处理,通过upstream定义一组服务器,服务器可以侦听不同的端口,默认其公开下使用加权循环平衡方法在服务器之间分配请求,如果在与服务器通信期间发生错误,请求将被传递到下一个服务器,依此类推,直到将尝试所有正常运行的服务器。如果无法从任何服务器获得成功的响应,则客户端将接收与最后一个服务器的通信结果。
3、用户的互联网请求通过nginx内网网卡172.16.0.1转发至内网服务器172.16.0.11:80上处理;
4、内网服务器处理完后,将返回信息到nginx的内网口172.16.0.1;
5、nginx的ngx_http_upstream_module模块发现来自upstream的信息,找到用户访问进来时的源IP地址x1.x2.x3.x4,将目的ip地址替换为x1.x2.x3.x4,目的端口替换为y;
6、nginx将源ip替换为自己的公网接口ip192.168.99.10,将数据包返回给用户x1.x2.x3.x4
二、实验nginx反向代理功能
1、实验组网架构
2、实验步骤
准备2台内网服务器133.3.5.144、133.3.5.145,分别在其8000端口上开放httpd服务,并发布一个测试页面在index.html上,主要目的在于标注服务器自身身份。
2.1 内网服务器安装并部署httpd
[root@web1 ~]# yum install -y httpd
[root@web2 ~]# yum install -y httpd
安装完成后执行httpd -v,查看httpd的版本
2.2 部署内网服务器测试页面
vim /etc/httpd/conf/httpd.conf
修改监听端口为8000
在服务器133.3.5.144上部署:echo "<h1>hello world web server 1</h1>" > /var/www/html/index.html
直接通过浏览器访问133.3.5.144的8000端口效果
在服务器133.3.5.145上部署:echo "<h1>hello world web server 2</h1>" > /var/www/html/index.html
2.3 准备一台外网访问服务器133.3.107.3安装nginx并配置反向代理服务
在服务器上安装nginx过程请见前面一篇博文讲如何安装配置nginx的正向代理篇
vim /etc/nginx/nginx.conf
worker_processes 1;
events {
use epoll;
worker_connections 51200;
}
http {
server_names_hash_bucket_size 128;
client_header_buffer_size 32k;
large_client_header_buffers 4 32k;
client_max_body_size 8m;
sendfile on;
tcp_nopush on;
keepalive_timeout 60;
tcp_nodelay on;
fastcgi_connect_timeout 300;
fastcgi_send_timeout 300;
fastcgi_read_timeout 300;
fastcgi_buffer_size 64k;
fastcgi_buffers 4 64k;
fastcgi_busy_buffers_size 128k;
fastcgi_temp_file_write_size 128k;
fastcgi_intercept_errors on;
upstream 133.3.107.3 {
# ip_hash;
fair;
server 133.3.5.144:8000 weight=1;
server 133.3.5.145:8000 weight=1;
}
server {
listen 80;
server_name localhost;
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
client_max_body_size 50m;
client_body_buffer_size 256k;
proxy_connect_timeout 30;
proxy_send_timeout 30;
proxy_read_timeout 60;
proxy_buffer_size 256k;
proxy_buffers 4 256k;
proxy_busy_buffers_size 256k;
proxy_temp_file_write_size 256k;
proxy_next_upstream error timeout invalid_header http_500 http_503 http_404;
proxy_max_temp_file_size 128m;
proxy_pass http://133.3.107.3;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
upstream参数配置说明:
句法: | server |
---|---|
默认: | - |
语境: | upstream |
weight
=number
设置服务器的权重,默认为1。
max_conns
=number
限制与number
代理服务器的同时活动连接的最大值。默认值为零,表示没有限制。
max_fails
=number
设置在fail_timeout
参数设置的持续时间内发生的与服务器通信的不成功尝试次数,以考虑服务器在fail_timeout
参数设置的持续时间内不可用 。默认情况下,不成功尝试次数设置为1.零值禁用尝试的计费。
fail_timeout
=time
- 指定数量的不成功尝试与服务器通信的时间应该考虑服务器不可用;
- 以及服务器被视为不可用的时间段。
默认情况下,参数设置为10秒。
backup
将服务器标记为备份服务器。当主服务器不可用时,它将被传递请求。
down
将服务器标记为永久不可用。
如果需要临时删除其中一个服务器,则应使用该down
参数对其进行标记,以保留客户端IP地址的当前哈希值
max_fails和fail_timeout一般会关联使用,如果某台server在fail_timeout时间内出现了max_fails次连接失败,那么Nginx会认为其已经挂掉了,从而在fail_timeout时间内不再去请求它,fail_timeout默认是10s,max_fails默认是1,即默认情况是只要发生错误就认为服务器挂掉了,如果将max_fails设置为0,则表示取消这项检查。
2.4 验证反向代理效果,通过外网访问nginx外网接口133.3.107.3
可以发现反向代理服务定义了一组服务器分别是133.3.5.144与133.3.5.145,通过ip_hash的模式进行请求负载均衡分配:
指定组应使用负载平衡方法,其中请求根据客户端IP地址在服务器之间分配。客户端IPv4地址的前三个八位字节或整个IPv6地址用作散列密钥。该方法确保来自同一客户端的请求将始终传递到同一服务器,除非此服务器不可用。在后一种情况下,客户端请求将被传递到另一个服务器。最有可能的是,它也将始终是同一台服务器。
2.5 nginx负载均衡调度算法
1、轮询(默认)
每个请求按时间顺序逐一分配到不同的后端服务,如果后端某台服务器死机,自动剔除故障系统,使用户访问不受影响。
upstream backend {
server 192.168.1.11:8888;
server 192.168.1.12:8888;
server 192.168.1.13:8888;
}
2、weight(轮询权值)
weight的值越大分配到的访问概率越高,主要用于后端每台服务器性能不均衡的情况下。或者仅仅为在主从的情况下设置不同的权值,达到合理有效的地利用主机资源。
轮询的加强版,即可以指定轮询比率,weight和访问几率成正比,主要应用于后端服务器异质的场景下。
upstream backend {
server 192.168.1.11 weight=1;
server 192.168.1.12 weight=2;
server 192.168.1.13 weight=3;
}
3、ip_hash
每个请求按访问IP的哈希结果分配,使来自同一个IP的访客固定访问一台后端服务器,并且可以有效解决动态网页存在的session共享问题。
根据客户端IP地址在服务器之间分配。客户端IPv4地址的前三个八位字节或整个IPv6地址用作散列密钥。该方法确保来自同一客户端的请求将始终传递到同一服务器,除非此服务器不可用。在后一种情况下,客户端请求将被传递到另一个服务器。最有可能的是,它也将始终是同一台服务器。
upstream backend {
ip_hash;
server 192.168.1.11:7777;
server 192.168.1.12:8888;
server 192.168.1.13:9999;
}
4、fair
比 weight、ip_hash更加智能的负载均衡算法,fair算法可以根据页面大小和加载时间长短智能地进行负载均衡,也就是根据后端服务器的响应时间 来分配请求,响应时间短的优先分配。Nginx本身不支持fair,如果需要这种调度算法,则必须安装upstream_fair模块。
fair顾名思义,公平地按照后端服务器的响应时间(rt)来分配请求,响应时间短即rt小的后端服务器优先分配请求。
upstream backend {
server 192.168.1.11;
server 192.168.1.12;
server 192.168.1.13;
fair;
}
5、url_hash
按访问的URL的哈希结果来分配请求,使每个URL定向到一台后端服务器,可以进一步提高后端缓存服务器的效率。Nginx本身不支持url_hash,如果需要这种调度算法,则必须安装Nginx的hash软件包。
与ip_hash类似,但是按照访问url的hash结果来分配请求,使得每个url定向到同一个后端服务器,主要应用于后端服务器为缓存时的场景下。
upstream backend {
server 192.168.1.11;
server 192.168.1.12;
server 192.168.1.13;
hash $request_uri;
hash_method crc32;
}
其中,hash_method为使用的hash算法,需要注意的是:此时,server语句中不能加weight等参数。
6、least_conn
将请求传递到具有最少活动连接的服务器,同时考虑服务器的权重。如果有多个这样的服务器,则使用加权循环平衡方法依次尝试它们。
upstream backend {
server 192.168.1.11;
server 192.168.1.12;
server 192.168.1.13;
least_conn;
}
7、least_time header
| last_byte
[inflight
];
请求以最少的平均响应时间和最少的活动连接传递给服务器,同时考虑服务器的权重。如果有多个这样的服务器,则使用加权循环平衡方法依次尝试它们。如果header
指定了参数,则使用接收响应头的时间 。如果last_byte
指定了参数, 则使用接收完整响应的时间。如果inflight
指定了参数(1.11.6),则还会考虑不完整的请求。
upstream backend {
server 192.168.1.11;
server 192.168.1.12;
server 192.168.1.13;
least_time header inflight
;
}
2.6、nginx反向代理负载均衡总结
Nginx负载均衡功能是通过upstream模块实现的,是基于内容和应用的7层交换负载均衡。Nginx负载均衡默认对后端服务器有健康检测能力,但是检测能力较弱,仅限于端口检测,在后端服务器比较少的情况下(10台及以下)负载均衡能力表现突出。
nginx_upstream_check:https://github.com/yaoweibin/nginx_upstream_check_module
nginx-upstream-fair:https://github.com/gnosek/nginx-upstream-fair
nginx-sticky-module:https://github.com/michaelneale/nginx-sticky-module
ngx_cache_purge:https://github.com/FRiCKLE/ngx_cache_purge
2.7 反向代理设置排障
故障现象:设置后端两台服务器为轮询模式,但是通过反向代理模式访问时始终只能选择到一台服务器,首先查看nginx的错误日志
发现从nginx服务器到133.3.5.145超时故障,在nginx上直接ping服务器发现不通,最后检查发现nginx服务器至133.3.5.145内网路由丢失导致。
2.8 nginx安装编译第三方负载均衡模块fair
cd /home
git clone https://github.com/gnosek/nginx-upstream-fair.git
./configure --sbin-path=/usr/local/nginx/nginx --conf-path=/etc/nginx/nginx.conf --pid-path=/usr/local/nginx/nginx.pid --with-http_ssl_module --with-pcre --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --add-module=/home/ngx_http_proxy_connect_module --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --with-compat --with-file-aio --with-threads --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_stub_status_module --with-http_sub_module --with-http_v2_module --without-http_gzip_module --with-mail --with-stream_realip_module --add-module=/home/nginx-upstream-fair
修改/home/nginx-1.15.6/src/http/ngx_http_upstream.h
在ngx_http_upstream_srv_conf_s结构体里新增一行
in_port_t default_port;
make && make install