我有一个非常奇怪的Python Kazoo库案例。我在下面的代码中所做的是 -
一旦我使用kazoo库连接到Zookeeper,我创建一个短暂的节点,然后在其他节点上监视,然后我继续在无限循环中继续运行程序..我还添加了一个监听器Zookeeper也将监视状态。
一切对我来说都很好,短暂的节点已经启动,看我的znode也工作得很好......
有时候,由于连接中断或丢失,我看到很奇怪的行为。正如我上面提到的,我已经向zookeeper添加了一个监听器,它将监视状态,我也有一个打印语句。我总是看到,那些打印语句被打印为Lost
,Suspended
, Connected
,我相信由于连接中断,之后我的短暂节点消失了,我对znode的监视也不起作用。
以下是我的代码,它永远运行 -
#!/usr/bin/python
from kazoo.client import KazooClient
from kazoo.client import KazooState
from kazoo.protocol.states import EventType
def watch_host(event):
print event
def my_listener(state):
if state == KazooState.LOST:
# Register somewhere that the session was lost
print "Lost"
elif state == KazooState.SUSPENDED:
# Handle being disconnected from Zookeeper
print "Suspended"
else:
# Handle being connected/reconnected to Zookeeper
# what are we supposed to do here?
print "Being Connected/Reconnected"
zk = KazooClient(hosts='127.0.0.1:2181')
zk.start()
zk.add_listener(my_listener)
# start an ephemeral node
zk.create("/my/example/h0", b"some value", None, True)
# put a watch on my znode
children = zk.get_children("/my/example/test1", watch=watch_host)
while True:
time.sleep(5)
有没有办法克服这个问题?每当我的Zookeeper状态更改为Lost
或Suspended
或Connected
时,我都希望这样。我希望通过再次创建它来获得我的短暂节点(如果这是正确的方法)并且我在znode上的监视也始终正常工作。
因为我将永远运行我的程序,所以无论出于何种原因,如果Zookeeper状态由于连接中断而发生变化并且它自动再次连接回来,那么我需要确保我的短暂节点也已启动并且我的手表在znode上也开始自动工作..
目前我的短暂死亡,如果州自动改变,手表也不起作用..
知道如何克服这个问题吗?
答案 0 :(得分:6)
这是事情,当连接状态发生变化时,你的观察者也会被触发。有一个事件发给了守望者。它可以是nodeDataChanged或nodeChildrenChanged。但是,由于当您的会话终止或存在连接问题时,您无法收到您感兴趣的事件的通知,因此您的观察者将收到有关这些会话问题的通知。我相信这个事件的类型是“无”。
来自http://zookeeper.apache.org/doc/trunk/zookeeperProgrammers.html#ch_zkWatches
关于手表的事项
所以,长话短说,你的观察者应该破解事件以查看它是什么类型,并通过进入某种故障转移模式适当地响应None类型。
我通常做的是我的Watcher对象也是听众。当重新连接发生时,我通过重置我的手表来做出回应,确保检查是否存在适当的znodes,并在必要时创建它们。
答案 1 :(得分:5)
我对Python一无所知,但我想我会强调一些关于ZNodes
的基本要点
Znodes
有两种类型:ephemeral
或persistent
ephemeral znode
创建persistent znode
只有在客户端明确删除时才会被删除(不一定是创建它的人)。 ephemeral znode
永远不会有任何子女关联,甚至不会ephemeral
个。在Java版本(Java API)中,如果客户端连接到多个服务器,并且它与连接的服务器断开连接,那么我们会使用KeeperState.Disconnected
触发事件,但它会重新尝试并连接到另一台服务器,< strong>在这个时间ephemeral znode
和所有手表完好无损,即它们没有被销毁但是一旦调用KeeperState.Expired
的事件(当客户端无法与任何服务器建立连接时)在指定的时间内)然后 ephemeral znode
被销毁我们必须创建一个新的客户端连接(实例化一个新的ZooKeeper
实例)如果我们想要访问整体然后重新建立一切都是节点创建和添加手表。
所以我认为在你的情况下这也可能适用,如Understanding Kazoo States Section
中所述当连接转换为LOST时,Zookeeper将删除已创建的任何短暂节点。这会影响创建短暂节点的所有配方,例如锁定配方。在状态再次转换为CONNECTED之后,需要重新获取锁定。当会话过期或停止客户端连接时,会发生此转换。
希望此信息可以帮助您了解各种状态以及何时重新配置所有状态。