Python对接OKX API的WebSocket异常及数据库存储问题排查
问题排查与解决方案
一、WebSocket连接莫名断开的原因及修复
核心原因
- 缺少心跳维持:OKX WebSocket服务器会主动断开长时间无交互的连接,若未定时发送心跳包,连接会被回收。
- 无自动重连机制:网络波动、服务器限流/会话超时等场景下,连接断开后无法自动恢复。
- 未处理服务器主动断开的信号:OKX可能因API权限、请求频率超限等原因主动断开连接,未捕获这类场景。
解决方案
启用内置心跳机制:
在run_forever()中配置ping_interval和ping_timeout,让websocket-client自动发送心跳:ws.run_forever(ping_interval=30, ping_timeout=10)(OKX要求心跳间隔不超过30秒,此处设置30秒发一次ping,10秒未收到pong则判定超时)
实现指数退避重连:
在on_close和on_error中添加重连逻辑,避免频繁重试导致被限流:import time def on_close(ws, close_status_code, close_msg): print(f"WebSocket closed: {close_status_code} - {close_msg}") reconnect() def on_error(ws, error): print(f"WebSocket error: {error}") reconnect() def reconnect(): retry_count = 0 while True: try: # 指数退避:间隔1s→2s→4s→…→最大60s sleep_time = min(2 ** retry_count, 60) print(f"Reconnecting in {sleep_time}s...") time.sleep(sleep_time) # 重新初始化WebSocket连接 new_ws = websocket.WebSocketApp( url="wss://ws.okx.com:8443/ws/v5/private", on_open=on_open, on_message=on_message, on_error=on_error, on_close=on_close ) new_ws.run_forever(ping_interval=30, ping_timeout=10) break except Exception as e: print(f"Reconnect failed: {e}") retry_count += 1检查API合规性:
- 确保API密钥权限正确(需钱包相关权限)
- 核对请求频率是否符合OKX WebSocket的限制,避免因超限被断开。
二、psycopg2异常适配错误与连接池耗尽的修复
核心原因
- 异常对象无法直接存入PostgreSQL:psycopg2默认不支持将
WebSocketConnectionClosedException这类自定义异常对象作为参数插入数据库,会触发ProgrammingError。 - 连接未正确归还:错误处理逻辑中若发生异常,可能导致连接池的连接未被
putconn()归还,长期积累后连接池耗尽,触发PoolError。
解决方案
将异常转换为字符串存储:
记录错误时,不要直接传入异常对象,而是用traceback.format_exc()获取完整错误栈(或str(error)获取简单描述):import traceback def log_error(error): # 获取完整错误栈字符串 error_detail = traceback.format_exc() conn = None try: conn = pool.getconn() with conn.cursor() as cur: # 确保数据库表的error_message字段是TEXT类型 cur.execute( "INSERT INTO error_logs (error_time, error_message) VALUES (NOW(), %s)", (error_detail,) ) conn.commit() except Exception as db_err: print(f"Failed to log error: {db_err}") if conn: conn.rollback() finally: # 无论是否成功,必须归还连接到池 if conn: pool.putconn(conn)强制保证连接回收:
使用try-finally结构包裹连接的获取与使用,确保即使发生数据库操作异常,连接也能被归还到池中,避免连接泄漏。优化连接池配置:
若业务量较大,可适当调整连接池的minconn和maxconn参数,但需注意PostgreSQL的最大连接数限制(默认通常是100):from psycopg2 import pool # 初始化连接池,根据业务调整参数 connection_pool = pool.SimpleConnectionPool( minconn=2, maxconn=10, dbname="your_db", user="your_user", password="your_pwd", host="your_host" )
内容的提问来源于stack exchange,提问作者Filips
相关产品推荐
相关产品推荐

