• 【Azure Redis 缓存】 Python连接Azure Redis, 使用redis.ConnectionPool 出现 "ConnectionResetError: [Errno 104] Connection reset by peer"


    问题描述

    Python连接Azure Redis, 使用redis.ConnectionPool 出现 "ConnectionResetError: [Errno 104] Connection reset by peer" "ConnectionResetError: [WinError 10054] An existing connection was forcibly closed by the remote host" 

    复制代码
    Traceback (most recent call last):
      File "C:\Users\AppData\Local\Programs\Python\Python310\lib\site-packages\redis\connection.py", line 748, in read_response
        response = self._parser.read_response()
      File "C:\Users\AppData\Local\Programs\Python\Python310\lib\site-packages\redis\connection.py", line 318, in read_response
        raw = self._buffer.readline()
      File "C:\Users\AppData\Local\Programs\Python\Python310\lib\site-packages\redis\connection.py", line 250, in readline
        self._read_from_socket()
      File "C:\Users\AppData\Local\Programs\Python\Python310\lib\site-packages\redis\connection.py", line 192, in _read_from_socket
        data = self._sock.recv(socket_read_size)
    ConnectionResetError: [WinError 10054] An existing connection was forcibly closed by the remote host
    
    During handling of the above exception, another exception occurred:
    ... ... 
    复制代码

    连接出错的Python代码为:

    复制代码
    import redis
    
    redis_params = {
        'host': 'redis-xxxxxx.redis.cache.chinacloudapi.cn',
        'port': 6380,
        'db': 1,
        'password': 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=',
        'timeout': 5000,
        'ssl': True
    }
    
    print('-----Try # 2------: Redis 使用连接池 ')
    
    print('connected to redis by connection pool ...')
    pool = redis.ConnectionPool( host=redis_params['host'], port=redis_params['port'], db=redis_params['db'], password=redis_params['password'], max_connections=20)
    conn_pool = redis.Redis(connection_pool=pool, socket_timeout=redis_params['timeout'], ssl=redis_params['ssl'], health_check_interval=30)
    
    
    conn_pool.set('test03', 'Value 结果显示在此')
    data = conn_pool.get('test03').decode()
    print(data)
    
    print('Connection Pool use Successful')
    复制代码

     

    而在不使用 ConnectionPool 的情况下,是能够正常连接的。

    print('-----Try # 1------: Redis 没有使用连接池的情况下: ')
    conn = redis.Redis(host=redis_params['host'], port=redis_params['port'], db=redis_params['db'], password=redis_params['password'], ssl=redis_params['ssl'], socket_timeout=redis_params['timeout'])
    print('connected to redis')
    conn.set('test', 'the normal value to set ')
    print('set done .... ')

     

    问题解答

    根据redis.py的源码查看,使用redis.Redis 当ssl为True时,构造函数中为 connection_class参数 初始化值为 SSLConnection。 而ConnectionPool的构造函数中默认使用的是 connection_class=Connection。

    redis.Redis

    redis.ConnectionPool

    根据以上分析,要解决Python Redis使用Connection Pool连接,只需要在创建Connection Pool对象时候,为Connection_class对象赋值为SSLConnection。

    修改后的代码为:

    复制代码
    import redis
    
    from redis.connection import SSLConnection
    
    redis_params = {
        'host': 'redis-xxxxxx.redis.cache.chinacloudapi.cn',
        'port': 6380,
        'db': 1,
        'password': 'xxxxxxxxxxxxxxxxxxx=',
        'timeout': 5000,
        'ssl': True
    }
    
    print('-----Try # 1------: Redis 没有使用连接池的情况下: ')
    conn = redis.Redis(host=redis_params['host'], port=redis_params['port'], db=redis_params['db'], password=redis_params['password'], ssl=redis_params['ssl'], socket_timeout=redis_params['timeout'])
    print('connected to redis')
    conn.set('test', 'the normal value to set ')
    print('set done .... ')
    
    data = conn.get('test').decode()
    print(str(data))
    
    print('-----Try # 2------: Redis 使用连接池 ')
    
    print('connected to redis by connection pool ...')
    pool = redis.ConnectionPool(connection_class= SSLConnection, host=redis_params['host'], port=redis_params['port'], db=redis_params['db'], password=redis_params['password'], max_connections=20)
    conn_pool = redis.Redis(connection_pool=pool, socket_timeout=redis_params['timeout'], ssl=redis_params['ssl'], health_check_interval=30)
    
    
    conn_pool.set('test03', 'Value 结果显示在此')
    data = conn_pool.get('test03').decode()
    print(data)
    
    print('Connection Pool use Successful')
    
    for i in range(1,10):
        conn_pool_1 = redis.Redis(connection_pool=pool, socket_timeout=redis_params['timeout'], ssl=redis_params['ssl'], health_check_interval=30)
        conn_pool_1.set('test_test__'+str(i), 'use conn pool to set value.......')
        print(conn_pool_1.client)
     
    
    clist = conn_pool.client_list()
    for c in clist:
        print(c)
    复制代码

    PS: 添加黄色高亮部分即可。

    整体演示动画如下:

    [END]

     

    参考资料

     

  • 相关阅读:
    浦东人大常委会副主任刘宇青一行莅临零数科技指导工作
    文件编码、转换、乱码问题
    Linux下C++开发笔记--g++命令
    MySQL表级锁——技术深度+1
    PHPOffice/PhpSpreadsheet的导入导出操作基本使用
    使用Python以UCI心脏病数据集为例,进行数据简单分析
    Json对象
    第55节—— redux-toolkit中的createReducer——了解
    软考 系统架构设计师系列知识点之云计算(3)
    基于SSM框架的电影院售票网站
  • 原文地址:https://www.cnblogs.com/lulight/p/16259722.html