Day62-Nginx四层负载均衡及结合7层负载均衡实践

news2024/11/24 14:40:16

Day62-Nginx四层负载均衡及结合7层负载均衡实践

  • 1. 什么是四层负载均衡?
  • 2. 四层负载均衡的常用场景
  • 3. 百万并发百亿PV大规模架构
  • 4. L4和L7的区别及常用软件。
  • 5. lvs、nginx、haproxy区别
  • 6. nginx四层负载均衡(tcp/ip,ip:port)
  • 7. nginx四层负载均衡实现主要就是stream模块
    • 7.1 nginx四层负载均衡实践:
  • 8. http_proxy_module相关参数

1. 什么是四层负载均衡?

所谓四层就是OSI模型的传输层,
主要是基于tcp/ip的负载均衡模式,即基于ip和端口的方式实现将请求转发至后端节点。

2. 四层负载均衡的常用场景

1)实现tcp协议的负载均衡
例:对后端服务MySQL从库、以及Redis等服务的负载。
纯粹基于四层的Web应用无法满足当下的负载均衡需求,中小企业直接会选择基于7层的负载均衡模式(nginx proxy)。
见数据库集群架构

2)四层+七层负载均衡架构
在Web前端的7层负载均衡之前,架设四层负载均衡以实现大规模高并发集群架构访问。
四层负载均衡专注于tcp请求的转发,把更复杂的调度(例如:动静分离、业务分离、根据来源设备调度等)交给7层负载均衡处理。
(见大规模集群架构)

在这里插入图片描述

3)如果7层负载业务能够拆分成不同的域名对应的业务,流量拆分,就可以直接用七层。

3. 百万并发百亿PV大规模架构

4. L4和L7的区别及常用软件。

面试题:L4和L7的区别
Layer4 tcp负载均衡 lvs、nginx、haproxy,nginx从1.9.2才支持四层负载。

四层优缺点:
1)基于tcp/ip,即IP+端口的负载均衡
2)四层更快:特别是lvs负载均衡,在内核空间处理,不用走用户空间。处理速度更快
3)四层适合大型站点,处于网站接入层最前端,结合四层+七层使用
(四层放在最前面专注做数据转发,后面可以用七层来继续处理更复杂的业务。一般是结合使用)
4)目前主要应用在后端tcp业务的负载,例如mysql,redis,k8s集群,数据库集群,应用服务器集群。
在这里插入图片描述

七层Layer7优缺点:
1)基于应用层http/https的负载均衡,实现开源软件有nginx、haproxy、F5(硬件)
2)七层功能更多:经内核空间进入用户空间的应用层进行转发。
3)可以实现更复杂的负载均衡控制,比如基于url、session、动静分离等。
4)会占用更多的CPU、内存资源,承载的并发比四层更少。
5)七层适合中小站点Web服务,只使用七层负载均衡

5. lvs、nginx、haproxy区别

LVS优点:
1.基于四层负载,并通过【转发】请求给后端节点实现负载功能。
5万并发,真正的5万并发。
2.内核级转发,效率极高。
3.四种负载模式NAT,DR,TUN,FULLNAT,
其中DR\TUN模式实现单臂路由及数据包返回用户,不在经过负载均衡器本身。
4.DR模式是其常用负载模式。
5.更完善的高可用支持(keepalived)。

LVS缺点:
1.只支持四层负载转发,不能实现基于URL7层转发能功能。
2.最常用的DR模式不支持端口转换功能。

2.nginx和haproxy优点
1.基于四层负载,并通过【代理】代替用户请求后端节点实现负载功能。
2.负载服务器占用双倍连接,并且数据返回依然会经过负载均衡器(收费站模式,不需要设置网关)。
3.既可以实现四层负载,还可以实现7层负载。
4.还可以实现web服务及缓存功能(nginx专有,haproxy仅专注于代理)
5.nginx作为Web和7层负载更流行(使用的人更多)

nginx和haproxy缺点:
1.效率及并发能力不如LVS,代理模式。
2.nginx四层负载太新(近几年才开发出来。)。
3.haproxy做负载更专业,但没有nginx在web上使用更流行。

