nginx通过ip-hash算法负载不均或不起效问题

ip-hash的算法

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循环i取 012三个值,而ip的点分十进制表示方法将ip分成四段(如:192.168.1.1),但是这里循环时只是将ip的前三个段作为参数加入hash函数。这样做的目的是保证ip地址前三位相同的用户经过hash计算将分配到相同的后端server。

由于Ng前面是一个硬负载,和Ng交换的IP是硬负载地址池中的多个固定的IP。从而导致Ng把请求都转发到一个机器上面啦。

解决方案:

第一种:

修改ip_hash代码算法中的取值,解决问题,可以参考

https://blog.csdn.net/qq_45367825/article/details/111355402?utm_medium=distribute.pc_relevant.none-task-blog-2~default~BlogCommendFromMachineLearnPai2~default-2.control&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2~default~BlogCommendFromMachineLearnPai2~default-2.control

第二种:

通过HTTP_X_FORWARDED_FOR获取IP地址

server {
        listen       80;
        .....
        location /{      
            set_real_ip_from  10.48.10.0/24;#需要过滤掉的IP
            set_real_ip_from  61.22.22.22;
            real_ip_header    X-Forwarded-For;
            real_ip_recursive on;
        }
    }

 

上一篇:Netty-介绍


下一篇:“中国开发者文化不看重平等?”说说我知道的Peer Bonus