nginx根据X-Forwarded-For实现会话保持
要在 Nginx 的 upstream 配置中使用基于客户端 IP 地址的会话保持(即 Sticky Session),可以结合 hash 方法来实现。通过 hash 指令,我们可以根据客户端的 IP 地址将请求路由到特定的后端服务器,以确保来自同一客户端的请求始终路由到同一个后端服务器。
配置步骤:
1、基于客户端 IP 的 upstream 配置:
- 在 upstream 块中,使用 hash 指令指定基于 IP 地址的会话保持。通常会使用 $clientRealIp 变量(上面提到的客户端真实 IP)来进行 IP 哈希。
2、确保提取到正确的客户端 IP 地址:
- 使用之前的 map 配置来提取客户端的真实 IP 地址并存储在 $clientRealIp 变量中。
3、配置 upstream 使用 hash:
- 使用 hash 指令来基于 $clientRealIp 进行负载均衡,并确保同一客户端的请求始终路由到同一个后端服务器。
示例配置: 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28# 使用 map 提取客户端的真实 IP 地址
map $http_x_forwarded_for $clientRealIp {
"" $remote_addr; # 如果 X-Forwarded-For 为空,使用 remote_addr(即客户端的 IP)
~^(?P<firstAddr>[0-9\.]+),?.*$ $firstAddr; # 提取 X-Forwarded-For 头中的第一个 IP 地址
}
# upstream 配置,基于客户端 IP 进行会话保持
upstream backend {
hash $clientRealIp consistent; # 基于 $clientRealIp 进行哈希负载均衡
server backend1.example.com;
server backend2.example.com;
server backend3.example.com;
}
server {
listen 80;
location / {
# 设置客户端的真实 IP 地址
set_real_ip_from 0.0.0.0/0; # 允许所有 IP 地址作为可信代理
real_ip_header X-Forwarded-For;
real_ip_recursive on; # 启用递归解析 X-Forwarded-For 中的所有代理
# 代理请求到 upstream
proxy_pass http://backend;
}
}
解析配置:
1、map 指令:
- 这里的 map 配置确保我们从 X-Forwarded-For 头中提取到客户端的真实 IP 地址,并将其存储在 $clientRealIp 变量中。
2、hash 指令:
在 upstream 块中,我们使用 hash $clientRealIp 来基于客户端的真实 IP 地址进行负载均衡。consistent 是一致性哈希策略,确保相同的客户端 IP 会被路由到同一个后端服务器。
你可以选择其他哈希策略(例如 zone,key),但是一致性哈希通常能提供更好的会话保持效果。
3、set_real_ip_from 和 real_ip_header:
这些指令告诉 Nginx 使用 X-Forwarded-For 头来获取客户端的真实 IP 地址,而不是直接使用连接的 IP 地址(即代理服务器的 IP)。
real_ip_recursive on 启用递归解析,确保你获取的是最初的客户端 IP,而不是中间代理的 IP。
4、proxy_pass:
- 最后,所有请求都通过 proxy_pass 代理到名为 backend 的 upstream 块。基于客户端的真实 IP,Nginx 会决定将请求路由到哪个后端服务器。
会话保持原理:
哈希机制:每次请求时,Nginx 会计算 $clientRealIp 的哈希值,并根据哈希值决定将请求分发到哪个后端服务器。如果相同的客户端(即具有相同的 IP 地址)再次发送请求,它会被路由到相同的后端服务器。
一致性哈希:一致性哈希算法确保即使有服务器节点的变动(如新增、删除后端服务器),已经分配给客户端的服务器节点尽量不发生变化,从而避免大量的请求重新分配。
其他考虑:
IP 地址变化:如果客户端的 IP 地址发生变化(例如使用了动态 IP 或代理服务器改变了 X-Forwarded-For 的值),可能会影响会话保持。
X-Forwarded-For 头的篡改:要确保信任的代理服务器正确设置 X-Forwarded-For 头,以避免客户端伪造 IP 地址。
通过这种方式,你就能在 Nginx 中实现基于 IP 地址的会话保持,确保相同的客户端始终访问同一台后端服务器。