用 APM 全链路追踪,29ms 内定位到 Docker 部署的 SSL 配置错误

这是一个真实的排查案例。没有日志打印的神操作,没有凭经验瞎猜的过程,只有一张链路追踪图,直接把问题定位到了具体的代码位置和请求节点。


起因:部署完成,注册接口一直 500

最近在帮一个客户用 Docker 镜像部署 Webfunny 私有化系统。镜像拉下来,容器启动顺利,服务也跑起来了。

但当我们打开页面,进行首次注册的时候,接口一直返回 500

第一反应当然是去看日志。翻了一圈容器日志,找到了一行报错:

bash 复制代码
POST http://your-domain.com:80/wfMonitor/monitorBaseInfo → 301
GET https://your-domain.com:80/wfMonitor/monitorBaseInfo → error

日志里能看到的信息就这些------某个接口调用失败了,但为什么失败,失败在哪个环节,日志完全没有说清楚。

这种情况就很头疼:你知道接口出错了,但不知道是网络问题、配置问题、还是代码问题。如果靠猜,可能要折腾半天。


转机:打开 APM 自监控

Webfunny 本身就内置了一套自监控系统------系统会对自己的服务进行监控,包括接口调用链路、耗时、状态码、异常信息。

我们打开 APM 的全链路追踪模块,等了片刻让数据采集上来,然后找到这次注册请求对应的 TraceID,点开链路详情。

整条链路一眼就清楚了:


链路图说了什么

从链路图里可以看到这次请求的完整过程:

  • 总耗时:29ms
  • 应用数:1,节点数:18
  • 请求入口:GET /wfCenter/registerForSaas

往下展开,能看到:

  1. 注册逻辑走到了 Controller/CenterUserController.registerForSaas
  2. 然后调用了 POST http://your-domain.com:80/wfMonitor/monitorBaseInfo
  3. 这个请求返回了 301 跳转
  4. 跳转目标是 GET https://your-domain.com:80/wfMonitor/monitorBaseInfo
  5. 这个 HTTPS 请求连接到了 :80 端口,TLS 握手失败

右侧的异常详情写得非常清楚:

vbnet 复制代码
error.message: write EPROTO 14070351799289:error:1408F10B:SSL routines:
ssl3_get_record:wrong version number:
/deps/openssl/openssl/ssl/record/ssl3_record.c:332

error.object: EPROTO

根本原因:80 端口被强制跳转到 https://domain:80

问题找到了。

整个链路失败的根源是:客户的服务器对 http://domain/ 配置了强制 HTTPS 跳转,但跳转目标 URL 写错了

正常的 HTTPS 跳转应该是:

bash 复制代码
http://your-domain.com/ → https://your-domain.com/(443端口)

但实际跳转的目标是:

bash 复制代码
http://your-domain.com:80/ → https://your-domain.com:80/(80端口)

:80 是 HTTP 端口,不支持 SSL 握手。代码拿到 301 跳转后,试图用 HTTPS 去连 80 端口,自然就报了 EPROTO: wrong version number------SSL 协议和端口对不上。

这个问题在普通日志里完全看不出来,因为日志只记录了"调用失败",没有记录跳转过程和 SSL 握手的细节。


修复方式

找到原因后,修复就很简单了。检查客户服务器的 Nginx 配置,找到 HTTP 强制跳转的规则:

nginx 复制代码
# 错误配置(保留了 :80 端口)
return 301 https://$host:$server_port$request_uri;

# 正确配置(不带端口号,自动走 443)
return 301 https://$host$request_uri;

改完之后重启 Nginx,重新注册,接口正常返回,问题解决。


这个案例说明了什么

如果没有 APM 链路追踪,这个问题的排查路径大概是这样的:

  1. 看到 500,去看应用日志
  2. 日志里看到接口报错,猜是网络问题
  3. ping 域名、telnet 端口、curl 接口
  4. 发现 301 跳转,再去排查跳转配置
  5. 找到 Nginx 配置,定位问题

这个过程快则半小时,慢则几个小时,而且每一步都依赖经验。

有了 APM 全链路追踪,整个过程是:

  1. 打开链路详情
  2. 看到 301 跳转到 https://domain:80
  3. 看到 EPROTO: wrong version number
  4. 直接去改 Nginx 配置

定位时间从小时级压缩到了分钟级。


一点延伸

这类问题在私有化部署的场景里很常见,尤其是在以下几种情况:

  • 服务器之前跑过其他业务,Nginx 有遗留的 HTTPS 跳转配置
  • 客户自己配置了全站 HTTPS,但跳转规则写得不规范
  • Docker 部署时端口映射和域名配置没有对齐

排查这类问题,光靠应用日志是不够的。需要能看到完整的请求链路,包括每一次跳转、每一个 DNS 解析、每一次 TCP 握手,才能准确定位。

这正是 APM 全链路追踪的价值所在。


Webfunny 的 APM 功能支持私有化部署,和前端监控、埋点系统集成在同一个平台,无需单独接入,一套 SDK 搞定:

相关推荐
涡能增压发动积16 小时前
同样的代码循环 10次正常 循环 100次就抛异常?自定义 Comparator 的 bug 让我丢尽颜面
后端
Wenweno0o16 小时前
0基础Go语言Eino框架智能体实战-chatModel
开发语言·后端·golang
swg32132116 小时前
Spring Boot 3.X Oauth2 认证服务与资源服务
java·spring boot·后端
tyung16 小时前
一个 main.go 搞定协作白板:你画一笔,全世界都看见
后端·go
gelald16 小时前
SpringBoot - 自动配置原理
java·spring boot·后端
@yanyu66616 小时前
07-引入element布局及spring boot完善后端
javascript·vue.js·spring boot
@大迁世界17 小时前
2026年React大洗牌:React Hooks 将迎来重大升级
前端·javascript·react.js·前端框架·ecmascript
殷紫川17 小时前
深入拆解 Java 内存模型:从原子性、可见性到有序性,彻底搞懂 happen-before 规则
java·后端
元宝骑士17 小时前
FIND_IN_SET使用指南:场景、优缺点与MySQL优化策略
后端·mysql
风止何安啊17 小时前
为什么要有 TypeScript?让 JS 告别 “薛定谔的 Bug”
前端·javascript·面试