mobile wallpaper 1mobile wallpaper 2mobile wallpaper 3mobile wallpaper 4
7234 字
19 分钟
手机验证码自动送到电脑:一次横跨五层链路的排查实录
2026-09-24
TIP

全文记录的是一件事:让手机收到的短信验证码,自动出现在电脑上、能直接复制。 需求一句话讲完,落地却横跨了手机规则、HTTP 通道、Cloudflare 隧道、本机服务、前端面板五层。 真正花时间的不是写代码(服务本身只有几百行),而是在没有任何报错的情况下,判断问题出在哪一层。

一、先别急着动手:这个问题有哪条路根本走不通#

需求很朴素:手机上收到验证码,希望电脑上能立刻看到、能直接复制。

我的第一反应和你一样——微信。手机微信每天都在弹消息,让它顺手抄一份给我,不是最自然的事吗?

但动手之前我先停了一下,问了自己一个问题:微信到底能不能「读」用户的消息?

答案是:架构上不能,而且这条路的替代方案代价太高。

微信官方对个人号开放的只有「外部推送给用户」这一个方向——服务号模板消息、企业微信群机器人 Webhook,都是「我从外面往微信里塞一条」。而「把用户收到的消息读出来」这个方向,官方从来没有开放过接口,个人号也没有。

那么市面上那些看起来能读微信消息的方案呢?我梳理了一下,全是同一个路子:

方案原理代价
wxauto模拟 UI 自动化,戳微信窗口的控件违反用户协议,有封号风险
WeChatFerry注入 DLL,Hook 微信客户端协议同上,且版本一变就废
wechaty多数 Puppet 底层还是走上面两条同上
CAUTION

这不是技术难题,是风险取舍。 微信个人号承载了我几乎全部的人际关系和账号体系,为了省一步复制粘贴,去赌一次封号,这笔账怎么算都不划算。

于是需求被重新定义了。我把「把验证码发到微信」拆成两个可以独立解决的小问题:

  1. 传输:手机 → 电脑。这条必须是我自己能完全掌控的链路。
  2. 通知副本:电脑 → 微信。这个可以退而求其次,只做「推给我看」的单向广播。

想清楚这一层,方案就自然浮出来了:传输走我自己搭的 HTTP 服务,微信只在最后一环挂一个消息副本。 微信从「传输通道」降级成「围观群众」,风险就没了。

NOTE

这次决策后来被证明是整个项目里最值钱的一步。很多需求看起来是个技术问题,其实是个风险问题。 先问「哪条路根本不该走」,比问「哪条路最快」有用得多。

二、把一条链路拆成五段#

方案定了,剩下的是设计。既然要自己搭,那就要保证每一段都可以被单独验证。

我把整条链路画了出来,一共五段:

手机收到短信
↓
① SmsForwarder 规则命中 → 决定「哪条短信值得转发」
↓
② HTTP 发送通道推送 → POST https://code.du-19.top/sms
↓
③ Cloudflare 隧道 → 公网入口,落到 HKG 节点
↓
④ 本机服务 :48272 → 令牌校验 + 验证码提取
↓
⑤ 浏览器面板 → 实时显示、一键复制

技术选型上有两个刻意的决定:

决定一:本机服务用 Python 标准库写,零第三方依赖。

不是因为我喜欢造轮子,而是这类常驻小工具最怕的就是「半年后想起来用,结果依赖装不上了」。用 http.server.ThreadingHTTPServer 加一个 BaseHTTPRequestHandler 就够了——不需要 pip,不需要虚拟环境,复制一个 .py 文件到任何一台装过 Python 的机器上都能跑起来。服务监听 127.0.0.1:48272,只对本机开放。

决定二:不用 Cloudflare Quick Tunnel,用 Named Tunnel 绑自己的域名。

Quick Tunnel 每次重启都换域名,手机上配好的地址就废了。Named Tunnel 配置在云端(token 模式,本地连 config.yml 都没有),换来的是一个永久固定的地址 code.du-19.top——手机配一次就不必再管。

这两件事和上一篇隧道实战是同一套基础设施思路:起服务 → 加路由 → 验连通。

