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

如何在AWS ECS Fargate的CloudFormation中禁用Spring Boot Data MongoDB重试写入

ECS Fargate中Spring Boot连接DocumentDB的重试写入错误及凭证注入方案

问题背景

通过CloudFormation将Docker化的Spring Boot应用部署到AWS ECS Fargate,使用Spring Data MongoDB连接AWS DocumentDB,所有资源均通过模板自动化部署。最初的容器定义通过环境变量注入数据库端点、端口,从Secrets Manager获取用户名和密码:

Environment:
  - Name: SPRING_DATA_MONGODB_HOST
    Value: !GetAtt DbCluster.Endpoint
  - Name: SPRING_DATA_MONGODB_PORT
    Value: !GetAtt DbCluster.Port
Secrets:
  - Name: SPRING_DATA_MONGODB_USERNAME
    ValueFrom: !Sub "${DbCredentials}:username::"
  - Name: SPRING_DATA_MONGODB_PASSWORD
    ValueFrom: !Sub "${DbCredentials}:password::"

应用启动时出现以下错误:

com.mongodb.MongoCommandException: Command failed with error 301: 'Retryable writes are not supported' on server my-db-cluster.cluster-xxxxxxxxxxxx.us-east-1.docdb.amazonaws.com:27017. The full response is {"ok": 0.0, "code": 301, "errmsg": "Retryable writes are not supported", "operationTime": {"$timestamp": {"t": xxxxxxxxxx, "i": 1}}}

原因是DocumentDB不支持重试写入,官方要求通过完整的SPRING_DATA_MONGODB_URI连接字符串设置retryWrites=False,格式如下:

mongodb://<username>:<password>@my-db-cluster.cluster-xxxxxxxxxxxx.us-east-1.docdb.amazonaws.com:27017/database?retryWrites=False

但直接在CloudFormation中定义URI会覆盖原有的用户名/密码环境变量,因此需要解决如何将Secrets Manager中的凭证注入到URI,或通过其他方式禁用重试写入。

解决方案

方案1:直接通过Secrets Manager注入完整连接URI

将包含用户名、密码、retryWrites=False的完整连接字符串存储到Secrets Manager中,然后在容器定义中直接引用该Secret作为SPRING_DATA_MONGODB_URI:

Secrets:
  - Name: SPRING_DATA_MONGODB_URI
    ValueFrom: !Sub "${DbUriSecret}::"

注意:Secret中的URI需严格遵循格式:mongodb://<username>:<password>@<cluster-endpoint>:<port>/<database>?retryWrites=False

方案2:容器启动脚本动态拼接URI

由于CloudFormation无法直接将Secrets Manager的单个字段嵌入到环境变量字符串中,可通过容器启动命令动态拼接URI:

  1. 保留原有环境变量和Secrets注入配置:
Environment:
  - Name: SPRING_DATA_MONGODB_HOST
    Value: !GetAtt DbCluster.Endpoint
  - Name: SPRING_DATA_MONGODB_PORT
    Value: !GetAtt DbCluster.Port
Secrets:
  - Name: SPRING_DATA_MONGODB_USERNAME
    ValueFrom: !Sub "${DbCredentials}:username::"
  - Name: SPRING_DATA_MONGODB_PASSWORD
    ValueFrom: !Sub "${DbCredentials}:password::"
  1. 修改容器Command字段,用Shell脚本拼接URI并启动应用:
Command:
  - "/bin/sh"
  - "-c"
  - >
    export SPRING_DATA_MONGODB_URI="mongodb://${SPRING_DATA_MONGODB_USERNAME}:${SPRING_DATA_MONGODB_PASSWORD}@${SPRING_DATA_MONGODB_HOST}:${SPRING_DATA_MONGODB_PORT}/?retryWrites=False" &&
    java -jar your-app.jar

启动时会自动将Secrets注入的凭证与端点信息拼接成符合要求的URI。

方案3:通过Spring Boot配置直接禁用重试写入(推荐)

无需修改连接方式,直接通过Spring Boot配置禁用重试写入,保留原有凭证注入方式:

  • 方式一:在应用的application.properties或application.yml中添加配置:
spring.data.mongodb.retry-writes=false
  • 方式二:通过环境变量注入该配置(无需修改应用代码):
Environment:
  - Name: SPRING_DATA_MONGODB_HOST
    Value: !GetAtt DbCluster.Endpoint
  - Name: SPRING_DATA_MONGODB_PORT
    Value: !GetAtt DbCluster.Port
  - Name: SPRING_DATA_MONGODB_RETRY_WRITES
    Value: "false"
Secrets:
  - Name: SPRING_DATA_MONGODB_USERNAME
    ValueFrom: !Sub "${DbCredentials}:username::"
  - Name: SPRING_DATA_MONGODB_PASSWORD
    ValueFrom: !Sub "${DbCredentials}:password::"

这种方式最简洁,完全兼容原有部署模式,无需调整URI或启动脚本。


内容的提问来源于stack exchange,提问作者Garret Wilson

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 08:08:11