无法启动Kazoo客户端。出现“在非套接字上尝试了一个操作”的错误

1 投票
1 回答
2174 浏览
提问于 2025-04-18 13:14

我刚开始学习Kazoo,想运行一个非常简单的程序,但遇到了问题:

from kazoo.client import KazooClient
import logging
logging.basicConfig(level=logging.DEBUG)
from kazoo.retry import KazooRetry
_retry = KazooRetry(max_tries=1000, delay=0.5, backoff=2)
zk = KazooClient(hosts='164.55.92.8:2181', logger=logging, timeout=10, connection_retry=_retry, read_only=True)

zk.start()
import time
print('sleeping 5!')
time.sleep(5)
zk.stop()

下面是输出结果:

ERROR:root:Unhandled exception in connection loop  
Traceback (most recent call last):  
  File "C:\Python27\lib\site-packages\kazoo-2.0-py2.7.egg\kazoo\protocol\connection.py", line 522, in _connect_attempt  
    [], [], timeout)[0]  
  File "C:\Python27\lib\site-packages\kazoo-2.0-py2.7.egg\kazoo\handlers\threading.py", line 250, in select  
    return select.select(*args, **kwargs)  
error: (10038, 'An operation was attempted on something that is not a socket')  
INFO:root:Zookeeper session lost, state: CLOSED  
Exception in thread Thread-3:  
Traceback (most recent call last):  
  File "C:\Python27\lib\threading.py", line 551, in __bootstrap_inner  
    self.run()  
  File "C:\Python27\lib\threading.py", line 504, in run  
    self.__target(*self.__args, **self.__kwargs)  
  File "C:\Python27\lib\site-packages\kazoo-2.0-py2.7.egg\kazoo\protocol\connection.py", line 466, in zk_loop  
    if retry(self._connect_loop, retry) is STOP_CONNECTING:  
  File "C:\Python27\lib\site-packages\kazoo-2.0-py2.7.egg\kazoo\retry.py", line 123, in __call__  
    return func(*args, **kwargs)  
  File "C:\Python27\lib\site-packages\kazoo-2.0-py2.7.egg\kazoo\protocol\connection.py", line 483, in _connect_loop  
    status = self._connect_attempt(host, port, retry)  
  File "C:\Python27\lib\site-packages\kazoo-2.0-py2.7.egg\kazoo\protocol\connection.py", line 522, in _connect_attempt  
    [], [], timeout)[0]  
  File "C:\Python27\lib\site-packages\kazoo-2.0-py2.7.egg\kazoo\handlers\threading.py", line 250, in select  
    return select.select(*args, **kwargs)  
error: (10038, 'An operation was attempted on something that is not a socket')  


Traceback (most recent call last):  
  File "C:\Users\klow\Google Drive\mycode\mykazoo\kazooo.py", line 8, in <module>  
    zk.start()  
  File "C:\Python27\lib\site-packages\kazoo-2.0-py2.7.egg\kazoo\client.py", line 537, in start  
    raise self.handler.timeout_exception("Connection time-out")  
TimeoutError: Connection time-out  
>>>   

我是在一台Windows 7的笔记本电脑上运行这个程序,而Zookeeper服务器是在一台Linux机器上。看起来TCP连接已经建立了,但之后似乎出了点问题。我查看了一下代码,发现TCP连接是在connection.py的第510行建立的(self._connect(host, port)),而self._socket被分配给create_tcp_connection(socket, *args, **kwargs)返回的对象。但是,在connection.py的第521行,self.handle.select()对这个socket不太满意。有人知道怎么回事吗?提前谢谢大家!

1 个回答

2

我最近在研究一个类似的设置。我的系统是Win7,zookeeper在一个Linux机器上运行,使用的是Python 3.4。总之,我认为这个调用

s = self.handler.select([self._socket, self._read_pipe],
                                        [], [], timeout)[0]

是在尝试对一个管道进行选择操作。根据Python的文档,管道上的选择操作在Windows上是不能用的。所以看起来,kazoo在当前的架构下无法在Windows上工作。我在代码的一个副本中尝试使用成对的套接字,但效果不太好。

kazoo不能在Windows客户端上工作,这限制了它的实用性……

更新:经过一些修改,kazoo的源代码可以解决这个问题。我创建了一个小工具函数,用于在Windows上创建一个套接字对。这个套接字对模拟了一个管道,并由utils中的create_pipe函数返回。在客户端的几个地方,有调用os.read()和os.write()的地方,我把它们替换成了socket.recv和socket.send,结果一切看起来都正常。

我不太明白为什么kazoo要使用管道。看起来这主要是为了信号功能,而信号可以做得更好。无论如何,我会查看代码,看看能否找到一个更永久的解决方案。

撰写回答