1.问题描述
zookeeper服务端通过zookeeper客户端上报心跳来确定zookeeper客户端的存活状态。当网络状态不稳定的时候,经常会造成zookeeper客户端心跳上报丢失,导致zookeeper服务端错以为zookeeper客户端死掉,然后删除相应结点。测试代码如下:
from kazoo.client import KazooClient, KazooState
import logging
import time
def my_listener(state):
if state == KazooState.LOST:
# Register somewhere that the session was lost
logging.warning('handle lost')
elif state == KazooState.SUSPENDED:
# Handle being disconnected from Zookeeper
logging.debug('handle being disconnected')
else:
# Handle being connected/reconnected to Zookeeper
logging.debug('handle being (re)connected')
if __name__ == '__main__':
logging.basicConfig(format='(%(name)s): %(asctime)s [%(levelname)s] %(module)s %(funcName)s %(message)s',
level=logging.DEBUG)
logging.debug('starting...')
zk = KazooClient(hosts='192.168.0.142:2181', timeout=30)
zk.start()
if zk.exists("/test999") is None:
zk.create("/test999", bytes("test999".encode('utf-8')), ephemeral=True,makepath=True)
zk.add_listener(my_listener)
i=0
while True:
print(i)
try:
zk.set("/test999", bytes(str(i), encoding='utf8'))
time.sleep(i+1)
i=i+1
except:
print("error sleep 5s")
time.sleep(5)
#解决方法2
# if zk.exists("/test999") is None:
# zk.create("/test999", bytes("test999".encode('utf-8')),
zk.stop()
当正常运行时,zookeeper下会创建一个test999的结点
image.png
人为制造网络不畅,通过防火墙阻断与服务器的连接:
在命令行输入 iptables -A OUTPUT -d 192.168.0.142 -p tcp --dport 2181 -j DROP
image.png
等待一段时间后 ,输入 iptables -F
zookeeper客户端与服务器端连接建立,但是test999结点消失了
解决办法:
1.创建永久结点代替临时结点
2.在重新建立连接后自己代码手动添加 相同的 临时结点
网友评论