Azure Web App部署Flask应用时SQLAlchemy连接SQL Server超时
问题描述
首次将Python Flask应用部署至Azure免费版Web App,应用通过SQLAlchemy结合pyodbc驱动连接SQL Server数据库,网站加载时完成数据库连接与表操作。本地运行正常,但部署后出现登录超时的OperationalError,错误信息如下:
Traceback (most recent call last): File "/tmp/8dc4e3d6e3306fa/antenv/lib/python3.11/site-packages/sqlalchemy/engine/base.py", line 145, in __init__ self._dbapi_connection = engine.raw_connection() ... pyodbc.OperationalError: ('HYT00', '[HYT00] [Microsoft][ODBC Driver 17 for SQL Server]Login timeout expired (0) (SQLDriverConnect)')
环境与配置
- 环境:Azure Web App(免费版)
- 数据库:SQL Server
- 连接方式:SQLAlchemy + pyodbc
- requirements.txt依赖:
cnos-connector==0.1.9 pyodbc==5.1.0 SQLAlchemy==2.0.28 - 数据库连接代码:
user = os.environ["User_Name"] password = os.environ["Password"] hostName = os.environ["hostName"] port = os.environ["port"] db = os.environ["database"] db_context = os.environ["context"] # Establishing the database connection URI database_uri = f"mssql+pyodbc://{user}:{password}@{hostName}:{port}/{db}?driver=ODBC+Driver+17+for+SQL+Server" engine = create_engine(database_uri) - 启动命令:
gunicorn --bind=0.0.0.0 --timeout 600 app:app
已尝试操作
- 确认Azure Web App应用设置中环境变量名称与代码一致(已设为部署槽设置,大写)
- 增加连接超时参数,Web App启动超时调至600秒
- 为Web App添加VNet集成,确保与SQL Server网络连通
- 确认本地运行正常、SQL Server服务正常
最新错误日志
2024-03-29T13:31:08.492306143Z [2024-03-29 13:31:08 +0000] [78] [INFO] Starting gunicorn 21.2.0 2024-03-29T13:31:08.494285752Z [2024-03-29 13:31:08 +0000] [78] [INFO] Listening at: http://0.0.0.0:8000 (78) 2024-03-29T13:31:08.495537458Z [2024-03-29 13:31:08 +0000] [78] [INFO] Using worker: sync 2024-03-29T13:31:08.513749140Z [2024-03-29 13:31:08 +0000] [79] [INFO] Booting worker with pid: 79 2024-03-29T13:40:20.623Z ERROR - Container remi2_1_322f8881 for site remi2 did not start within expected time limit. Elapsed time = 600.4550416 sec 2024-03-29T13:40:20.631Z ERROR - Container remi2_1_322f8881 didn't respond to HTTP pings on port: 1433, failing site start. See container logs for debugging. 2024-03-29T13:40:20.675Z INFO - Stopping site remi2 because it failed during startup.
解决方案
1. 修正Web App健康检查端口配置
日志明确显示Azure Web App错误地将健康检查端口设为SQL Server的1433端口,但你的gunicorn应用监听的是8000端口,这是启动失败的核心原因之一。
- 登录Azure门户,进入目标Web App
- 左侧导航栏选择配置 > 常规设置
- 在启动探测区域,将端口改为8000(与gunicorn绑定端口一致)
- 保存设置并重启Web App
2. 优化数据库连接时机,避免启动阻塞
Azure免费版资源有限,启动时立即执行数据库连接+初始化(本地需20-35秒)会导致启动超时。将连接逻辑延迟到首次请求时执行:
from flask import Flask from sqlalchemy import create_engine import os app = Flask(__name__) engine = None def get_db_engine(): global engine if engine is None: user = os.environ["User_Name"] password = os.environ["Password"] hostName = os.environ["hostName"] port = os.environ["port"] db = os.environ["database"] # 显式添加登录超时参数 database_uri = f"mssql+pyodbc://{user}:{password}@{hostName}:{port}/{db}?driver=ODBC+Driver+17+for+SQL+Server&login_timeout=60" engine = create_engine(database_uri, pool_pre_ping=True) # 执行初始化表操作 with engine.connect() as conn: # 你的初始化代码 pass return engine @app.route('/') def index(): engine = get_db_engine() # 业务逻辑 return "Hello World"
3. 确认SQL Server网络与权限设置
即使做了VNet集成,仍需检查:
- Azure SQL Server的网络设置中,已添加Web App所在VNet的子网规则
- 数据库登录账号拥有
CONNECT权限,且默认数据库配置正确
4. 明确指定启动命令端口
在Azure Web App的配置 > 常规设置中,将启动命令改为:
gunicorn --bind=0.0.0.0:8000 --timeout 600 app:app
避免端口歧义,确保应用监听的端口与健康检查端口一致。
5. 查看详细容器日志
通过Azure门户的日志流,或执行Azure CLI命令查看实时日志,定位数据库连接失败的具体原因:
az webapp log tail --name <你的Web App名称> --resource-group <资源组名称>
内容的提问来源于stack exchange,提问作者Ahad Anjum
相关产品推荐
相关产品推荐