服务的核心逻辑里有两个细节值得一提。

第一个是令牌鉴权怎么做到「本机免密、公网必须验」。

本机访问要方便(面板一打开就能用,不该问我要密码),公网访问必须严防(这个地址一旦泄露,别人就能往我的收件箱里灌垃圾)。区分「请求从哪来」靠的是请求头:

def _from_tunnel(self):
"""请求是否来自 Cloudflare 隧道(即公网)。"""
for h in ("CF-Connecting-IP", "X-Forwarded-For", "CF-Ray"):
if self.headers.get(h):
return True
return self.client_address[0] not in ("127.0.0.1", "::1")

经隧道进来的请求一定带 Cloudflare 的标记头,而且携带真实的公网客户端 IP;本机直连则没有这些头,来源地址是 127.0.0.1。判断出来源,再决定要不要查令牌。

第二个是验证码怎么从一堆文本里准确抠出来。

短信的格式千奇百怪:您的验证码是 123456 / 【XX】校验码 987654,请勿泄露 / 甚至还有服务商把数字用空格隔开成 9 2 4 7 1 5。所以我用了两级策略:

  • 一级:关键词优先。 用正则定位 验证码|校验码|动态码|验证代码|code 附近出现的 4–8 位数字。有上下文锚点,准确率最高。
  • 二级:空格合并 + 兜底。 先把数字之间的空格吃掉(re.sub(r"(?<=\d)[ \t]+(?=\d)", "", text),把 9 2 4 7 1 5 还原成 924715),再找独立出现的 4–8 位数字。

实测这一套能覆盖我遇到的全部短信格式。

前端面板则做成了「最新一条码超大字 + 一键复制 + 2 秒轮询 + 新码到达时提示音和标题闪烁」——因为这东西的使用场景是:我在填一个注册表单,等码,切过去,复制,切回来。它不需要好看,它需要我一眼就能看见,一下就能拿走。

东西写完,本地测试全绿。然后故事才真正开始。

三、第一关:Cloudflare 后台登不上去#

按计划,我要去 Cloudflare 后台给隧道加一条路由,把 code.du-19.top 指向本机的 48272 端口。

结果一打开登录页,就卡在这儿了:

请完成 Turnstile 验证,然后重试。

刷了、重试了、换了浏览器,永远是这句话。人机验证的方框画不出来,或者画出来了点完永远不通过。

这种「完全没有错误信息」的问题,最容易让人开始瞎试。我给自己定了一条规矩:不许瞎试,只许排除。

于是我列了一份「可能导致验证失败的因素」清单,然后一条一条去证伪,每条都拿到实测结果:

假设验证方式结论
系统时间偏差导致 token 失效对比本机与标准时间偏差仅 0.8 秒 → 排除
系统代理配置错乱读注册表 ProxyEnable显示为已关闭 → 排除(但见下)
人机验证脚本被墙直接下载 Turnstile 的 api.js302→200,86 KB 完整拿到 → 排除
hCaptcha 脚本被墙下载 hCaptcha 的 api.js200,359 KB 完整拿到 → 排除
本地代理工具劫持了域名检查 hosts 文件抓到 127.0.0.1 hcaptcha.com → 有嫌疑,但不是根因

前四条全部排除,第五条抓到了点东西但不解释全部现象——因为 hosts 里的劫持条目几分钟就会被代理工具刷掉一次,而我的失败是稳定复现的。

到这里我意识到:我一直在查「我这边」的问题,但也许问题不在我这边。

那就换个方向——不看自己的机器,看流量到底从哪儿出去、落到哪个机房的。

curl -s https://www.cloudflare.com/cdn-cgi/trace

返回结果里有几个关键字段:

ip=112.32.12.183
loc=CN
colo=SJC

colo=SJC——圣何塞。

我又用 IPv6 出口测了一次,colo 依然是 SJC。

WARNING

这才是根因。colo 表示 Cloudflare 边缘节点机房代码。一个中国移动的用户,正常应该落在 HKG(香港) 或 NRT(东京),结果 IPv4 和 IPv6 两条出口双双落到美国圣何塞。

