nginx 会话保持
对于经过NAT网关的用户,nginx可以通过以下几种方式实现会话保持:
1. 基于Cookie的会话保持
1.1 sticky-cookie模块
nginx
upstream backend {
server 192.168.1.10:8080;
server 192.168.1.11:8080;
# 使用sticky cookie实现会话保持
sticky cookie srv_id expires=1h domain=.example.com path=/;
}
1.2 第三方sticky模块
nginx
upstream backend {
server 192.168.1.10:8080;
server 192.168.1.11:8080;
# 使用nginx-sticky-module
sticky;
sticky_hide_cookie upstream=;
}
2. 基于URI的会话保持
nginx
upstream backend {
hash $request_uri consistent;
server 192.168.1.10:8080;
server 192.168.1.11:8080;
}
3. 基于自定义Header的会话保持
nginx
# 提取用户标识Header
map $http_x_user_id $backend_pool {
default "";
"~*" $http_x_user_id;
}
upstream backend {
hash $backend_pool consistent;
server 192.168.1.10:8080;
server 192.168.1.11:8080;
}
4. 应用层会话标识
4.1 基于Session ID
nginx
# 从Cookie中提取session id
map $cookie_jsessionid $session_backend {
default "";
"~*(.+)" $1;
}
upstream backend {
hash $session_backend consistent;
server 192.168.1.10:8080;
server 192.168.1.11:8080;
}
4.2 基于Token
nginx
# 从Authorization头提取token
map $http_authorization $token_backend {
default "";
"~*Bearer\s+(.+)" $1;
}
upstream backend {
hash $token_backend consistent;
server 192.168.1.10:8080;
server 192.168.1.11:8080;
}
5. 完整的NAT用户会话保持配置示例
nginx
http {
# 定义后端服务器组
upstream backend_servers {
# 使用consistent hash算法
hash $consistent_key consistent;
server 192.168.1.10:8080 weight=3;
server 192.168.1.11:8080 weight=2;
server 192.168.1.12:8080 weight=1;
}
# 定义一致性hash的key
# 优先级:session id > user token > 其他标识
map $cookie_sessionid $consistent_key {
default $cookie_sessionid;
"" $http_x_user_token;
}
map $consistent_key $consistent_key_final {
default $consistent_key;
"" $remote_addr$http_user_agent; # 最后回退到IP+UA组合
}
server {
listen 80;
server_name example.com;
location / {
# 设置会话保持cookie(如果应用没有提供)
add_header Set-Cookie "sessionid=$upstream_http_x_session_id; Path=/; HttpOnly" always;
proxy_pass http://backend_servers;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# 健康检查
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
proxy_connect_timeout 30s;
proxy_read_timeout 30s;
}
# 健康检查端点
location /health {
access_log off;
proxy_pass http://backend_servers;
}
}
}
6. 使用Nginx Plus的会话保持功能
如果使用Nginx Plus,可以使用更强大的会话保持功能:
nginx
upstream backend {
zone backend 64k;
server 192.168.1.10:8080;
server 192.168.1.11:8080;
# Nginx Plus的sticky route功能
sticky route $route_cookie $route_uri;
}
7. 针对不同场景的建议
7.1 Web应用场景
nginx
# 优先使用session cookie
map $cookie_jsessionid $backend_key {
default $cookie_jsessionid;
"" $cookie_phpsessid;
}
upstream web_backend {
hash $backend_key consistent;
server 192.168.1.10:8080;
server 192.168.1.11:8080;
}
7.2 API服务场景
nginx
# 使用API token或自定义header
map $http_authorization $api_key {
default $http_authorization;
"" $http_x_api_key;
}
upstream api_backend {
hash $api_key consistent;
server 192.168.1.20:8080;
server 192.168.1.21:8080;
}
注意事项
-
NAT用户特征:同一NAT下的用户共享公网IP,不能依赖源IP进行会话保持
-
会话超时:设置合理的会话超时时间,避免长时间占用服务器资源
-
服务器下线:当后端服务器下线时,相关会话需要重新分配
-
负载均衡:确保会话保持不会导致负载不均衡
-
加密传输:对于敏感信息,建议使用HTTPS加密传输
选择哪种方式取决于你的具体应用场景和技术栈。对于大多数Web应用,基于Cookie的会话保持是最常用且有效的方法。
时来天地皆同力,运去英雄不自由
浙公网安备 33010602011771号