驾驶舱'挂了'排查实录:服务没死,bat 先死了——一键启动快捷方式诞生记

AI 工作日志 作者头像野生码农 阅读 10 min
返回板块 GEO 源码全文 ✓
驾驶舱'挂了'排查实录:服务没死,bat 先死了——一键启动快捷方式诞生记

背景与目标

本人报障:"我们的驾驶舱后台挂了。重新启动一下驾驶舱项目的后台。并在我的桌面创建一个快捷方式。快捷方式的启动可以一键启动,包括 MySQL 及后台相关所有服务。"

一条指令三件事:处置(重启)+ 根治(一键启动)+ 落点(桌面快捷方式)。经营驾驶舱 = BuildAdmin(ThinkPHP8 + Vue3),本机 php think run -p 8096,MySQL 依赖 phpStudy 的 MySQL8.0.12(3306,库 jiashicang)。

过程回顾

诊断:端口活着,服务也活着

按快速定位四件套起手,先查端口:

  • 3306 LISTENING(PID 54192,mysqld.exe,10-06 22:50 启动);
  • 8096 LISTENING(PID 36392,php.exe,10-06 20:43 启动,命令行 php -S 0.0.0.0:8096 -t ...\code\public router.php);
  • curl http://127.0.0.1:8096/ → 302,耗时 0.004 秒;跟随跳转 → 登录页 200,13965 字节,Vue SPA 资源引用齐全。

结论:"挂了"在服务端未复现——进程没死、响应毫秒级。大概率是浏览器侧一过性卡死或此前瞬间假死。但指令是重启,照办:服务端正常不等于不该重启,重启也是排除"假死进程"的最快路径。

另一个关键侦察结果:phpStudySrv 服务状态 Stopped/Disabled——MySQL 不是系统服务,是 phpStudy GUI 拉起的控制台进程。这直接决定了一键启动脚本不能走 net start,得直接拉 mysqld.exe --defaults-file=...。

重启:一把过

taskkill /PID 36392 /F → Start-Process php 'think run -p 8096' -WindowStyle Hidden → curl 302 复验,收工。

关键踩坑

坑一:UTF-8 的 .bat 在 GBK cmd 下碎成渣(主坑)

第一版一键启动写成 一键启动.bat,UTF-8 编码 + 开头 chcp 65001。实跑直接崩:

'ho' 不是内部或外部命令……      ← echo 被咬掉两个字符
'evel' 不是内部或外部命令……    ← errorlevel 被咬
'ano' 不是内部或外部命令……     ← netstat 被咬

根因:cmd 解析 .bat 按系统 ANSI 代码页(本机 936/GBK)逐字节读,chcp 65001 改的是控制台输出代码页,救不了对脚本文件本身的解码;UTF-8 中文三字节序列按 GBK 双字节错位切分,把后续 ASCII 命令字节都吞了。

解决:弃 bat 改 PowerShell。.ps1 带 BOM 写入,PS 5.1 见 BOM 才按 UTF-8 读(无 BOM 按 ANSI,同样翻车)。脚本逻辑重写为 Get-NetTCPConnection 探端口 + 30 秒等待循环,一次通过。

注:dev 章程易错命令表里早有"本机底色 936(GBK)"的明文,且 PowerShell 读文件那条翻车记录就在表里——这次是同根因的新变体(cmd 解析 bat),属于手册有规则、动手前没查。

坑二:bash 内嵌 PowerShell,$_ 被吞(连踩两次)

Git Bash 里 powershell -Command "... { $_.Name ... }" 用双引号,$_ 被 bash 当变量展开成空,PowerShell 收到 /d/code/dev.Name 这种残片,报一堆 ObjectNotFound。同一个坑在查服务、验快捷方式两处各踩一次,第二次才改成写 .ps1 脚本文件再 -File 执行——第一次报错时就该切换。

最终方案

  • 项目\经营驾驶舱\一键启动.ps1:幂等——先探 3306/8096,在跑则跳过;未跑则拉起 mysqld(带 defaults-file)或 php think run -p 8096(Hidden 窗口);各自 30 秒超时,失败回车退出;全部就绪自动开浏览器到登录页;
  • 桌面 经营驾驶舱.lnk → powershell.exe -NoProfile -ExecutionPolicy Bypass -File 一键启动.ps1,WScript.Shell COM 创建,工作目录、图标、描述齐全;
  • 项目级 AGENTS.md 部署节登记一行脚本口径。

验证(全实跑,无静态目测)

  • 分支一:杀掉 8096 的 php 进程后跑脚本 → 正确识别 MySQL 在跑跳过、拉起后台、curl 302/200 复验;
  • 分支二:双服务在跑时跑脚本 → 两项均"已在运行,跳过";
  • 快捷方式读回校验:名称/目标/工作目录/图标四字段与预期一致。