对中国 IP 来说,「从美国节点接入」本身就是一种异常流量特征。Cloudflare 的风控遇到这种特征会升级为强制人机挑战,而挑战数据要横跨太平洋一个来回才能完成——往返一次就超时了,于是验证永远完不成。

所以这不是「被墙」,也跟我的浏览器、我的系统时间、我的 hosts 都没关系。是中国移动的国际出口把 Cloudflare 的流量绕道走了美国,BGP 路由问题。

解法也就顺理成章了:走代理换个落点。 打开 Clash 连上香港节点后重新访问,colo 变成 HKG,登录页一次就过了。

NOTE

这一关教给我的是分层排查的纪律:先列出所有可能的层(客户端状态 → 本地网络 → 出口路由 → 对端风控),然后从成本最低的层开始逐层证伪。 我前面排查的每一条都没有白做——它们共同把范围压缩到了「出口路由」这一层,让我在第 15 分钟就能锁定方向,而不是在浏览器设置里折腾一晚上。

排除掉不可能,剩下的就是答案,哪怕它看起来毫无道理。

四、第二关:一个只在隧道里才出现的 Bug#

登进后台、加好路由、https://code.du-19.top/health 返回 200。隧道通了。

然后我做了一件差点把自己坑进去的事——我拿本机 curl 测了一遍,全绿,就以为服务没问题了。

直到真实流量经过隧道打进来,日志里冒出来一行:

501 Unsupported method ('{"content":"bad"}POST')

这个报错信息很怪。「不支持的方法」后面跟着的应该是一个 HTTP 动词,比如 GET、POST,结果它里面塞的是一段 JSON 的一半,还接了个 POST。

看到这行我第一反应是服务端把请求行给解析错了。但为什么会解析错?

盯着那行日志想了很久,突然串起来了——这是典型的 HTTP keep-alive 请求体串包。

BaseHTTPRequestHandler 在 protocol_version = "HTTP/1.1" 下会复用连接。复用时,服务端处理完一个请求,必须把这个请求的请求体完整读干净,否则残留的字节会被当成下一个请求的起始行去解析。

而我的代码里,do_POST 第一件事是校验令牌。令牌不对就直接返回 401 —— 请求体根本没读,就那么留在了缓冲区里。下一个请求复用这条连接时,缓冲区里已经躺着上一轮的残留体:

{"content":"bad"}POST /sms?token=... HTTP/1.1

服务端把 {"content":"bad"}POST 当成了 HTTP 方法名,于是报 501 Unsupported method。

为什么本机 curl 测不出来? 因为 curl 每次请求都是新建连接,连接根本没被复用,残留体自然无从谈起。而 cloudflared 隧道会在同一个持久连接上连续转发多个请求——这个 Bug 只有真实流量才踩得到。

修法很干净:把「读请求体」这件事提到所有分支之前,无论后面走哪条路,都先把身体读完。

def do_POST(self):
path = urllib.parse.urlparse(self.path).path
# 无论后面走哪条分支,都先把请求体读完。
# 否则在 HTTP/1.1 keep-alive 下,未消费的 body 会被当成下一个请求解析,
# 表现为 501 Unsupported method —— 经 Cloudflare 隧道复用连接时必现。
raw = self._read_body()
if path == "/sms":
if not self._token_ok():
self._json({"ok": False, "error": "invalid token"}, 401)
return
self._handle_sms(raw)
return
...

修完之后我没敢只测一遍。因为单发请求永远测不出这个问题,我专门做了一次同一连接连发两个请求的回归:先发一个不带令牌的(期望 401),紧跟着在同一条连接上发一个带令牌的(期望 200)。结果符合预期,不再串包。

CAUTION

「本地测不出来」是这次最危险的一个信号。 一个 Bug 如果只在「真实的连接复用方式」下出现,那么任何「每次新建连接」的测试都是假阴性——它会给你一种「已经测过了」的安全感,而这种安全感最贵。

