Azure部署Flask应用遇ssl.SSLEOFError:Binance WebSocket进程异常终止
问题分析与解决方案
问题概述
部署在Azure Web Service的Flask应用通过多进程运行Binance WebSocket连接,不定期出现ssl.SSLEOFError: EOF occurred in violation of protocol异常,导致进程终止并自动重启,但异常反复出现。应用已开启Always On配置。
核心原因
SSLEOFError通常表示SSL连接意外中断,可能由以下原因导致:
- 网络波动(Azure或Binance端的临时网络故障)
- WebSocket客户端未处理连接断开的情况
- Azure Web App资源限制导致连接被强制关闭
- SSL协议版本或验证配置不兼容
解决方案
1. 捕获WebSocket异常并实现自动重连
在WebSocket连接逻辑中添加异常捕获,当出现连接中断时自动重启连接,避免进程直接终止。
修改do_binance_trading函数:
import time import ssl from websocket import WebSocketException def do_binance_trading(queue): # 循环实现自动重连 while True: try: print("Going to start a socket. . .") socket_manager = BinanceSocketManager.getInstance() # 指定SSL协议版本,避免兼容性问题 socket_manager.startSocket(queue, sslopt={"ssl_version": ssl.PROTOCOL_TLSv1_2}) print("Socket started. . .") # 若startSocket为阻塞调用,执行到此处说明连接已断开 print("Socket disconnected, initiating restart...") except WebSocketException as e: print(f"WebSocket connection error: {str(e)}") time.sleep(5) # 延迟重连,避免频繁请求 except ssl.SSLEOFError as e: print(f"SSL connection interrupted: {str(e)}") time.sleep(5) except Exception as e: print(f"Unexpected error: {str(e)}") time.sleep(10)
2. 优化多进程与Azure环境的兼容性
Azure Web App的进程管理机制与本地环境有差异,调整多进程配置减少异常:
- 使用
multiprocessing.Manager创建跨进程队列,避免原生队列的潜在问题 - 将进程设置为守护进程,确保主进程退出时子进程能正确清理
修改main函数中的进程初始化代码:
from multiprocessing import Manager @app.route("/") def main(): global process global queue global latestQueueData print("Ping app. . .") if process is not None and process.is_alive(): print("App is running. Trading process id:" + str(process.pid)) # Retrieve all data from the queue queue_data = [] while not queue.empty(): queue_data.append(queue.get()) if len(queue_data) > 0 and latestQueueData != queue_data[-1]: latestQueueData = queue_data[-1] # Display all data in the queue return latestQueueData.replace("\n", "<br>"), 200 else: print("Starting App. . .") # 使用Manager创建队列,确保跨进程访问稳定 manager = Manager() queue = manager.Queue() # 设置daemon=True,主进程退出时子进程自动终止 process = multiprocessing.Process(target=do_binance_trading, args=(queue,), daemon=True) process.start() print("Process started. . .") return "Trading started", 200
3. 调整Azure Web Service配置
- 升级服务计划:如果使用免费/共享层,资源限制可能导致连接被强制中断,升级到Basic或Standard层获得更稳定的资源分配
- 设置环境变量:添加
PYTHONUNBUFFERED=1确保日志实时输出,方便排查问题;添加WEBSITE_RUN_FROM_PACKAGE=1优化部署稳定性 - 验证网络出站规则:确保Azure Web App允许访问Binance的WebSocket端点(
wss://stream.binance.com:9443),无防火墙或NSG规则限制
4. 增强日志排查
替换print为标准logging模块,记录详细异常信息,帮助定位问题根源:
import logging # 配置日志格式,包含时间和异常堆栈 logging.basicConfig( level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s', handlers=[logging.StreamHandler()] ) def do_binance_trading(queue): while True: try: logging.info("Initiating Binance WebSocket connection...") socket_manager = BinanceSocketManager.getInstance() socket_manager.startSocket(queue) logging.info("WebSocket connection established") logging.info("WebSocket disconnected, restarting...") except ssl.SSLEOFError as e: logging.error(f"SSL EOF Error occurred", exc_info=True) time.sleep(5) except Exception as e: logging.error(f"Unexpected error in trading process", exc_info=True) time.sleep(10)
内容的提问来源于stack exchange,提问作者Alex Vashchenko
相关产品推荐
相关产品推荐