企业中到底如何选择?
1.需要四层负载且高并发(3万以上),选LVS,否则就选nginx或haproxy。
2.nginx有web服务及缓存功能及4和7层负载功能,且配置简单(常规选Nginx)。
3.haproxy仅专注于负载均衡,在负载算法和健康检查等好于nginx,但不足以让普通用户选择。

6. nginx四层负载均衡(tcp/ip,ip:port)

扩展作业:haproxy负载搞定

通过ip:port实现负载均衡

Nginx负载形式,基于【代理】的方式,而非转发的模式。
场景1: 基于四层IP+端口代理
场景2: 四层结合七层(实现4,7层由不同的负载均衡器调度)

LVS负载形式,基于【转发】请求方式(内核级别转发)
场景1: 基于四层(NAT\DR\tun\fullnat)转发
场景2: 四层+七层实现大规模高并发集群场景
在这里插入图片描述

7. nginx四层负载均衡实现主要就是stream模块

1)stream模块官方说明:
链接: http://nginx.org/en/docs/stream/ngx_stream_core_module.html#stream

The ngx_stream_core_module module is available since version 1.9.0. This module is not built by default, it should be enabled with the --with-stream configuration parameter.

2)检查nginx支持–with-stream情况

nginx -V 2>oldboy.log
egrep '\-\-with-stream' oldboy.log 

3)学员博客:
链接: https://www.cnblogs.com/gongjingyun123–/p/11424424.html

4)stream模块语法

Syntax:	stream { ... }
Default:	—
Context:	main	

7.1 nginx四层负载均衡实践:

1)环境
lb4-01 10.0.0.15
lb4-02 10.0.0.16
克隆10.0.0.5为10.0.0.15,目的是不用安装nginx和keepalived了。
克隆10.0.0.6为10.0.0.16,目的是不用安装nginx和keepalived了。

2)安装nginx+keepalived(默认装好了)

3)生产场景1:实现MySQL数据库负载均衡
四层代理:10.0.0.15 172.16.1.15
DB节点:172.16.1.7 172.16.1.51
在这里插入图片描述

步骤:
1.克隆10.0.0.15
2.检查负载的节点正常172.16.1.7 172.16.1.51
3.配置lb4-01 10.0.0.15
4.测试

[root@lb4-01 ~]# vim /etc/nginx/nginx.conf +12

