【问题标题】:Python - How to check if Redis server is availablePython - 如何检查 Redis 服务器是否可用
【发布时间】:2012-10-03 04:23:08
【问题描述】:

我正在开发一个用于访问 Redis 服务器的 Python 服务(类)。我想知道如何检查 Redis Server 是否正在运行。而且如果我无法连接到它。

这是我的代码的一部分

import redis
rs = redis.Redis("localhost")
print rs

它打印以下内容

<redis.client.Redis object at 0x120ba50>

即使我的 Redis 服务器没有运行。

我发现我的 Python 代码只有在我对我的 redis 实例执行 set()get() 时才会连接到服务器。

所以我不希望其他服务使用我的类得到异常提示

redis.exceptions.ConnectionError: Error 111 connecting localhost:6379. Connection refused.

我想返回正确的消息/错误代码。我该怎么做??

【问题讨论】:

标签: python redis


【解决方案1】:

检查redis服务器可用性的官方方法是ping(http://redis.io/topics/quickstart)。

一种解决方案是继承 redis 并做两件事:

  1. 在实例化时检查连接
  2. 在发出请求时编写一个异常处理程序以防止连接失败

【讨论】:

  • 我刚刚包装了我的连接并尝试了 ping:除了 RedisError:它对我有用。
  • 注意,你可能还会从套接字库中得到一个 ConnectionRefusedError ,这不是 RedisError
【解决方案2】:

如果要在启动时测试一次 redis 连接,请使用ping() 命令。

from redis import Redis

redis_host = '127.0.0.1'
r = Redis(redis_host, socket_connect_timeout=1) # short timeout for the test

r.ping() 

print('connected to redis "{}"'.format(redis_host)) 

ping() 命令检查连接,如果无效将引发异常。

  • 注意 - 执行测试后连接可能仍然失败,因此这不会掩盖以后的超时异常。

【讨论】:

    【解决方案3】:

    如您所说,仅当您尝试在服务器上执行命令时,才会建立与 Redis 服务器的连接。如果您不想在不检查服务器是否可用的情况下继续前进,您可以向服务器发送随机查询并检查响应。类似的东西:

    try:
        response = rs.client_list()
    except redis.ConnectionError:
        #your error handlig code here    
    

    【讨论】:

    • 我不得不添加 redis: redis.ConnectionError:
    • 你好 user984003。我已经更新了我的答案以反映你所说的。不过,您始终可以使用“from redis import ConnectionError”来避免使用“redis”。
    • 你也可以从套接字库中得到一个 ConnectionRefusedError
    【解决方案4】:

    这里已经有很好的解决方案,但这是我对 django_redis 的快速而肮脏的解决方案,它似乎不包含 ping 功能(尽管我使用的是旧版本的 django,并且不能使用最新的 django_redis)。

    # assuming rs is your redis connection
    def is_redis_available():
        # ... get redis connection here, or pass it in. up to you.
        try:
            rs.get(None)  # getting None returns None or throws an exception
        except (redis.exceptions.ConnectionError, 
                redis.exceptions.BusyLoadingError):
            return False
        return True
    

    这似乎工作得很好。请注意,如果 redis 正在重新启动并且仍在加载保存磁盘上缓存条目的 .rdb 文件,那么它将抛出 BusyLoadingError,尽管它的基类是 ConnectionError,因此只需捕获它就可以了。

    您也可以简单地在 redis.exceptions.RedisError 上除外,这是所有 redis 异常的基类。

    根据您的需要,另一种选择是创建 get 和 set 函数,以在设置/获取值时捕获 ConnectionError 异常。然后你可以继续或等待或任何你需要做的事情(引发一个新的异常或只是抛出一个更有用的错误消息)。

    如果您完全依赖于设置/获取缓存值(出于我的目的,如果缓存因我们通常必须“继续”而处于脱机状态),这可能无法正常工作,在这种情况下,有例外情况可能是有意义的让程序/脚本死掉,让redis服务器/服务回到可达状态。

    【讨论】:

      【解决方案5】:

      我还遇到了来自 sockets 库的 ConnectionRefusedError,当时 redis 没有运行,因此我不得不将它添加到可用性检查中。

      r = redis.Redis(host='localhost',port=6379,db=0)
      
      def is_redis_available(r):
          try:
              r.ping()
              print("Successfully connected to redis")
          except (redis.exceptions.ConnectionError, ConnectionRefusedError):
              print("Redis connection error!")
              return False
          return True
      
      if is_redis_available(r):
          print("Yay!")
      

      【讨论】:

        【解决方案6】:

        可以通过对服务器执行ping命令来检查Redis服务器连接。

        >>> import redis
        >>> r = redis.Redis(host="127.0.0.1", port="6379")
        >>> r.ping()
        True
        

        使用ping方法,我们可以处理重新连接等。为了了解连接错误的原因,可以按照其他答案的建议使用异常处理。

        try:
            is_connected = r.ping()
        except redis.ConnectionError:
            # handle error
        

        【讨论】:

          【解决方案7】:

          使用 ping()

          from redis import Redis
          
          conn_pool = Redis(redis_host)
          # Connection=Redis<ConnectionPool<Connection<host=localhost,port=6379,db=0>>>
          
          try:
              conn_pool.ping()
              print('Successfully connected to redis')
          except redis.exceptions.ConnectionError as r_con_error:
              print('Redis connection error')
              # handle exception
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2012-04-09
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-05-19
            • 2014-11-06
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多