华为云 APIG 返回 504,为什么 RDS 里已经有了数据

举报
yd_49100212 发表于 2026/11/07 03:02:49 2026/11/07
【摘要】 APIG 返回 504 后,后台写入可能已经提交。结合华为云鸿蒙待办清单案例,说明怎样沿用任务 ID 重试、用唯一约束防止重复创建,以及如何验证超时和并发提交。

华为云 APIG 返回 504,为什么 RDS 里已经有了数据

在手机上新增一条待办,转了几秒后提示请求超时。再点一次,列表里却出现了两条相同内容。遇到这种情况,先别急着把重试次数加大:第一次请求可能已经把数据写进数据库,只是结果没有及时送回手机。

华为云鸿蒙实践中心的“云同步待办清单”案例采用 App → APIG → FunctionGraph → RDS for MySQL 的调用链。案例的排障部分提到,注册接口可能提示失败,数据库里却已经建好了账号。顺着这条链路看,网关等待后端的时间、函数执行时间和数据库事务提交时间,各自影响着请求的不同阶段。

504 出现时,写入可能已经完成

假设 APIG 等待后端响应的时间设为 5 秒。函数在第 4 秒提交了事务,第 6 秒才返回结果。客户端会先收到超时,但数据库已经保留了那次写入。这组时间只是说明执行顺序的例子;实际排查要看实例配置和调用日志。

还有一种顺序是,网关先超时,函数随后才完成提交。客户端拿到 504 时,单凭这个状态码无法判断数据最后有没有写进去。网络断开、客户端主动取消,也会带来类似的不确定性。页面显示“提交失败”容易让人立即再点一次,后台如果把每次请求都当成新建,就会多出一条记录。

排查时可以用同一个业务请求标识,把客户端日志、函数日志和数据库记录对应起来。先确认请求有没有到达函数,再看写入是否提交、响应在什么时候生成。日志中记录请求标识和关键阶段即可,密码、会话 token 和完整用户资料都不需要打印。只看函数入口日志,只能证明执行开始;判断提交结果还需要数据库记录或明确的提交日志。

重试时沿用同一个任务 ID

待办清单的创建操作,可以在用户第一次点击保存时生成任务 ID,并把它和待提交内容一起保存在本地。第一次请求超时后,再次发送时继续使用这个 ID。只有用户明确新增另一条任务,才生成新的 ID。

例如,第一次提交的任务 ID 是 demo-task-001,标题是“检查备份”。网络超时后,重试仍然携带 demo-task-001。如果每次重试都重新生成 ID,服务端看到的就是不同任务,数据库的唯一约束也拦不住重复内容。

服务端需要用唯一约束承接这个约定。下面是演示用表结构,表示同一个用户的任务 ID 不能重复:

CREATE TABLE task_retry_demo (
    user_id BIGINT NOT NULL,
    task_id VARCHAR(36) NOT NULL,
    title VARCHAR(200) NOT NULL,
    PRIMARY KEY (user_id, task_id)
);

用户标识应由服务端校验会话后取得。客户端传来的 user_id 不能直接决定数据归属,否则只改一个参数就可能读写别人的任务。查询已有记录、处理重复键和返回结果,都应带上当前用户的范围。

遇到重复键时,还要检查这次请求与原请求的含义是否一致。相同 ID、相同创建内容,可以返回已存在的任务;相同 ID 却携带另一份内容,则应提示冲突。直接把重复请求里的标题覆盖进去,会让一条迟到的旧请求覆盖用户后来编辑的内容。创建和修改分开处理,更容易解释每次操作的结果。

如果接口同时发消息、扣减库存或调用其他系统,仅给任务表加唯一约束还不够。数据库提交后进程退出,消息可能尚未发出;反过来,重试也可能再次发送消息。这类操作需要把待发送事件与业务写入放进同一事务,再由后台投递,并让接收方识别重复事件。对普通待办创建,先把一条任务的重复写入处理正确,就已经解决了眼前的问题。

验证“超时后再试”这条路径

可以在测试环境中,让函数在事务提交之后延迟返回,延迟时间超过测试网关的后端超时配置。客户端收到 504 后,使用原来的任务 ID 重试,再检查数据库:应当只有一条任务,两次请求最终应指向同一条记录。测试结束后恢复超时配置并移除人为延迟。

还要补两个容易漏掉的场景:两次相同请求同时到达,以及同一个任务 ID 携带不同内容到达。前者检查数据库唯一约束是否生效,后者检查服务端有没有把冲突当成普通重试。用另一个测试账号提交相同 ID,则可以验证数据归属是否正确。

华为云案例中还记录了 VPC 函数冷启动超过网关后端等待时间的现象。调整超时前,先看冷启动和正常调用各自的耗时,确认等待时间是否符合接口需求。延长等待时间能减少一部分超时;网络中断和响应丢失仍然可能发生,写接口的重试行为仍需单独验证。

页面文案也可以据此调整。暂时拿不到结果时,显示“正在确认提交结果”,随后按任务 ID 查询,比立刻提示用户重新新增更合适。查到记录就展示已有任务;仍需重试时,沿用原请求标识,让用户的一次保存操作始终对应同一条数据。

参考:华为云鸿蒙开发实践中心《云同步待办清单:鸿蒙端云一体实战》,其中的“注册提示失败,数据库里却已经建了账号”及“幂等写入与越权防护”部分。本文在该案例问题的基础上讨论重试设计,示例表结构用于说明约束。

https://harmonybp.developer.huaweicloud.com/cases/18f755e68ca24c298b5efb8533ef6a44

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。