ECS Fargate使用Elasticache Redis时出现Error Code 137故障求助
ECS Fargate容器启动失败(Error Code 137)排查与解决(Redis Pub/Sub场景)
问题描述
在ECS Fargate上部署包含client、nginx、mongo、Redis等组件的服务时,服务端加入以下Redis Pub/Sub代码后,server容器无法进入稳定状态,启动失败并返回Error Code 137,且CloudWatch中无该容器的运行日志:
const REDIS_ENDPOINT = process.env.REDIS_ENDPOINT; const pubClient = createClient({ url: REDIS_ENDPOINT, }); const subClient = pubClient.duplicate(); await Promise.all([pubClient.connect(), subClient.connect()]);
已排查项
- 已将ECS任务定义内存调至15GB(无Redis代码时6GB可正常运行)
- 确认Elasticache Redis端点格式正确:
redis://mycompany-534sdf.serverless.use1.cache.amazonaws.com:6379 - 安全组已开放6379端口
- 本地使用Docker Compose运行服务一切正常
可能的原因与解决方案
1. Redis连接超时/阻塞导致容器启动超时
Fargate容器默认启动超时为60秒,若Redis连接过程因网络延迟、Elasticache节点未就绪等原因长时间阻塞,容器会被强制终止,且可能来不及写入日志。
- 解决方案:
- 给Redis客户端添加超时与重试配置,避免无限等待:
const pubClient = createClient({ url: REDIS_ENDPOINT, connectTimeout: 10000, // 设置10秒连接超时 socket: { timeout: 10000, // 套接字超时 reconnectStrategy: (retries) => Math.min(retries * 50, 500) // 渐进式重试策略 } }); - 增加错误捕获逻辑,确保连接失败时输出日志并主动退出:
try { await Promise.all([pubClient.connect(), subClient.connect()]); console.log("Redis pub/sub clients connected successfully"); } catch (err) { console.error("Redis连接失败:", err); process.exit(1); // 主动退出以便日志被CloudWatch捕获 }
- 给Redis客户端添加超时与重试配置,避免无限等待:
2. VPC网络连通性问题
即使安全组开放端口,Fargate任务所在VPC与Elasticache的VPC可能存在路由或 peering 配置问题,导致无法连通。本地运行时通常使用公网或本地Redis,不会遇到此类问题。
- 解决方案:
- 确认Fargate任务与Elasticache处于同一VPC,或已配置正确的VPC peering(跨VPC场景)
- 用Fargate任务子网内的EC2实例执行
telnet mycompany-534sdf.serverless.use1.cache.amazonaws.com 6379,验证端口连通性
3. Redis客户端版本兼容性问题
本地开发环境与Fargate容器内的Redis客户端版本不一致,可能导致未捕获的兼容性错误,引发容器崩溃。
- 解决方案:
- 查看本地
package.json中的redis依赖版本,在Dockerfile中明确指定该版本安装,确保环境一致:RUN npm install redis@<指定版本号>
- 查看本地
4. Fargate任务执行角色权限不足
任务执行角色缺少VPC网络相关权限,可能导致网络接口创建失败或访问受限。
- 解决方案:
- 确保任务执行角色关联了
AmazonECSTaskExecutionRolePolicy,并包含以下VPC相关权限:ec2:CreateNetworkInterfaceec2:DescribeNetworkInterfacesec2:DeleteNetworkInterface
- 确保任务执行角色关联了
内容的提问来源于stack exchange,提问作者brohxa
相关产品推荐
相关产品推荐

