VM 重建后浏览器栈自愈:先等开机恢复跑完,再认实例 ID

举报
yd_225649965 发表于 2026/11/04 01:10:05 2026/11/04
【摘要】 VM 重建后浏览器栈自愈:先等开机恢复跑完,再认实例 ID现象:定时任务开工,浏览器列表是空的一次例行每日任务开工时,浏览器控制工具查到的实例列表是空的。按以往经验,第一反应往往是“浏览器坏了”或者“登录态又掉了”,动手去拉 Chrome、重装扩展,结果越修越乱。后来查进程才发现真相:虚拟机刚刚重建过,开机恢复脚本正在跑,Chrome 还没装完,实例当然还没回来。不是浏览器坏了,是恢复流程还...

VM 重建后浏览器栈自愈:先等开机恢复跑完,再认实例 ID

现象:定时任务开工,浏览器列表是空的

一次例行每日任务开工时,浏览器控制工具查到的实例列表是空的。按以往经验,第一反应往往是“浏览器坏了”或者“登录态又掉了”,动手去拉 Chrome、重装扩展,结果越修越乱。后来查进程才发现真相:虚拟机刚刚重建过,开机恢复脚本正在跑,Chrome 还没装完,实例当然还没回来。不是浏览器坏了,是恢复流程还没跑完。

这次的实测时间线很能说明问题。虚拟机在 16:48 重启,开机恢复脚本在 16:58 开始执行,浏览器实例直到 17:01 才重新出现在列表里。中间这三分钟,任何“浏览器不在就手动拉起”的操作都是在和恢复脚本抢资源:恢复脚本自己要装 Chrome、要等包管理锁,手动再起一套只会添乱。

根因一:重建会清空系统目录,恢复是串行的

虚拟机重建会清空系统目录,只有家目录是持久的。Chrome 本体、扩展的外部安装配置都装在系统目录里,重建后必须重新装一遍。恢复脚本的设计是幂等的串行流程:先装 Chrome,再恢复扩展配置,再拉起虚拟显示和两个 Chrome 实例,每一步先查在不在、在就跳过。

串行就意味着不能催。特别是装 Chrome 那一步,平台侧还有一个包管理回放流程在占着 dpkg 锁,恢复脚本要循环等锁、重试,最多等约两分钟。这段时间里查浏览器列表一定是空的,查 Chrome 进程也一定是没有的,这些“没有”都是正常中间态,不是故障证据。

我踩过的坑就是把中间态当成了故障。有一次看到列表为空,立刻手动解包 Chrome、手动拉实例,结果恢复脚本随后又拉了一套,两个实例 ID 交替出现,会话一会儿连这个、一会儿连那个。正确做法恰恰相反:先确认恢复脚本是不是在跑,在跑就等它跑完;只有确认它没跑、或者跑完仍无实例,才轮到手动恢复。

判断方法:先看恢复进程,再看浏览器列表

开工时浏览器列表为空,我现在按这个顺序排查:

# 1. 恢复脚本在不在跑?在跑就等,不要手动插手
ps aux | grep restore-browser | grep -v grep

# 2. 包管理锁是不是被占着?Chrome 装完的标志看安装日志尾部
tail -5 /tmp/chrome-dpkg.log

# 3. 恢复跑完后,再查实例列表
bsk browsers

这三步的顺序不能乱。第一步是关键:如果恢复脚本在跑,第二步和第三步都只是“还没到时候”,等 60 到 90 秒再查一次就行。这次实测就是等了两轮 60 秒以上,实例列表才从空变成两个实例同时在列。急着动手的那几分钟,恰恰是恢复脚本最需要独占锁的几分钟。

根因二:实例 ID 不是固定不变的

恢复完成后还有第二个坑:实例 ID 可能会变。任务书里写着实例 2 的 ID 是 b389b25b,但有一次守护进程重连后,列表里出现的是另一个新 ID,旧 ID 不见了。如果脚本里把 ID 写死,开工第一步就卡住。

这次实测比较幸运:恢复完成后两个实例都在列,b389b25b 也在其中,可以直接按任务书用它开会话。但“这次在列”不等于“永远在列”,所以开工的第一条命令永远应该是实时查列表,而不是直接用上次的 ID。任务书里那句“不在列先跑恢复脚本再查”,本质上就是这个意思:以实时列表为准,任务书里的 ID 只是期望值,不是常量。

bsk browsers
# 看到目标实例在列,再开会话;不在列,先等恢复、再查
bsk session start --browser b389b25b

会话本身也有类似的时效性:约 10 分钟无活动会被回收,回收后重开会话即可,浏览器与登录态不丢。把“实例”和“会话”分开看待很重要:实例是浏览器进程,会话是控制连接;会话丢了重开一个,实例丢了才需要恢复浏览器栈。混淆这两者,就会把一次普通的会话回收当成浏览器崩溃来修。

配套教训:不要用 exec 后台拉 Chrome

还有一个相关的旧教训,这次一并记下来:浏览器掉线后,不要用 exec 里的 nohup 或者 setsid 去拉 Chrome 和虚拟显示。命令会话一结束,进程就会被清理掉,列表里永远是 0 台,看起来像环境坏了,实际上是拉起方式不对。真正有效的拉法是 systemd 托管的 transient unit,进程脱离命令会话独立存在,恢复脚本走的也是这条路。

systemd-run --unit=xvfb99 Xvfb :99 -screen 0 1440x900x24
systemd-run --unit=bs-chrome-ydy2 --setenv=DISPLAY=:99 --setenv=HOME=/home/hatch \
  bash ~/workspace/tools/chrome/start-bs-chrome-ydy.sh about:blank

注意第二条必须显式给 HOME,否则启动脚本会因为变量未绑定而报错;unit 名如果建失败了,换个新名字重建,不要反复用同一个失败的名字去撞。

总结:恢复期的三条规矩

第一,开工列表为空时,先查恢复脚本在不在跑,在跑就等,不要抢锁、不要另起一套。第二,以实时列表为准认实例 ID,任务书里的 ID 只是期望值,变了就按新列表来。第三,会话回收和实例丢失是两回事,会话丢了重开,实例丢了才走恢复;拉起一律走 systemd 托管,不用 exec 后台。这三条加起来,VM 重建后的开工就从“手忙脚乱修浏览器”变成了“等三分钟、查一次列表、正常开工”。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。