做得好的地方

  • 先取证后动手:"挂了"没有直接重启了事,先 netstat + curl 双侧实测,得出"服务端未复现"的准确结论再处置——重启照做,但报告里说清了事实,没配合演出"已修复";
  • 侦察改变了设计:发现 MySQL 是 phpStudy 控制台进程而非服务,脚本才走直拉 mysqld 路线;若想当然 net start mysql,快捷方式交付即翻车;
  • 产物闭环:脚本、快捷方式、AGENTS.md 登记三件套一次齐,下次任何岗接手都查得到口径。

复盘与改进

  • GBK 类翻车已三次同根(PowerShell 读文件、子进程中文、本次 bat 解析),易错命令表收了两条没收"cmd 解析 UTF-8 bat"这条变体——本次故障台账补记一行,规则沉淀为:Windows 本机自动化脚本一律 .ps1(带 BOM),禁新建 .bat;
  • bash 内嵌 PowerShell 单行命令,含 $_/$变量 的一律写临时 .ps1 文件执行,不内联;
  • 报障类指令("挂了")缺现象描述时,服务端未复现也要把实测证据摆进报告,让本人判断是浏览器侧还是网络侧。

成长评估

五维评分(10 分制,对事)

维度 分 证据
指令与提示词质量 8.5 一条指令给全问题定性+处置动作+根治产物+落点+覆盖范围,全程零澄清零纠偏跑完;扣分点:"挂了"无现象(白屏/报错/转圈?),服务端实测未复现,若带一句现象可省一轮方向判断
判断与结论 8 "重启"处置方向正确(假死进程 curl 测不出全部病灶,重启是最快排除法);"挂没挂"的定性与服务端实测有出入,但浏览器侧体验无法从服务端证伪,不算误判
思维方式 9 救火与防火打包:同一指令里既要"重启"(处置)又要"一键启动快捷方式"(根治复发成本),典型系统工程思维——不只是修好,而是让下次 3 秒自助修好
最终结果与产出 9 双分支实跑全绿,产物三件套(脚本/快捷方式/AGENTS.md 登记)闭环,无口头完成
AI 协作能力 8.5 auto 模式授权充分,全程零打断;边界词明确("我的桌面"、"包括 MySQL 及后台相关所有服务"),AI 无需猜测交付形态

指令实证

原话:"重新启动一下驾驶舱项目的后台。并在我的桌面创建一个快捷方式。快捷方式的启动可以一键启动,包括 MySQL 及后台相关所有服务。"

效果:处置+根治+落点+范围四要素一句话给全,AI 零澄清直跑全链,从诊断到桌面快捷方式交付一轮完成,无返工(中途 bat→ps1 是 AI 自己的技术选型翻车,非指令问题)。证据:项目/经营驾驶舱/一键启动.ps1、C:\Users\three\Desktop\经营驾驶舱.lnk、项目/经营驾驶舱/AGENTS.md 部署节新增行。

AI 自评失分点

  1. 手册有规则没执行前置查询:dev 章程易错命令表明文"本机底色 936(GBK)",仍先写 UTF-8 .bat 翻车一轮;动手写自动化脚本前应先把该行规则映射到"禁 bat、用 ps1+BOM"的结论;
  2. 同坑连踩两次:$_ 被 bash 吞掉第一次报错后就该切脚本文件方式,结果第二次又内联又炸,多烧一轮;
  3. 结论表述可更精确:首轮报告"应是当时假死/卡死"偏推测,应明确分层——"服务端实测无异常(curl 302/200 毫秒级),故障未复现,浏览器侧可能性大"。

素材点

  • "服务没死,bat 先死了":936 代码页机器上 UTF-8 bat 的碎片化报错现场('ho'/'evel'/'ano'),S3 技术稿好题材;
  • phpStudy 的 MySQL 是控制台进程不是服务——phpStudySrv Stopped/Disabled 这个侦察细节决定启动脚本路线;
  • 一键启动脚本幂等模板(探端口→跳过/拉起→30 秒超时→开浏览器),可复用到 GEO 博客等其他本机多服务项目;
  • "挂了"类报障的标准取证动作:netstat 端口 + curl 响应码/耗时 + 进程启动时间,三件套 30 秒出结论。
野生码农头像

关于作者 · 野生码农

把 AI 真放进生产环境的独立开发者。自研本地知识库、数字员工团队、软考备考系统、量化交易四套系统,全程公开复盘。

看他的平台账号 →
相关

继续阅读