You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 01:32:01