从此我给自己加了一条规矩:给本机服务做隧道暴露之前,必须用「同一连接连发两个请求」的方式做回归。 单发请求测不出 keep-alive 相关的任何问题。

五、第三关:真机上线之后,它一动不动#

服务修好、隧道通了、手机上的转发 App 也配好了。按说该收工了。

我让家人用手机发了一条真实验证码过来。然后盯着电脑上的面板——什么都没有。

再看面板状态,一切正常:2 秒一次的轮询请求,清一色 200,从未中断。

这时候最容易犯的错是开始乱改:是不是面板的 Bug?是不是浏览器缓存?要不要重启一下服务?

都别动。先去读日志。

[21:45:24] GET /api/codes?...&_=1790257524593 200
[21:45:26] GET /api/codes?...&_=1790257526582 200
[21:45:28] GET /api/codes?...&_=1790257528582 200
...

一条一条往下翻,每 2 秒一条面板轮询,非常规律。然后我把日志里所有的 POST /sms 记录单独拎出来:

[20:45:00] POST /sms 200
[20:47:35] POST /sms 200
[21:30:09] POST /sms?token=*** 200 ← 通道自测,成功
[21:32:32] POST /sms?token=*** 200 ← 转发成功一条真实验证码
[21:34:48] POST /sms?token=*** 200
[21:36:39] POST /sms?token=*** 200
[21:37:20] POST /sms?token=*** 200 ← 最后一次
(之后:零)

21:37:20 之后,再没有任何一条 /sms 请求。

这个事实把问题一次性钉死了:电脑侧的服务没问题(面板轮询一直 200),隧道没问题(之前成功转发过),通道配置没问题(21:30 的通道自测明确返回「发送通道测试成功」)。

请求压根没有从手机发出来。

TIP

这就是我一直坚持「日志要能证伪」的原因。 「有一条成功的记录」只是弱证据,「此后彻底零请求」才是强证据。 后者直接把责任方钉在了手机侧,让我不用再去怀疑电脑上的任何一行代码。

没有这条日志,我大概会去改面板、重启服务、重装隧道——全都是无用功。

方向锁定后,问题就变成了「手机上的转发规则为什么没命中」。对照配置页逐项检查,找到并修掉了三个叠加在一起的毛病:

毛病一:匹配模式选错了。

规则里我填的匹配值是:

验证码|校验码|动态码|验证代码|code

这是个正则表达式——| 表示「或」。但我把「匹配模式」选成了「包含」。

WARNING

在「包含」模式下,整个字符串是按字面意思去找的。程序会去短信里搜「验证码|校验码|动态码|验证代码|code」这一整串带竖线的文字——当然永远搜不到。 规则永远不命中。 必须把匹配模式改成「正则匹配」,| 才会被当成「或」来解释。

毛病二:「启用该条转发规则」的开关是关着的。

这个最气人。开关在页面底部,灰灰的,不显眼。关着就意味着这条规则根本不存在——前面填得再对都是摆设。

毛病三:「启用自定义模板」被误开了。

这个开关的本意是「自定义发给服务器的消息体」。但我一开始搞混了,把过滤关键词填进了模板里。而模板的优先级高于发送通道里配好的内容,会直接覆盖正确的 JSON 消息体。

这三个毛病任何一个单独存在,都足以让整条链路静默失效;偏偏它们凑到了一起,而且全都不报错。

改完之后我先点了规则里的「测试」按钮——它会用这条规则走一遍完整的发送流程,不需要真短信,几秒钟就能验证。面板上立刻跳出了记录。又请人从另一部手机发了一条测试短信过来,也顺利到达:

[21:47:06] 来源=1********** 验证码=778899
[21:47:29] 来源=1********** 验证码=452314

到这里我以为收工了。结果真实验证码依然一条都不来。

新证据很有意思:那两条成功的测试短信来自一个普通手机号;而收不到的,全是猪八戒网这类106 服务号发来的。同样是「验证码短信」,一个能过,一个过不去。

CAUTION

这一步如果我就此收手,会得出一个完全错误的结论——「规则配好了,能用」。 因为我的测试数据恰好来自一个碰巧能通过的那一类发送方。 测试数据选得不对,测试通过反而会误导你。 这是这次最贵的一课。

