前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Nginx的ip_hash解析

Nginx的ip_hash解析

作者头像
星哥玩云
发布2022-06-30 18:14:07
1.3K0
发布2022-06-30 18:14:07
举报
文章被收录于专栏:开源部署

网络结构描述: 1个Nginx(前端)+2个tomcat(后端)

环境: 公司内网(网段:192.168.1.0/24),服务器也是分配的内网ip:192.168.1.4(暂定);后端两个tomcat:192.168.1.31/189 网站有session,所有Nginx启用ip_hash.

现象: 测试组用loadrunner模拟N多内网ip进行压测系统。发现,这些ip统一都转发到一个后端。

后经排查发现问题所在(结论最下面)。

1、请看官方解释: This directive causes requests to be distributed between upstreams based on the IP-address of the client. The key for the hash is the class-C network address or the entire IPv6-address of the client. IPv6 is supported for ip_hash since 1.3.2 or 1.2.2. This method guarantees that the client request will always be transferred to the same server. But if this server is considered inoperative, then the request of this client will be transferred to another server. This gives a high probability clients will always connect to the same server. (简译:将客户端ip转化成C类网络地址,然后将该网络地址当作hash关键字,来保证这个客户端请求总是被转发到一台服务器上)

2、请看Nginx的ip hash算法(该段代码为转发。原文链接: http://www.linuxidc.com/Linux/2014-02/96869.htm ):

for ( ;; ) { for (i = 0; i < 3; i++) { hash = (hash * 113 + iphp->addr[i]) % 6271;  //iphp->addr[i]为ip的点分十进制法的第i段 } p = hash % iphp->rrp.peers->number; n = p / (8 * sizeof(uintptr_t)); m = (uintptr_t) 1 << p % (8 * sizeof(uintptr_t)); if (!(iphp->rrp.tried[n] & m)) { ngx_log_debug2(NGX_LOG_DEBUG_HTTP, pc->log, 0, "get ip hash peer, hash: %ui %04XA", p, m); peer = &iphp->rrp.peers->peer[p]; /* ngx_lock_mutex(iphp->rrp.peers->mutex); */ if (!peer->down) { if (peer->max_fails == 0 || peer->fails < peer->max_fails) { break; } if (now - peer->accessed > peer->fail_timeout) { peer->fails = 0; break; } } iphp->rrp.tried[n] |= m; /* ngx_unlock_mutex(iphp->rrp.peers->mutex); */ pc->tries--; } if (++iphp->tries >= 20) { return iphp->get_rr_peer(pc, &iphp->rrp); } }

主要代码请看这里: for( ;; ) { for(i = 0; i < 3; i++) { hash = (hash * 113+ iphp->addr[i]) % 6271;  1、for循环 i 取 012三个值,而ip的点分十进制表示方法将ip分成四段(如:192.168.1.1),但是这里循环时只将ip的前三个端作为参数加入hash函数。这样做的目的是保证ip地址前三位相同的用户经过hash计算将分配到相同的后端server。 作者的这个考虑是极为可取的,因此ip地址前三位相同通常意味着来着同一个局域网或者相邻区域,使用相同的后端服务让nginx在一定程度上更具有一致性。 通过上述解释,已经基本判断出问题所在了。。 主要原因就是,公司局域网用的192.168.1.0/24 C类地址,这样Nginxip_hash(for循环后三个参数统一计入hash值)的时候,就将该类所有ip都转发到一个后端了。 另,晕了我半天了。。。不论A类B类C类等网络地址,Nginx的ip_hash算法都将一个ip地址的前三段作为hash的关键字。。(规定)

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档