#注意要在http标签外面加上如下几行
stream {
    include /etc/nginx/stream_conf.d/*.conf;
}
mkdir /etc/nginx/stream_conf.d/
[root@lb4-01 nginx]# cd /etc/nginx/stream_conf.d/
[root@lb4-01 stream_conf.d]# cat 01_lb4-mysql.conf 
		upstream mysql{
			server 172.16.1.51:3306;
			server 172.16.1.7:3306;  #开启mariadb
		}
		server {
			listen 3306;  #监听的机器本地不能有3306端口。
			proxy_pass mysql;
		}

nginx -t
systemctl restart nginx

注意:此场景用于代理各类tcp应用,比如,k8s集群,数据库集群,中间件应用服务器集群。

注意:
1.nginx.conf里不允许多个stream标签。
2.stream标签配置为主配置文件nginx.conf main区段。
3.可以在主配置的stream标签里嵌入include /etc/nginx/stream_conf.d/*.conf;

4)安装Navicat for MySQL或使用Phpmyadmin进行测试
在这里插入图片描述

5)场景2:实现nginx4层+Nginx多七层代理+多Web节点
大并发: www:10.0.0.15-----10.0.0.5/10.0.0.6----->172.16.1.7/172.16.1.7
不需要高并发:blog:10.0.0.5/10.0.0.6----->172.16.1.7/172.16.1.7
在这里插入图片描述

四层代理:10.0.0.15 172.16.1.15
四层代理:10.0.0.16 172.16.1.16

L7层代理:172.16.1.5 172.16.1.5
L7层代理:172.16.1.6 172.16.1.6

Web节点:172.16.1.7 172.16.1.8

1)四层负载均衡(lb4-01) 10.0.0.15:
完整配置如下:

[root@lb4-01 stream_conf.d]# cat 02_web.conf 
         upstream proxy_7 {
            server 10.0.0.5:80;
            server 10.0.0.6:80;
        }
		server {
			listen 80;
			proxy_pass proxy_7; #注意,不带HTTP。
			#proxy_protocol on;  #开启proxy_protocol协议
	}

注意别忘了:
1.stream里的监听80端口不能和7层的监听80冲突。
因此,注释结尾 #include /etc/nginx/conf.d/*.conf;
2.指定VIP listen 10.0.0.17:80;

nginx -t
systemctl restart nginx

七层负载均衡(lb01,lb02)

[root@lb01 conf.d]# cat 03_www.etiantian.org.conf
upstream www {
    server 172.16.1.7       weight=1 ; #默认80端口 
    server 172.16.1.8       weight=1; #默认80端口
}
server {
	listen 80;
	server_name www.etiantian.org;
location / {
        proxy_pass http://www;
         proxy_set_header Host $http_host;
	}
}
nginx -t
systemctl restart nginx


[root@lb02 conf.d]# cat 03_www.etiantian.org.conf 
upstream www {
    server 172.16.1.7       weight=1 ; #默认80端口 
    server 172.16.1.8       weight=1; #默认80端口
}
server {
	listen 80;
	server_name www.etiantian.org;
location / {
        proxy_pass http://www;
         proxy_set_header Host $http_host;
	}
}

nginx -t
systemctl restart nginx

部署web01,web02

[root@lb01 conf.d]# curl -H"host:www.etiantian.org" 172.16.1.7
web01
[root@lb01 conf.d]# curl -H"host:www.etiantian.org" 172.16.1.8
web02

[root@web02 conf.d]# cat 02_www.etiantian.org.conf 
server {
	listen 80;
	server_name www.etiantian.org;
	root /data/www;
	location / {
		index index.html;
	}
}

必要测试步骤;测试早前配置的7层代理情况

[root@lb4-01 nginx]# curl -H"host:www.etiantian.org" 10.0.0.5
web01
[root@lb4-01 nginx]# curl -H"host:www.etiantian.org" 10.0.0.5
web02

[root@lb4-01 nginx]# curl -H"host:www.etiantian.org" 10.0.0.6
web01
[root@lb4-01 nginx]# curl -H"host:www.etiantian.org" 10.0.0.6
web02

测试L4(15)---L7(5,6)--->Web(7,8)
[root@web02 conf.d]# curl -H"host:www.etiantian.org" 10.0.0.15
web01
[root@web02 conf.d]# curl -H"host:www.etiantian.org" 10.0.0.15
web01
[root@web02 conf.d]# curl -H"host:www.etiantian.org" 10.0.0.15
web02
[root@web02 conf.d]# curl -H"host:www.etiantian.org" 10.0.0.15
web02

3)Nginx四层负载结合七层负载获取【真实用户IP地址】
从web01上看上述访问日志:

172.16.1.6 - - [01/Aug/2021:15:44:06 +0800] "GET / HTTP/1.0" 200 6 "-" "curl/7.29.0" "-"
172.16.1.5 - - [01/Aug/2021:15:47:22 +0800] "GET / HTTP/1.0" 200 6 "-" "curl/7.29.0" "-"
172.16.1.6 - - [01/Aug/2021:15:47:23 +0800] "GET / HTTP/1.0" 200 6 "-" "curl/7.29.0" "-"
172.16.1.5 - - [01/Aug/2021:15:47:25 +0800] "GET / HTTP/1.0" 200 6 "-" "curl/7.29.0" "-"

web01上的客户IP为7层代理,结尾的真实IP为-。

场景3:实现nginx4层+Nginx多七层代理+多Web节点【获取真实用户IP地址】

四层负载均衡
链接: http://nginx.org/en/docs/stream/ngx_stream_proxy_module.html
1)开启proxy_protocol协议
proxy_protocol on;
2)语法

Syntax:	proxy_protocol on | off;
Default:	
proxy_protocol off;
Context:	stream, server
This directive appeared in version 1.9.2.

Enables the PROXY protocol for connections to a proxied server.		
http://www.haproxy.org/download/1.5/doc/proxy-protocol.txt		

使用PROXY protocol获取客户IP
链接: https://www.nixops.me/articles/PROXY_protocol_pass_client_ip.html

使用PROXY protocol获取客户IP
8月 29日, 2017年
获取客户IP是常见的需求,对于大流量的项目都会使用反向代理、负载均衡等,甚至多重代理,导致架构和网络都比较复杂,在这种情况下获取IP就不那么容易了。七层代理可以通过添加头信息来实现,如http协议的X-Forword-For,还比较方便;四层代理基本无法简单的获取到客户端IP地址,像LVS的FULLNAT模式,前端LVS把真实IP写在TCP option里面,后端服务器用内核toa模块获取客户IP;haproxy配合TPROXY也是类似的方式实现,两者都需编译内核非常麻烦,这种情况下就可以考虑使用代理协议

一、代理协议简介
代理协议即 PROXY protocol,是haproxy的作者Willy Tarreau于2010年开发和设计的一个Internet协议,通过为tcp添加一个很小的头信息,来方便的传递客户端信息(协议栈、源IP、目的IP、源端口、目的端口等),在网络情况复杂又需要获取客户IP时非常有用。如:

多层NAT网络
TCP代理(四层)或多层tcp代理
https反向代理http(某些情况下由于Keep-alive导致不是每次请求都传递x-forword-for)

代理协议分为v1和v2两个版本,v1人类易读,v2是二进制格式,方便程序处理。Proxy protocol是比较新的协议,但目前已经有很多软件支持,如haproxy、nginx、apache、squid、mysql等等,要使用proxy protocol需要两个角色sender和receiver,sender在与receiver之间建立连接后,会先发送一个带有客户信息的tcp header,因为更改了tcp协议,需receiver也支持proxy protocol,否则不能识别tcp包头,导致无法成功建立连接。

配置开启proxy_protocol,lb4-01(10.0.0.15)

[root@lb4-01 stream_conf.d]# cat 02_web.conf 
         upstream proxy_7 {
            server 172.16.1.5:80;
            #server 172.16.1.6:80;
        }
		server {
			listen 80;
			proxy_pass proxy_7; #注意,不带HTTP。
			proxy_protocol on;  #开启proxy_protocol协议==================
	}

七层负载均衡(lb01,lb02)10.0.0.5/6

		upstream www {
			server 172.16.1.7:80;
			server 172.16.1.8:80;
		}
		server {
			 listen 80 proxy_protocol;       #添加proxy_protocol
			 server_name www.etiantian.org;
              set_real_ip_from 172.16.1.0/24;  #添加七层负载前经过的代理IP地址
              real_ip_header proxy_protocol;   #将proxy_protocol获取的IP赋值给$remote_addr	
			 location / {
			 proxy_pass http://www;
              proxy_set_header Host $http_host;
              proxy_set_header X-Forwarded-For $proxy_protocol_addr;
			 #将proxy_protocol真实客户端的IP地址赋值给X-Forwarded-For变量携带至后端
			 proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
			}
		}

web01:
配置之前的日志

172.16.1.5 - - [01/Aug/2021:16:03:40 +0800] "GET / HTTP/1.0" 200 6 "-" "curl/7.29.0" "-"
172.16.1.5 - - [01/Aug/2021:16:03:41 +0800] "GET / HTTP/1.0" 200 6 "-" "curl/7.29.0" "-"

lb4-01上测试已经获取到客户端地址

172.16.1.5 - - [01/Aug/2021:16:04:09 +0800] "GET / HTTP/1.0" 200 6 "-" "curl/7.29.0" "10.0.0.15"
172.16.1.5 - - [01/Aug/2021:16:04:10 +0800] "GET / HTTP/1.0" 200 6 "-" "curl/7.29.0" "10.0.0.15"

windows浏览器测试获取到客户端地址10.0.0.1

172.16.1.5 - - [01/Aug/2021:16:04:58 +0800] "GET / HTTP/1.0" 200 6 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.212 Safari/537.36" "10.0.0.1"
172.16.1.5 - - [01/Aug/2021:16:05:02 +0800] "GET / HTTP/1.0" 200 6 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.212 Safari/537.36" "10.0.0.1"
172.16.1.5 - - [02/Aug/2021:17:31:50 +0800] "GET / HTTP/1.0" 200 6 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.212 Safari/537.36" "10.0.0.1"

测试众多nginx http变量值

[root@web01 conf.d]# cat 02_www.etiantian.org.conf 
server {
	listen 80;
	server_name www.etiantian.org;
	root /data/www;
	
    location / {
	     #index index.html;
         return 200 "web01,老男孩Linux77最优班级\n 
         remote_addr: $remote_addr\n 
         proxy_add_x_forwarded_for:$proxy_add_x_forwarded_for\n
         proxy_protocol_addr: $proxy_protocol_addr\n
         http_x_forwarded_for:$http_x_forwarded_for\n";
     }
}

从DB01访问:10.0.0.51—10.0.0.15----172.16.1.5----172.16.1.7

[root@db01 ~]# curl -H"host:www.etiantian.org" 10.0.0.15
web01,老男孩Linux77最优班级
remote_addr: 172.16.1.5
proxy_add_x_forwarded_for:10.0.0.51, 172.16.1.5
http_x_forwarded_for:10.0.0.51

更改web01主配置日志测试:

log_format  access '-$proxy_protocol_addr-,--$remote_addr--,---$http_x_forwarded_for---,----$proxy_add_x_forwarded_for----,$remote_user,$time_local,$host,$request,$status,$http_referer,$HTTP_X_UP_CALLING_LINE_ID,$request_time,$http_user_agent  $upstream_addr  $upstream_response_time  $upstream_cache_status';
access_log  /var/log/nginx/access.log  access;
---, --172.16.1.5--,---10.0.0.51, 10.0.0.15---,----10.0.0.51, 10.0.0.15, 172.16.1.5----
-$proxy_protocol_addr-,--$remote_addr--,---$http_x_forwarded_for---,----$proxy_add_x_forwarded_for----

日志结果:

[root@web01 conf.d]# tail /var/log/nginx/access.log
---,--172.16.1.5--,---10.0.0.51---,----10.0.0.51, 172.16.1.5----,-,01/Aug/2021:17:17:29 +0800,www.etiantian.org,GET / HTTP/1.0,200,-,-,0.000,curl/7.29.0  -  -  -
---,--172.16.1.5--,---10.0.0.51---,----10.0.0.51, 172.16.1.5----,-,01/Aug/2021:17:17:31 +0800,www.etiantian.org,GET / HTTP/1.0,200,-,-,0.000,curl/7.29.0  -  -  -

nginx多层代理获取客户端的真实ip总结:
1、要有http_realip_module模块支持
2、在nginx.conf文件中

proxy_pass http://www; #添加下面三行
proxy_set_header   Host             $host;
proxy_set_header   X-Real-IP        $remote_addr;
proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;

3、在每一层nginx日志中的打印的"$http_x_forwarded_for"就是真实客户端的ip地址。
4、后台服务器获取真实的客户端ip地址:
headers中的X-Forwarded-For选项中逗号前第一个ip就是真实客户端ip
日志中获取真实ip: $http_x_forwarded_for 就是获取真实ip的变量

log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                     '$status $body_bytes_sent "$http_referer" '
                     '"$http_user_agent" "$http_x_forwarded_for"';

提示:
1、set_real_ip_from 是指接受从哪个信任前代理处获得真实用户ip
2、real_ip_header 是指从接收到报文的哪个http首部去获取前代理传送的用户ip
3、real_ip_recursive 是否递归地排除直至得到用户ip(默认为off)
首先,real_ip_header 指定一个http首部名称,默认是X-Real-Ip,假设用默认值的话,nginx在接收到报文后,会查看http首部X-Real-Ip。
(1)如果有1个IP,它会去核对,发送方的ip是否在set_real_ip_from指定的信任ip列表中。如果是被信任的,它会去认为这个X-Real-Ip中的IP值是前代理告诉自己的,用户的真实IP值,于是,它会将该值赋值给自身的$remote_addr变量;如果不被信任,那么将不作处理,那么$remote_addr还是发送方的ip地址。
(2)如果X-Real-Ip有多个IP值,比如前一方代理是这么设置的:proxy_set_header X-Real-Ip $proxy_add_x_forwarded_for;
得到的是一串IP,那么此时real_ip_recursive的值就至关重要了。nginx将会从ip列表的右到左,去比较set_real_ip_from 的信任列表中的ip。
如果real_ip_recursive为off,那么,当最右边一个IP,发现是信任IP,即认为下一个IP(右边第二个)就是用户的真正IP;
如果real_ip_recursive为on,那么将从右到左依次比较,知道找到一个不是信任IP为止。
然后同样把IP值复制给$remote_addr。

8. http_proxy_module相关参数

在这里插入图片描述

相关重要参数 参数说明
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-Forwarded-For字段信息,用于后端服务器程序、日志等接收记录真实用户的IP,而不是代理服务器IP。
这是反向代理时,节点服务器获取用户真实IP的必要功能配置

[root@web02 conf.d]# tail -f /var/log/nginx/access.log
172.16.1.5 - - [02/Aug/2021:16:45:59 +0800] "GET / HTTP/1.0" 200 6 "-" "curl/7.29.0" "-"
172.16.1.5 - - [02/Aug/2021:16:46:00 +0800] "GET / HTTP/1.0" 200 6 "-" "curl/7.29.0" "-"

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  /var/log/nginx/access.log  main;

结果:

$remote_addr 172.16.1.5
$http_x_forwarded_for -

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

[root@lb01 conf.d]# cat 03_www.etiantian.org.conf
upstream www {
 server 172.16.1.7       weight=1 ; #默认80端口 
 server 172.16.1.8       weight=1; #默认80端口
}
server {
listen 80;
server_name www.etiantian.org;
location / {
     proxy_pass http://www;
     proxy_set_header Host $http_host;
     proxy_set_header X-Forwarded-For $remote_addr;
#<==在代理向后端服务器发送的http请求头中加入X-Forwarded-For字段信息,用于后端服务器程序、日志等接收记录真实用户的IP,而不是代理服务器的IP。
     }
}
[root@lb01 conf.d]# nginx -t 
[root@lb01 conf.d]# systemctl restart nginx

测试:使用DB01或者浏览器测试

[root@db01 ~]# curl -H"host:www.etiantian.org" 172.16.1.5
web01
[root@db01 ~]# curl -H"host:www.etiantian.org" 172.16.1.5
web02

[root@web02 conf.d]# tail -f /var/log/nginx/access.log
172.16.1.5 - - [02/Aug/2021:16:45:59 +0800] "GET / HTTP/1.0" 200 6 "-" "curl/7.29.0" "-"
172.16.1.5 - - [02/Aug/2021:16:46:00 +0800] "GET / HTTP/1.0" 200 6 "-" "curl/7.29.0" "-"
172.16.1.5 - - [02/Aug/2021:16:51:21 +0800] "GET / HTTP/1.0" 200 6 "-" "curl/7.29.0" "172.16.1.5"
172.16.1.5 - - [02/Aug/2021:16:51:52 +0800] "GET / HTTP/1.0" 200 6 "-" "curl/7.29.0" "172.16.1.51"
172.16.1.5 - - [02/Aug/2021:16:52:23 +0800] "GET /favicon.ico HTTP/1.0" 404 555 "http://www.etiantian.org/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.212 Safari/537.36" "10.0.0.1"
172.16.1.5 - - [02/Aug/2021:16:52:25 +0800] "GET /favicon.ico HTTP/1.0" 404 555 "http://www.etiantian.org/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.212 Safari/537.36" "10.0.0.1"
172.16.1.5 - - [02/Aug/2021:16:52:28 +0800] "GET / HTTP/1.0" 200 6 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.212 Safari/537.36" "10.0.0.1"
172.16.1.5 - - [02/Aug/2021:16:52:28 +0800] "GET / HTTP/1.0" 200 6 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.212 Safari/537.36" "10.0.0.1"

看结尾$http_x_forwarded_for列如果出现访问的客户的真实IP就对了
浏览器访问的结果,真实IP是10.0.0.1,如果通过db01访问真实IP就是172.16.1.51

结果:

$remote_addr依然是172.16.1.5,上级代理IP
$http_x_forwarded_for 10.0.0.1

nginx反向代理的若干参数说明:
fastcgi_pass
链接: http://nginx.org/en/docs/http/ngx_http_fastcgi_module.html
proxy_pass
链接: http://nginx.org/en/docs/http/ngx_http_proxy_module.html
uwsgi_pass
链接: http://nginx.org/en/docs/http/ngx_http_uwsgi_module.html

扩展:搭建nginx cache服务 作为静态web服务的前端缓存。

链接: https://blog.csdn.net/dengjiexian123/article/details/53386586
在这里插入图片描述

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1557942.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

python多方式操作elasticsearch介绍

python多方式操作elasticsearch介绍 1. requests模块操作ES ​ requests 是一个 Python HTTP 库&#xff0c;它简化了发送 HTTP 请求和处理响应的过程。通过 requests 模块&#xff0c;开发人员可以轻松地与 Web 服务进行通信&#xff0c;包括获取网页内容、执行 API 请求等。…

JavaScript(一)---【js的两种导入方式、全局作用域、函数作用域、块作用域】

一.JavaScript介绍 1.1什么是JavaScript JavaScript简称“js”&#xff0c;js与java没有任何关系。 js是一种“轻量级、解释型、面向对象的脚本语言”。 二.JavaScript的两种导入方式 2.1内联式 在HTML文档中使用<script>标签直接引用。 <script>console.log…

跨越时空,启迪智慧:奇趣相机重塑儿童摄影与教育体验

【科技观察】近期&#xff0c;奇趣未来公司以其创新之作——“奇趣相机”微信小程序&#xff0c;强势进军儿童AI摄影市场。这款专为亚洲儿童量身定制的应用&#xff0c;凭借精准贴合亚洲儿童面部特征的AIGC大模型&#xff0c;以及丰富的摄影模板与场景设定&#xff0c;正在重新…

【每日跟读】常用英语500句(400~500)

【每日跟读】常用英语500句 Where can I buy a ticket? 在哪里能买到票&#xff1f; When is the next train? 下趟火车什么时候到&#xff1f; Thank you so much for helping me move yesterday. 非常感谢你昨天帮我搬家 I’m feeling a little under the weather toda…

与webpack类似的工具还有哪些?区别?

文章目录 一、模块化工具二、详细对比RollupParcelSnowpackVitewebpack 参考文献 一、模块化工具 模块化是一种处理复杂系统分解为更好的可管理模块的方式 可以用来分割&#xff0c;组织和打包应用。每个模块完成一个特定的子功能&#xff0c;所有的模块按某种方法组装起来&a…

吴恩达2022机器学习专项课程(一) 4.1 梯度下降

问题预览 梯度下降算法的作用是&#xff1f;梯度下降的过程&#xff1f;梯度下降和最小化成本函数的联系&#xff1f;所有的成本函数都是一个形状吗&#xff1f;在非凸形状中&#xff0c;梯度下降的更新过程是&#xff1f;在非凸形状中&#xff0c;不同的初值对最小化成本函数…

量化交易入门(三十二)什么是BIAS指标以及它的优缺点

BIAS&#xff0c;中文名称为“乖离率”&#xff0c;是量化交易中常用的一种技术指标&#xff0c;主要用于衡量价格偏离移动平均线的程度。下面我将从原理、优缺点和应用三个方面对BIAS指标进行详细讲解。 一、BIAS指标的原理 BIAS指标的计算公式为&#xff1a;BIAS(当前收盘价…

车载电子电器架构 —— 电气架构释放检查

车载电子电器架构 —— 电气架构释放检查 我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 屏蔽力是信息过载时代一个人的特殊竞争力,任何消耗你的人和事,多看一眼都是你的不对。非必要不费力证明…

Android vehicle车辆属性新增demo

目录 前言一、Vehicle模块1.1 简介1.2 Vehicle框架1.3 主要功能和特点1.4 重要服务CarService1.4.1 简介1.4.2 组成1.4.3 启动时序1.4.4 作用 二、车辆属性新增demo2.1 CarPropertyService2.1.1 简介2.1.2 架构2.1.3 车辆属性 API2.1.4 CarPropertyService 初始化流程 2.2 App …

Sentinel原理及实践

Sentinel 是什么 Sentinel 是面向分布式、多语言异构化服务架构的流量治理组件&#xff0c;主要以流量为切入点&#xff0c;从流量路由、流量控制、流量整形、熔断降级、系统自适应过载保护、热点流量防护等多个维度来帮助开发者保障微服务的稳定性。 为什么使用sentinel&…

RIP环境下的MGRE 综合实验

实验题目及要求&#xff1a; 1.R5为ISP&#xff0c;只能进行IP地址配置&#xff0c;其所有地址均配为公有IP地址 2.R1和R5间使用PPP的PAP认证&#xff0c;R5为主认证方; R2于R5之间使用PPP的chap认证&#xff0c;R5为主认证方&#xff1b; R3于R5之间使用HDLC封装。 3.R1/…

数据链路层之信道:数字通信的桥梁与守护者

✨✨ 欢迎大家来访Srlua的博文&#xff08;づ&#xffe3;3&#xffe3;&#xff09;づ╭❤&#xff5e;✨✨ &#x1f31f;&#x1f31f; 欢迎各位亲爱的读者&#xff0c;感谢你们抽出宝贵的时间来阅读我的文章。 我是Srlua小谢&#xff0c;在这里我会分享我的知识和经验。&am…

LeetCode 双指针专题

11.盛最多水的容器 给定一个长度为 n 的整数数组 height 。有 n 条垂线&#xff0c;第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 。 找出其中的两条线&#xff0c;使得它们与 x 轴共同构成的容器可以容纳最多的水。 返回容器可以储存的最大水量。 说明&#xff1a;你不…

Kubeflow文档1:介绍与架构

Kubeflow 2024/3/19版本的文档 此专栏用来展示相关的内容翻译&#xff0c;重点关注本地部署&#xff0c;关于运营商的方案&#xff0c;请自行查阅 文档地址https://www.kubeflow.org/docs/ 开始编辑时间&#xff1a;2024/3/27&#xff1b;最后编辑时间2024/3/27 Kubeflow文…

【Hello,PyQt】QTextEdit和QSplider

PyQt5 是一个强大的Python库&#xff0c;用于创建图形用户界面&#xff08;GUI&#xff09;。其中&#xff0c;QTextEdit 控件作为一个灵活多用的组件&#xff0c;常用于显示和编辑多行文本内容&#xff0c;支持丰富的格式设置和文本操作功能。另外&#xff0c;QSlider 控件是一…

java数据结构与算法刷题-----LeetCode1091. 二进制矩阵中的最短路径

java数据结构与算法刷题目录&#xff08;剑指Offer、LeetCode、ACM&#xff09;-----主目录-----持续更新(进不去说明我没写完)&#xff1a;https://blog.csdn.net/grd_java/article/details/123063846 文章目录 广度优先双分裂蛇 广度优先双分裂蛇 双分裂蛇&#xff1a;是求二…

上门家政按摩H5小程序源码

《服务器环境配置》 1、服务器环境&#xff1a;CentOS7 宝塔 Nginx php 2、环境&#xff1a;PHP7.2 MySQL5.6 3、安装扩展&#xff1a;fileinfo、redis 《程序安装配置》 1、新建站点及数据库&#xff0c;然后申请创建SSL证书&#xff0c;配置到站点&#xff0c;开启强…

LeetCode Python - 84. 柱状图中最大的矩形

目录 题目描述解法方法一方法二 运行结果方法一方法二 题目描述 给定 n 个非负整数&#xff0c;用来表示柱状图中各个柱子的高度。每个柱子彼此相邻&#xff0c;且宽度为 1 。 求在该柱状图中&#xff0c;能够勾勒出来的矩形的最大面积。 示例 1: 输入&#xff1a;heights …

“崖山数据库杯”深圳大学程序设计竞赛(正式赛)M题 一图秒

“崖山数据库杯”深圳大学程序设计竞赛&#xff08;正式赛&#xff09;_ACM/NOI/CSP/CCPC/ICPC算法编程高难度练习赛_牛客竞赛OJ (nowcoder.com) —————— 可以去牛客看题解&#xff1a; 题解 | #暂时没想法#_牛客博客 (nowcoder.net) —————— 上面的就是题解了。…

CKS之安全沙箱运行容器:gVisor

目录 一、gVisor介绍 二、gVisor架构 三、gVisor使用前置条件 四、Docker中使用gVisor 五、containerd中使用gVisor 六、Kubernetes结合gVisor使用 一、gVisor介绍 gVisor是Google开源的一种容器沙箱技术&#xff0c;其设计初衷是在提供较高安全性的同时&#xff0c;尽量…