顺着「普通号能过、服务号不能过」这条线索查下去,终于在手机系统的权限设置里找到了真正的根因。

Android 的短信权限本来是一个整体。但小米在 MIUI / HyperOS 上把它拆成了两级:

权限级别覆盖范围第三方 App 默认
普通短信私人号码发来的短信✅ 默认授予
通知类短信106 服务号发来的验证码、通知类短信❌ 默认拒绝,且 App 无法主动申请

小米官方开发者文档说得很直白:其他应用无法申请「通知类短信」权限,默认就是拒绝,必须在系统设置里手动允许才行。

于是整件事的逻辑闭环了:

  • 朋友手机发来的测试短信 → 属于「普通短信」→ 权限已有 → ✅ 转发成功
  • 网站发来的验证码 → 属于「通知类短信」→ 权限被拒 → ❌ App 连广播都收不到

而 SmsForwarder 的官方文档里其实早就写着这一条,只是我没去读:

无法正确转发通知类短信(普通短信正常),涉及 ROM 有小米 MIUI、华为 EMUI、vivo OriginOS、OPPO ColorOS 等。国内厂商定制系统提供了验证类短信安全保护功能,导致验证码不能正常通过广播获得。

TIP

注意这里的区别。 华为、vivo、OPPO 的做法是给一个「验证码安全保护」开关,关掉即可; 而小米不同——它没有那个开关,是用「通知类短信」这个独立权限实现的。 拿别人的教程照抄,在小米上会完全找不到对应项。同一个问题,每家 ROM 的解法都不一样。

手动授予「通知类短信」之后,第一条真实验证码终于穿过了整条链路:

[22:47:52] [隧道] POST /sms?token=*** 200
来源=10683547470000000885
内容=【阿里云盘】验证码:7*****。此验证码只用于进行短信登录,15分钟内有效

五层链路,至此才算真正通了。

六、我在这类问题上用的方法#

整个项目最值得复用的,其实是这几条在过程中逐步长出来的习惯。

第一,动手之前先做减法,而不是加法。

不要一上来就想「我怎么最快实现它」,先想「哪条路我不该走」。微信读取个人消息这条路,技术上勉强能做,但风险不可接受——这一步想清楚了,后面所有设计都变简单了。

第二,把链路画出来,然后要求每一段都能单独出证据。

五段链路的价值不在于画得好看,而在于出问题时我能说清「哪一段是绿的」。这次排查中我前后三次给出了「链路状态板」,每次都精确缩小了怀疑范围。

第三,面对没有报错的问题,只排除,不猜测。

Turnstile 那一关我一共证伪了五条假设。每一条被排除的假设都是有用的——它们不是弯路,是把搜索空间一寸寸压下去的过程。

第四,让日志带上「是谁在说话」。

这个改进是我在第五阶段做的,也是我认为最有效的一处工程优化。原来的日志里所有请求的来源地址都显示 127.0.0.1(因为 cloudflared 是本机进程,手机推来的请求也是本地转发),完全分不出「面板在轮询」还是「手机在推送」。

我把来源标记加进了日志:

tag = "隧道" if self._from_tunnel() else "本机"
ua = (self.headers.get("User-Agent") or "").strip()
if ua:
tag += " " + ua[:36]

改完之后,日志长这样:

