记一次线上API调用失败的排查过程:从405到时间同步

最近在开发一个代码审查工具时,遇到了一个有意思的问题。本地测试一切正常,但调用线上API时却一直 失败。整个排查过程挺有意思的,记录下来分享给大家。

背景

我们团队开发了一个内部的代码审查系统,前端使用React,后端是Node.js + Koa框架。最近在开发一个CLI工具,需要调用后端API上传代码审查报告。

问题现象

本地开发时,CLI工具调用本地服务一切正常: POST http://localhost:34789/document/createCodeReviewDocument 返回 200 OK

但调用线上服务时,却返回了405错误: POST gw.example.com/document/cr... 返回 405 Method Not Allowed

排查过程

第一阶段:路由问题

首先怀疑是路由配置问题。查看后端代码发现,我们的路由分为公有路由和私有路由:

  • 公有路由:/public/* (登录等接口)
  • 私有路由:直接挂载,无前缀

但通过浏览器开发者工具发现,线上其他接口都是通过 /api/* 访问的。原来是Nginx做了路由转发:

bash 复制代码
location /api/ {
    proxy_pass http://backend/;
}

第一个坑:线上需要加 /api 前缀,而本地不需要。

第二阶段:认证问题

修复URL后,405错误解决了,但又出现了新问题:

bash 复制代码
{
  "success": false,
  "errorCode": 40403,
  "errorMsg": "{\"code\":9999}"
}

9999是我们系统的默认错误码,说明出现了未知异常。为了定位问题,我临时修改了错误处理代码,让它 返回详细错误信息:

bash 复制代码
} catch (error) {
  // 临时添加详细错误信息
  throw new CodedError(error.message || '系统错误')
}

第三阶段:数据库连接?

重新部署后,发现本地连接生产环境会报数据库连接超时。这很正常,因为阿里云RDS有IP白名单限制。

但奇怪的是,其他接口(如 getProjectList)能正常返回数据,说明线上服务是能访问数据库的。那问题出在哪里?

第四阶段:真相大白

最后实在没办法,只能登录服务器查看日志。PM2的日志暴露了真正的问题:

bash 复制代码
RequestTimeTooSkewedError: The difference between the request time and the current time is too large.

原来是服务器时间不同步!

阿里云OSS有个安全机制:请求时间与服务器时间差不能超过15分钟。我们的服务器时间慢了20多分钟。

解决方案

解决方法很简单,同步服务器时间:

同步时间

bash 复制代码
ntpdate ntp.aliyun.com

设置定时同步

bash 复制代码
echo "*/30 * * * * /usr/sbin/ntpdate ntp.aliyun.com" >> /var/spool/cron/root

重启服务

bash 复制代码
pm2 restart all

经验总结

  1. 不同环境的差异要重视 - 本地和线上的路由配置可能不同(Nginx转发规则) - 注意时区和时间同步问题
  2. 错误处理很重要 - 默认的错误码(如9999)掩盖了真实问题 - 开发环境可以返回详细错误,生产环境要注意信息安全
  3. 日志是排查问题的关键 - 不要只看API返回,要看服务端日志 - PM2、系统日志都可能包含关键信息
  4. OSS等云服务的特殊要求 - 时间同步是基础但容易被忽略 - 签名机制对时间很敏感
  5. 排查思路 - 从表象到本质,层层深入 - 对比正常接口和异常接口的差异 - 必要时登录服务器查看详细日志

这次问题虽然最后解决很简单,但排查过程还是学到不少东西。特别是时间同步这种基础设施问题,平时 不注意,出问题的时候还真不容易想到。


PS: 感谢团队小伙伴们的支持,特别是运维同学提供的服务器权限。

相关推荐
聪明墨菲特12 小时前
HttpClient工具类优化实践:提升性能与可维护性
后端·设计模式
Java中文社群12 小时前
面试官:如何提升项目并发性能?
java·后端·面试
阿杆12 小时前
OAuth 图解指南(阮老师推荐)
前端·后端·架构
Mintopia12 小时前
每个国家的核安全是怎么保证的,都不怕在自己的领土爆炸吗?
前端·后端·面试
tonydf13 小时前
浅聊一下AOP
后端
悟空码字13 小时前
腾讯开源啦,源码地址+部署脚本
后端·腾讯
Xxtaoaooo13 小时前
Spring Boot 启动卡死:循环依赖与Bean初始化的深度分析
java·后端·依赖注入·三级缓存机制·spring boot循环依赖
洛小豆13 小时前
Ubuntu 网络配置演进:从 20.04 到 24.04 的静态 IP 设置指南
linux·后端·ubuntu
JavaGuide13 小时前
2025 程序员时薪排行榜,PDD 太顶了!
java·后端