记一次线上服务器问题排查过程

问题描述

前几天我们更新线上服务器,使用对应的新版客户端连接时,怎么都连不上,如果直接连接其他服,比如我们内部的测试服或者审核服,却一切正常。同时,如果使用老包连接服务器,也是正常的

这个问题查的头疼,每一步都超出我的理解范围

排查过程

首先第一步,我们在服务器接口的必经之路上增加了一个调试日志,只要消息到了服务端,就必定会触发这条日志,然后使用客户端发起请求,发现服务器日志并没有有效记录

但是!老版的客户端是存在有效日志的,这就奇怪了。接下来排查方向要优先确定正式服的环境和测试服环境到底存在什么差别

我司正式服的部署和维护,都由运维来统一管理,所以他们做了什么开发一般是不太清楚的

此时我使用 postman 模拟刚刚的 API,发送至服务器。观察日志发现,postman 的消息可以正确收到,且有对应的日志信息。观察 postman 返回值,可以发现有 cloudflare 相关的内容,因此可以猜测运维在我们服务器前,架设了 cloudflare 的服务,用来隐藏服务器的真实 IP 地址

那么此时我们可以得到如下两个结论:

  • postman 发出的消息可以正确收到
  • 线上环境增加了 cloudflare 服务

目前的有效信息还是非常有限,接下来就需要使用 Surge 这个工具,来定位网络问题了,我使用 Surge 接管 Editor 和真机的所有请求,既然服务是由 cloudflare 提供的,我把 Surge 的 DNS 解析服务器强制设为 1.1.1.1,同时这条域名的所有请求都转发到 warp+ (cloudflare 家的代理) 中

发现依然不通,无论是服务器日志,还是 nginx 日志都没有收到这个请求,那么可以得到如下结论

  • 与 DNS 解析无关
  • 与 代理 无关

接着观察 http 发出的状态,在我们游戏中,这个 API 的访问会有 retry 机制,默认重试 3 次,但是奇怪的是客户端建立了 3 次 tcp 通道

正常 http 请求我们会设置 keep alive 时间,短时间的请求都在一个通道里完成,节约反复握手时间

那么出现这种情况就说明握手时,客户端建立的通道被服务器强制断开了。更奇怪的是,http 协议层不管是客户端还是服务器,我们都没动过,此时开始检查 API 参数是否发生变化,根据 git 的日志可以发现,确实有一个参数名发生了变化,由 A 改成了 B

猜测可能因为参数名发生变化,导致 cloudflare 提供的服务解析失败,接着尝试改回客户端参数,然后看 nginx 日志是否正常

发现依然没有日志,这一步已经完全超出了我的认知范围,但是种种迹象都在暗示 cloudflare 提供的服务跪了

然后直接放弃 DNS 解析,强制在 host 中绑定域名到我们服务器的真实 IP 上,从而绕过 cloudflare 的服务,此时惊喜的发现所有服务一切正常。这时我们就能确定就是 cloudflare 的问题

查到问题后续就是运维的工作了,至于为什么 cloudflare 存在这个问题,目前还不得而知

最后

云服务厂商出问题在我司发生已经是第二次了,上一次是阿里云,对于开发者来说,想要把问题锁定在云服务上,过程还是比较艰辛的

cloudflare 的问题排查了几个小时,只能各种猜测挨个尝试,同时学会这些网络分析工具也非常有必要,如果没有这些软件的辅助,锁定问题范围,查到问题不知道什么时候了