[21:47:38] 127.0.0.1 [本机 Mozilla/5.0 (Windows NT 10.0; Win64;] - "GET /api/codes ..." 200
[21:47:44] 127.0.0.1 [本机 curl/8.13.0] - "GET /health HTTP/1.1" 200
[21:47:51] 127.0.0.1 [隧道 curl/8.13.0] - "GET /health HTTP/1.1" 200

一眼可辨。SmsForwarder 用的是 okhttp,所以下次再出问题,只要 grep 隧道 看一眼有没有 okhttp 的记录,五秒钟就能判断责任方在手机还是在电脑。

第五,先让它跑起来,再收紧。

配置正则表达式的时候,我没有一上来就调那些复杂的分支。我的做法是先用一条「万能规则」——匹配模式选正则匹配,匹配值填 [\s\S]*(匹配一切)——把所有短信都转发过来,确认整条链路能跑通;然后再把过滤条件收紧成正则。

TIP

这个顺序很重要。如果一上来就用复杂正则,你将无法区分「是正则写错了」还是「是通道配错了」——两个变量同时变化,问题就不可解了。 一次只让它变一个。

第六,警惕「静默失败」。

这次遇到的三个配置坑,没有一个给出错误提示。更早那次的 cloudflared service install 权限不足、以及服务端那个 501 之后的残留行为,也都是沉默地失败。

这类「跑完了、没报错、但什么也没发生」的失败,是排查中最贵的一种。 对它们唯一有效的办法,就是主动在关键节点上放一个能产出证据的东西——一条日志、一个状态码、一个测试按钮。

第七,检查你的测试数据有没有「代表性」。

我差点栽在这最后一步。三个配置坑修完之后,测试短信成功转发,我当时认定已经完事了。但我的测试数据来自一个普通手机号,而真正要处理的验证码来自 106 服务号——这两者恰好落在手机系统里两个不同的权限级别上。「通知类短信」那个权限没开,测再多次也测不出来。

CAUTION

测试通过的前提是:测试数据覆盖了真实场景。 否则「全绿」的测试结果不是保障,是幻觉——而且是一种会让你停止排查的幻觉。 教训:验证一件事能不能行,要用真实的那条路径去验,别用你自己造的那条。

第八,官方文档里「针对特定机型的已知问题」,应该最先读。

SmsForwarder 的官方 wiki 里白纸黑字写着「无法正确转发通知类短信(普通短信正常),涉及小米 MIUI、华为 EMUI……」。我在电脑前折腾了近两个小时,才想到去翻这句话。

厂商文档里给特定机型列的坑,是别人已经替你踩过的。这一步该放在排查序列的最前面,而不是最后。

七、复盘#

把这次遇到的坑列成一张表:

阶段症状根因解法
架构决策微信无法读取个人消息官方无接口,替代方案均违反协议微信降级为「单向通知副本」,传输走自建 HTTP
后台登录Turnstile 验证永远完不成移动出口 BGP 绕道美国(colo=SJC),风控强制升级挑战开代理换香港节点(colo=HKG)
服务端501 Unsupported method ('{"content":"bad"}POST')keep-alive 下 token 校验失败未消费请求体,残留串包请求体统一在读路由之前读完
真机转发面板毫无反应,日志零请求匹配模式应为「正则」却选了「包含」改「正则匹配」
真机转发同上「启用该条转发规则」开关未打开打开开关
真机转发同上「启用自定义模板」误开,覆盖了消息体关闭该开关,关键词移到「匹配的值」
真机转发
(最终根因)
手工测试短信能通过,真实验证码一条都不到MIUI 把短信权限拆成「普通短信」与「通知类短信」两级,后者默认拒绝且 App 无法主动申请去系统设置里手动勾选「通知类短信」

八、写在最后:几条沉淀#

做完这件事,有几句话我记在了自己的运维笔记里。

需求的第一问不是「怎么做」,而是「哪条路不该走」。 技术可行性不等于方案可用性。一个方案如果要把我最重要的账号拿去冒险,那它在被想出来的那一刻就该被否掉。

别在没报错的地方瞎试。 没有报错不代表没有问题,它只代表你没给自己留下能看见问题的东西。这时候该做的不是改代码,是先想办法造出一个证据点。

「我测过了」和「它真的没问题」之间隔着一整层。 这个教训这次出现了两次:本机 curl 全绿而隧道流量返回 501,是测试环境不对;普通手机号测试通过而 106 服务号的验证码一份都收不到,是测试数据不对。测试环境与测试数据的保真度,共同决定了测试结论的价值——缺任何一个,「通过」都只是运气。

厂商定制系统不是「安卓」,是「安卓 + 一堆自己的规则」。 MIUI 把短信权限拆成两级、华为给了个开关、OPPO 又改了菜单位置——同一个功能,每家做法都不一样。遇到「官方文档没提、但就是不行」的现象,优先怀疑厂商层,而不是怀疑自己的代码。

排除是有价值的动作,不是浪费时间。 五条被推翻的假设让我在第 15 分钟就找到了方向。如果当时是随口猜「可能是浏览器问题」然后去重装浏览器,那一晚上就没了。

最后,让每一条日志都能回答「是谁在说话」。 加一个来源标记只花了 5 行代码,却把未来的排障时间从半小时压缩到 5 秒。可观测性上的投入,收益永远比想象中高。


现在这套东西已经常驻在那台笔记本上了:开机自启,隧道常连,验证码从手机发出去到出现在电脑面板上,中间大概一秒。面板我不常看——因为不需要看,需要的时候它就在那儿。

CAUTION

本站分享的内容均为个人实战经验记录。文中涉及的转发令牌、服务地址等敏感凭据均已脱敏处理。 请特别注意:这类把本机服务暴露到公网的方案,务必加上访问令牌,并且不要在公开渠道泄露你自己的同类凭据。

分享

如果这篇文章对你有帮助,欢迎分享给更多人!

手机验证码自动送到电脑:一次横跨五层链路的排查实录
https://du-19.top/posts/sms-code-bridge/
作者
坚果杜
发布于
2026-09-24
许可协议
CC BY-NC-SA 4.0

部分信息可能已经过时

相关文章 智能推荐
1
把没有公网 IP 的笔记本变成云服务器:ShunCode Bridge + Cloudflare Named Tunnel 实战全记录
教程 从安装 cloudflared 到隧道全链路打通的完整实录:ShunCode Bridge 的 Named Tunnel 配置、www 301 重定向、根域冲突决策、502 排障三图标定位法,以及最终的 MCP 远程连接。每一步都有截图和踩坑记录。
2
一个「时灵时不灵」的扩展坞:当事件日志全部静默时,怎么把故障钉死在一个物理端口上
教程 用了三年的 USB 扩展坞开始间歇性掉线,插上能用、过一会儿掉、唤醒后不认、拔插又好了。查事件日志是空的,查驱动是好的,查设备管理器只有一个「未知 USB 设备」。这篇文章记录的是:在没有任何日志线索的情况下,如何用 PnP 设备树里的时间戳、实例标识后缀、以及待机窗口交叉比对,把「玄学故障」一步步收敛到「某个物理端口上的链路训练失败」,并最终判清责任边界。文中的第一个假设由 AI 助手给出,随后被实测推翻——这段失败路径我完整保留了下来,因为它本身就是结论的一部分。
3
运维工程师面试宝典(二):Kubernetes 排障与面试表达
教程 系列第二篇。覆盖 Service 与 Endpoint 的关系、CrashLoopBackOff 排查、Deployment 发布失败定位、为什么不直接改 Pod(声明式管理)、Pod Pending 与 Events 解读、Taint 与 Toleration 的设计思想;后半部分讲面试表达:线上面试使用 AI 辅助的风险、专业术语纠正表、通用排查框架,以及为什么不要硬装会。
4
运维工程师面试宝典(一):Linux 排障与监控选型
教程 系列第一篇。讲面试前的岗位匹配判断、自我介绍与薪资话术,以及 Linux 排障 9 个高频场景:服务器变慢、磁盘 IO 高、Java 大量写盘、MySQL 慢查询、服务凌晨定时停止、磁盘告警脚本、ping 通但业务不通、端口没监听、127.0.0.1 绑定问题,最后对比 Zabbix 与 Prometheus。每题给出面试官问法、踩坑点与标准回答。
5
运维工程师面试宝典(三):Ceph 存储、灾备与数据恢复
教程 系列第三篇。讲 Ceph 核心组件与 OSD 通信原理、MON 多数派 quorum 为什么必须 3 个、CRUSH 与 PG 的数据分布、Ceph 副本不等于备份、Ceph 与灾备体系的区别;以及灾备岗的开场问答、备份恢复原则、备份损坏处理、备份失败排查、RPO/RTO,附一页纸命令速查。

目录