找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

328

积分

0

好友

44

主题
发表于 22 小时前 | 查看: 7| 回复: 0

负载均衡策略:ip_hash / hash 会话保持

1. 为何需要会话保持?

在经典的轮询(Round Robin)负载均衡策略下,来自同一客户端的请求可能会被分发到不同的后端服务器上。这适用于AKF扩展立方体中的X轴水平扩展场景。然而,若要实现Z轴扩展,即确保特定用户或客户端的请求总是被转发到同一台上游服务器,从而实现会话(Session)的持久化,就需要借助哈希算法。Nginx提供了ip_hashhash两种负载均衡策略来满足这一需求。

负载均衡与会话保持关系示意图

2. 核心算法解析

在 upstream 模块中,ip_hashhash是实现会话保持的关键指令:

  • ip_hash:根据客户端的IP地址进行哈希计算以决定路由。默认使用$remote_addr变量作为关键字,IPv4地址取前3个字节,IPv6则使用完整地址。该算法不受服务器权重(weight)影响ip_hash模块默认编译进Nginx核心。
  • hash:根据任意指定的字符串或变量进行哈希计算。你可以基于URL参数、Cookie值等自定义关键字,该算法同样不受服务器权重影响hash模块也默认编译进Nginx。
# 基于客户端IP地址哈希的负载均衡方法。
# Syntax: ip_hash;
# Default: —
# Context: upstream

# 基于指定键值哈希的负载均衡方法。
# Syntax: hash key [consistent];
# Default: —
# Context: upstream

关键前提:获取真实客户端IP 在实际生产环境中,Nginx前方通常存在CDN、负载均衡器等代理链。为了确保ip_hash基于真实的客户端IP进行计算,必须正确配置以提取原始IP。这依赖于 http_realip_module 模块,它默认未编译,需要通过 --with-http_realip_module 选项启用。

核心配置指令包括:

  • set_real_ip_from:指定可信的代理服务器IP段。
  • real_ip_header:指定包含真实IP的HTTP头部字段(如 X-Forwarded-For)。
  • real_ip_recursive:启用递归查找,跳过所有可信代理IP,取第一个不可信IP作为真实客户端IP。

关于Nginx处理请求的十一个阶段及realip模块的详细实践,可深入阅读 网络/系统 相关文章进行系统学习。若未启用该模块,配置时可能会遇到 unknown directive "set_real_ip_from" 错误。

3. ip_hash 负载均衡实践

环境准备

创建两个测试后端服务器:

  • 服务器A (10.20.172.213):监听 8010 端口。
  • 服务器B (10.20.172.214):监听 8011 和 8012 端口。

配置示例 (/usr/local/nginx/conf.d/server.conf):

# 在 10.20.172.214 主机上配置
server {
    listen 8011;
    return 200 'From 8011 server response!\n';
}
server {
    listen 8012;
    return 200 'From 8012 server response!\n';
}

# 在 10.20.172.213 主机上配置
server {
    listen 8010;
    return 200 'From 10.20.172.213:8010 server response!\n';
}
Nginx 反向代理配置

编辑代理配置文件 (proxy_server_iphash.conf),启用 ip_hash

upstream backend {
    ip_hash; # 启用IP哈希负载均衡
    server 127.0.0.1:8011 weight=2;  # 权重设置对ip_hash无效
    server 127.0.0.1:8012;
    server 10.20.172.213:8010 max_fails=2 fail_timeout=10s;
    keepalive 10;
}

server {
    listen 80;
    server_name test.weiyigeek.top;

    # 从代理链中提取真实客户端IP,这是ip_hash生效的关键
    set_real_ip_from 10.20.172.0/24;
    real_ip_recursive on;
    real_ip_header X-Forwarded-For;

    location / {
        proxy_pass http://backend;
        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_http_version 1.1;
        proxy_set_header Connection "";
    }
}
验证结果

重启Nginx服务后,使用curl进行测试:

# 同一客户端IP多次请求
for i in $(seq 1 5); do curl http://test.weiyigeek.top; done
# 输出始终指向同一台后端服务器(例如 8011)

# 模拟不同客户端IP
for i in $(seq 1 5); do curl -H 'X-Forwarded-For: 100.10.2.215' http://test.weiyigeek.top; done
for i in $(seq 1 5); do curl -H 'X-Forwarded-For: 100.10.12.215' http://test.weiyigeek.top; done
# 不同IP可能被哈希到不同的后端服务器

ip_hash负载均衡效果验证图

结论ip_hash确保了同一客户端IP的所有请求都落在固定的后端服务器上,完美实现了会话保持,且不同IP的请求被均匀(哈希)分布到不同后端。

4. hash 负载均衡实践

Nginx 配置调整

将负载均衡策略改为基于URL参数的hash算法:

upstream backend {
    hash $arg_user; # 基于请求参数 `user` 的值进行哈希计算
    server 127.0.0.1:8011 weight=2;  # 权重设置对hash同样无效
    server 127.0.0.1:8012;
    server 10.20.172.213:8010 max_fails=2 fail_timeout=10s;
    keepalive 10;
}
# server 部分配置与上文相同,可省略提取真实IP的配置,因为hash不依赖IP。
验证结果
# 相同user参数请求
for i in $(seq 1 5); do curl http://test.weiyigeek.top?user=weiyigeek; done
# 输出始终指向同一台后端服务器

# 不同user参数请求,即使客户端IP相同
for i in $(seq 1 5); do curl -H 'X-Forwarded-For: 100.10.2.215' http://test.weiyigeek.top?user=WeiyiGeek; done
for i in $(seq 1 5); do curl -H 'X-Forwarded-For: 100.10.2.215' http://test.weiyigeek.top?user=Geek; done
# user值不同,请求被路由到不同的后端服务器

hash负载均衡效果验证图

结论hash算法基于自定义的关键字(如$arg_user)实现会话保持。只要关键字不变,请求就会固定转发到特定后端,完全不受客户端IP和服务器权重影响,灵活性远高于ip_hash

5. 总结与注意事项

通过上述实践,我们验证了ip_hashhash算法都能有效实现会话保持,是构建AKF扩展立方体中Z轴扩展(数据分区)的基础。hash算法因其可定制性,应用场景更为广泛。

重要警告: 使用标准哈希算法时,切忌直接从上upstream配置中移除宕机或下线的后端服务器。因为节点列表的改变会导致整个哈希环(Hash Ring)发生变化,引发大规模的路由重映射。这意味着大量用户的会话会因路由到新服务器而中断,缓存也可能全面失效,对线上服务是灾难性的。这正是 运维/DevOps 工作中需要密切关注的容量管理与变更风险。

为了解决节点动态增减带来的问题,Nginx的hash指令支持consistent参数,用于启用一致性哈希算法。它能极大程度地缓解节点变动带来的影响,是生产环境更推荐的选择。在后续的 数据库/中间件 优化专题中,我们将深入探讨一致性哈希的原理与配置实践。




上一篇:Nginx负载均衡配置实战:详解round-robin加权轮询算法与故障处理
下一篇:Linux核心哲学:深入理解“一切皆是文件”提升系统管理能力
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区(YunPan.Plus) ( 苏ICP备2022046150号-2 )

GMT+8, 2025-12-6 23:54 , Processed in 0.105227 second(s), 39 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2025 CloudStack.

快速回复 返回顶部 返回列表