使用Python 3.11.x部署AWS AppRunner健康检查失败,3.8.16正常
问题背景
在AWS AppRunner上部署Django应用时,Python 3.8.16版本可正常运行,但切换到官方支持的Python 3.11.9后,部署因健康检查失败终止:
- AppRunner事件日志:TCP健康检查(端口8000)失败,部署ID
xxxxxxxxx终止 - 应用日志:pip安装依赖时出现网络不可达错误:
NewConnectionError('<pip._vendor.urllib3.connection.HTTPSConnection object at xxxxxxxxx>: Failed to establish a new connection: [Errno 101] Network is unreachable')
已尝试的调整:修改startup.sh使用pip3/python3、更新apprunner.yaml指定python311运行时、切换端口(8000/8080)、改用HTTP健康检查、调整安全组规则、集成django-health-check,均无效;切回Python 3.8则恢复正常。
关键错误分析
健康检查失败只是表象,核心问题是Python 3.11环境下pip无法连接PyPI下载依赖,导致Django服务未正常启动。这说明网络连接或环境配置差异是问题根源,而非Python 3.11与3.8的健康检查逻辑有本质区别。
排查与解决方向
1. 检查AppRunner运行时的网络权限
AppRunner的Python 3.11运行时可能存在出站网络策略的细微差异:
- 如果使用VPC连接模式,确认VPC安全组和NACL允许出站443端口(PyPI的HTTPS端口)
- 若使用默认公共网络,检查是否有账户级别的网络限制(比如AWS组织的SCP策略)阻止了Python 3.11环境的出站流量
2. 调整依赖安装时机
将依赖安装从启动脚本(startup.sh)移到构建阶段,避免运行时环境的网络限制:
修改apprunner.yaml的build步骤,提前安装依赖:
runtime: python311 runtime-version: 3.11.9 build: commands: - pip3 install --upgrade pip - pip3 install -r requirements.txt run: command: ./startup.sh network: port: 8000 healthCheck: protocol: TCP port: 8000 startDelaySeconds: 30 # 延长启动等待时间,适配Python 3.11的启动速度
3. 验证pip配置与源
Python 3.11的pip可能存在默认配置差异,强制指定PyPI源排查:
在构建命令中添加源参数:
pip3 install -r requirements.txt -i https://pypi.org/simple/
同时可添加pip3 config list查看当前pip配置,确认是否存在代理或源的异常设置。
4. 完善服务启动日志与兼容性检查
在startup.sh中添加调试日志,确认Django服务是否真的启动:
#!/bin/bash # 验证Python环境与依赖 echo "Python version: $(python3 --version)" echo "Installed packages:" pip3 list # 检查Django配置合法性 python3 manage.py check # 启动服务 python3 manage.py runserver 0.0.0.0:8000
此外,确认requirements.txt中的依赖包支持Python 3.11(比如某些旧版本的Django或第三方库可能不兼容3.11)。
5. 调整健康检查触发时机
Python 3.11下Django的启动速度可能略快或慢于3.8,延长健康检查的启动延迟:
在apprunner.yaml的healthCheck部分设置startDelaySeconds: 30(默认可能是10秒),给服务足够的启动时间。
总结
Python 3.11与3.8在AppRunner的健康检查逻辑上没有本质差异,问题更可能是Python 3.11运行时的网络配置、pip行为或依赖兼容性导致的服务未启动,而非AppRunner的bug。优先排查依赖安装阶段的网络问题,调整构建流程与健康检查参数,验证环境兼容性即可解决。
内容的提问来源于stack exchange,提问作者qualityPancakes

