Celery Got an Unexpected Keyword Argument 'Socket_connect_timeout'
这是一次问题的错误记录,celery在机器A上可以正常工作,但在机器B上启动时
celery worker -A app --loglevel=info
会遇到如下问题:
File "/usr/local/lib/python2.7/site-packages/celery-3.1.23-py2.7.egg/celery/worker/consumer.py", line 376, in connect
callback=maybe_shutdown,
File "/usr/local/lib/python2.7/site-packages/kombu-3.0.35-py2.7.egg/kombu/connection.py", line 369, in ensure_connection
interval_start, interval_step, interval_max, callback)
File "/usr/local/lib/python2.7/site-packages/kombu-3.0.35-py2.7.egg/kombu/utils/__init__.py", line 246, in retry_over_time
return fun(*args, **kwargs)
File "/usr/local/lib/python2.7/site-packages/kombu-3.0.35-py2.7.egg/kombu/connection.py", line 237, in connect
return self.connection
File "/usr/local/lib/python2.7/site-packages/kombu-3.0.35-py2.7.egg/kombu/connection.py", line 742, in connection
self._connection = self._establish_connection()
File "/usr/local/lib/python2.7/site-packages/kombu-3.0.35-py2.7.egg/kombu/connection.py", line 697, in _establish_connection
conn = self.transport.establish_connection()
File "/usr/local/lib/python2.7/site-packages/kombu-3.0.35-py2.7.egg/kombu/transport/virtual/__init__.py", line 809, in establish_connection
self._avail_channels.append(self.create_channel(self))
File "/usr/local/lib/python2.7/site-packages/kombu-3.0.35-py2.7.egg/kombu/transport/virtual/__init__.py", line 791, in create_channel
channel = self.Channel(connection)
File "/usr/local/lib/python2.7/site-packages/kombu-3.0.35-py2.7.egg/kombu/transport/redis.py", line 464, in __init__
self.client.info()
File "/usr/local/lib/python2.7/site-packages/kombu-3.0.35-py2.7.egg/kombu/utils/__init__.py", line 325, in __get__
value = obj.__dict__[self.__name__] = self.__get(obj)
File "/usr/local/lib/python2.7/site-packages/kombu-3.0.35-py2.7.egg/kombu/transport/redis.py", line 908, in client
return self._create_client(async=True)
File "/usr/local/lib/python2.7/site-packages/kombu-3.0.35-py2.7.egg/kombu/transport/redis.py", line 861, in _create_client
return self.AsyncClient(connection_pool=self.async_pool)
File "/usr/local/lib/python2.7/site-packages/kombu-3.0.35-py2.7.egg/kombu/transport/redis.py", line 882, in __init__
self.connection = self.connection_pool.get_connection('_')
File "/usr/local/lib/python2.7/site-packages/redis/connection.py", line 455, in get_connection
connection = self.make_connection()
File "/usr/local/lib/python2.7/site-packages/redis/connection.py", line 464, in make_connection
return self.connection_class(**self.connection_kwargs)
TypeError: __init__() got an unexpected keyword argument 'socket_connect_timeout'
网上关于此问题的主要讨论来自: https://github.com/celery/celery/issues/2903
但感觉大多数讨论并没有指明问题的解决方法。重新查看错误日志,看到问题最终出现在 /redis/connection.py中,即python redis客户端模块中,其中Connection类的构造函数如下:
class Connection(object):
"Manages TCP communication to and from a Redis server"
description_format = "Connection<host=%(host)s,port=%(port)s,db=%(db)s>"
def __init__(self, host='localhost', port=6379, db=0, password=None,
socket_timeout=None, encoding='utf-8',
encoding_errors='strict', decode_responses=False,
parser_class=DefaultParser):
self.pid = os.getpid()
self.host = host
self.port = port
self.db = db
self.password = password
self.socket_timeout = socket_timeout
self.encoding = encoding
self.encoding_errors = encoding_errors
self.decode_responses = decode_responses
self._sock = None
self._parser = parser_class()
再对比可以运行机器中相应源代码:
class Connection(object):
"Manages TCP communication to and from a Redis server"
description_format = "Connection<host=%(host)s,port=%(port)s,db=%(db)s>"
def __init__(self, host='localhost', port=6379, db=0, password=None,
socket_timeout=None, socket_connect_timeout=None,
socket_keepalive=False, socket_keepalive_options=None,
retry_on_timeout=False, encoding='utf-8',
encoding_errors='strict', decode_responses=False,
parser_class=DefaultParser, socket_read_size=65536):
self.pid = os.getpid()
self.host = host
self.port = int(port)
self.db = db
self.password = password
self.socket_timeout = socket_timeout
self.socket_connect_timeout = socket_connect_timeout or socket_timeout
self.socket_keepalive = socket_keepalive
self.socket_keepalive_options = socket_keepalive_options or {}
self.retry_on_timeout = retry_on_timeout
self.encoding = encoding
self.encoding_errors = encoding_errors
self.decode_responses = decode_responses
可以看到在新版本的redis中才会支持socket_connect_timeout字段。
因为问题的解决办法是:升级redis到2.10以上版本
pip install redis --upgrade
这个解决方案我也补充在 https://github.com/celery/celery/issues/2903 的最后了。s