可以使用主机名连接到 Redis,但不能使用 URL

问题描述 投票:0回答:1

我正在尝试将 Celery 连接到另一台计算机上的 Redis 后端,但出现无主机路由错误。从问题中删除 Celery,我可以使用主机名与 Redis 客户端连接,但使用 Redis url 时会得到相同的“无路由到主机”错误。

我尝试使用每种方法创建 2 个连接对象 1,两者看起来都很相似:

>>> import redis
>>>
>>> r = redis.Redis(host='server.domain.com',port=6379)
>>> r2 = redis.Redis.from_url('redis://server.domain.com:6379')
>>>
>>> r
Redis<ConnectionPool<Connection<host=server.domain.com,port=6379,db=0>>>
>>> r2
Redis<ConnectionPool<Connection<host=server.domain.com,port=6379,db=0>>>

主机名版本按预期工作:

>>> r.get('test')
b'Test stuff'

但是使用redis url的版本返回“没有到主机的路由”错误:

>>> r2.get('test')
Traceback (most recent call last):
  File "/home/user/venv/lib/python3.10/site-packages/redis/connection.py", line 264, in connect
    sock = self.retry.call_with_retry(
  File "/home/user/venv/lib/python3.10/site-packages/redis/retry.py", line 46, in call_with_retry
    return do()
  File "/home/user/venv/lib/python3.10/site-packages/redis/connection.py", line 265, in <lambda>
    lambda: self._connect(), lambda error: self.disconnect(error)
  File "/home/user/venv/lib/python3.10/site-packages/redis/connection.py", line 627, in _connect
    raise err
  File "/home/user/venv/lib/python3.10/site-packages/redis/connection.py", line 615, in _connect
    sock.connect(socket_address)
OSError: [Errno 113] No route to host

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/user/venv/lib/python3.10/site-packages/redis/commands/core.py", line 1829, in get
    return self.execute_command("GET", name)
  File "/home/user/venv/lib/python3.10/site-packages/redis/client.py", line 533, in execute_command
    conn = self.connection or pool.get_connection(command_name, **options)
  File "/home/user/venv/lib/python3.10/site-packages/redis/connection.py", line 1086, in get_connection
    connection.connect()
  File "/home/user/venv/lib/python3.10/site-packages/redis/connection.py", line 270, in connect
    raise ConnectionError(self._error_message(e))
redis.exceptions.ConnectionError: Error 113 connecting to server.domain.com:6379. No route to host.

更新

进步。我对 redis 对象进行了更深入的研究,似乎 from_url 方法在创建 connection_pool 时遗漏了几个 kwargs:

>>> r.connection_pool.__dict__
{'connection_class': <class 'redis.connection.Connection'>, 'connection_kwargs': {'db': 0, 'username': None, 'password': None, 'socket_timeout': None, 'encoding': 'utf-8', 'encoding_errors': 'strict', 'decode_responses': True, 'retry_on_error': [], 'retry': None, 'health_check_interval': 0, 'client_name': None, 'lib_name': 'redis-py', 'lib_version': '5.0.1', 'redis_connect_func': None, 'credential_provider': None, 'protocol': 2, 'host': 'server.domain.com', 'port': 6379, 'socket_connect_timeout': None, 'socket_keepalive': None, 'socket_keepalive_options': None}, 'max_connections': 2147483648, '_fork_lock': <unlocked _thread.lock object at 0x7fcfd576ebc0>, '_lock': <unlocked _thread.lock object at 0x7fcfd576d2c0>, '_created_connections': 1, '_available_connections': [Connection<host=server.domain.com,port=6379,db=0>], '_in_use_connections': set(), 'pid': 37317}
>>> r2.connection_pool.__dict__
{'connection_class': <class 'redis.connection.Connection'>, 'connection_kwargs': {'host': 'server.domain.com', 'port': 6379, 'db': 0}, 'max_connections': 2147483648, '_fork_lock': <unlocked _thread.lock object at 0x7fcfd5d6bb40>, '_lock': <unlocked _thread.lock object at 0x7fcfd5d6bbc0>, '_created_connections': 1, '_available_connections': [Connection<host=server.domain.com,port=6379,db=0>], '_in_use_connections': set(), 'pid': 37317}

这修复了独立 Redis 客户端的连接,但似乎不适用于 Celery,同样的错误:

>>> r2 = redis.Redis.from_url('redis://:@server.domain.com:6379')
>>> r2.get('test')
b'Test stuff'
python redis celery
1个回答
0
投票

您在 Python 中使用 URL 格式连接到 Redis 后端时遇到的问题表明,与标准主机名和端口方法相比,redis.Redis.from_url 方法解释 URL 的方式存在细微差别。

考虑到直接主机名和端口方法工作正常(redis.Redis(host='server.domain.com', port=6379)),但 URL 方法(redis.Redis.from_url('redis://server. domain.com:6379')) 会导致“没有到主机的路由”错误。

您可以尝试 URL 解析来解决您的错误: from_url 方法可能会以不同的方式解析 URL。仔细检查 URL 的格式。确保没有拼写错误或意外字符。它的格式应该是 redis://server.domain.com:6379。

© www.soinside.com 2019 - 2024. All rights reserved.