由于服务器数量限制,所以将keepalived和nginx装在同一台,结果出现了一个很奇葩的问题,在这儿描述一下。

拓补图:(虽然是同一台,但是还是照下面的架构)

keepalived 查看 IIS状态_python

配置文件:(这儿只放keepalived主节点配置文件)

global_defs {
   router_id master_015
}

vrrp_instance VI_1 {
    state MASTER
    interface eth0
    lvs_sync_daemon_inteface eth0
    virtual_router_id 51
    priority 180
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 123456
    }
    virtual_ipaddress {
        10.97.10.100
    }
}

virtual_server 10.97.10.100 80 {
    delay_loop 6
    lb_algo rr
    lb_kind DR
    persistence_timeout 30
    protocol TCP

    real_server 10.97.10.15 80 {
        weight 100
        TCP_CHECK {
            connect_timeout 3
            nb_get_retry 3
            delay_before_retry 3
	    connect_port 80
        }
    }
    real_server 10.97.10.16 80 {
        weight 100
        TCP_CHECK {
            connect_timeout 3
            nb_get_retry 3
            delay_before_retry 3
	    connect_port 80
        }
    }
}

环境情况大致如上。

现在出现的问题就是,通过VIP访问80端口,会出现时通时不通的情况,注意是时通时不通,而不是一直不通 ,而且只有80端口出现这个问题,我们在keepalived下还配置了MariaDB集群,Redis集群,都没有出现这个问题。

(这个问题前段时间提过一次问,可能是描述的问题,所以一直没有人回答:)

检查各个参数,VIP飘移情况,日志都是正常的。最初怀疑是网络的问题,但后续也排除了,抓报文,请求已经到达了服务器,是服务器没有返回。


然而并不会调试源码,所以开始各种折腾~省略10000字。。。


最后发现关键点就在 时通时不通

如图:通过VIP访问,请求会先到达A的LVS,然后根据权重选举真实服务器,接着将请求的报文改为选举出来真实服务器的MAC地址,并将报文广播至当前LAN中。此时arp协议会根据MAC地址找到真实服务IP将报文传给它。但是~~当选举出来的是A节点的Nginx,那就没问题,访问正常,关键是当选举出来的是B节点的Nginx,此时报文传到B节点,但是B节点也有LVS,会首先将其拦截了,然后再选举一次。。。如图所示,是不是发现有一定几率会出现报文在LVS之间来回跳(抓包应该体现在Mac地址上的变化)的死循环。

这就是为什么会出现时通时不通的情况。。

解决办法:

1、将keepalived放在独立的服务器,折中一下放在不归它自己负载服务的服务器;

2、采用热双机互备的模式,但是会启用多个VIP,然后当同一台服务器的keepalived或Nginx挂了,那么这台服务器都将不可用,可用性差了;

3、两台服务器通过脚本及crond定时任务去互相检测对方80端口,以此来起停nginx服务,保持始终只有一台Nginx是启动的,另一台是关闭的。

3、哪位大神还有其它解决办法或是我没有说到的,希望分享一下哇~