如何让Ubuntu EC2上的Python Flask应用连接RDS MySQL数据库
问题解答
关于EC2出站规则的疑问
如果你的RDS使用公网IP对接,EC2安全组默认出站规则是全量放通,无需额外配置;如果你手动修改过EC2安全组的出站规则,必须新增允许TCP 3306端口(MySQL默认端口)到RDS公网IP/关联安全组的出站规则,否则会出现连接中断问题。
故障排查思路
你当前SSH登录EC2后可正常连接RDS,说明底层网络连通性正常,500错误大概率出在应用运行环境、配置或代理链路层面,按优先级依次排查:
- 优先查应用运行日志
大部分Python Web框架(Django/Flask/FastAPI等)的500错误会打印具体堆栈信息,确认报错原因是否为数据库连接失败、配置读取失败、权限不足等。重点注意:你SSH终端配置的数据库环境变量、配置文件读取权限,是否对应用进程的运行用户(如nginx、www-data、appuser等)生效,很多场景下终端能读到的配置,应用进程因权限问题读不到会直接抛500。 - 模拟应用环境验证数据库连接
在EC2上编写最小测试脚本,使用和应用完全一致的运行用户、配置参数测试连接:
用应用运行用户执行脚本:import pymysql # 替换为你应用实际使用的数据库配置 DB_CONFIG = { "host": "RDS公网地址", "user": "数据库用户名", "password": "数据库密码", "database": "业务库名", "port": 3306 } try: conn = pymysql.connect(**DB_CONFIG) print("数据库连接正常") conn.close() except Exception as e: print(f"连接失败,报错信息:{str(e)}")sudo -u 你的应用运行用户名 python3 测试脚本名.py,根据返回的报错信息定位问题即可。 - 检查NGINX代理配置
查看NGINX错误日志(默认路径/var/log/nginx/error.log),确认是否存在转发超时、上游服务不可达、请求头缺失等问题。核心要确认NGINX的反向代理规则是否正确把请求转发到后端应用服务的端口,是否配置了必要的请求头传递参数,参考配置如下:location / { proxy_pass http://127.0.0.1:你的应用监听端口; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } - 核对网络访问规则
- 确认RDS安全组入站规则,已放通EC2的公网IP或EC2关联的安全组ID访问3306端口,不要仅放通你本地办公网的IP
- 确认EC2所在子网的网络ACL没有拦截3306端口的出站请求,以及临时端口段的入站响应
- 确认RDS实例已开启公网访问权限,所在子网配置了公网路由
内容的提问来源于stack exchange,提问作者Josepch
相关产品推荐
相关产品推荐

