我在华为云跑Playwright的三次返工

举报
yd_272744321 发表于 2026/11/03 15:41:00 2026/11/03
【摘要】 我们把一个定时截图校验任务迁到华为云 ECS 后,Playwright 连续踩了三次坑:系统依赖缺失、/dev/shm 太小导致浏览器崩溃、中文字体缺失引发截图误判。我把报错、命令、镜像改动、并发参数和实际费用都记下来了。

事情起因和三次返工

我这边内部巡检一直是固定节奏,crontab 写死 */10 * * * *,每轮要开 6 个供应商页面截图,再把 PNG 扔给 OCR 比对合同号、金额、状态 3 个字段。旧环境是办公室 N5105 迷你主机,16GB 内存,Ubuntu 22.04,平时看着稳定,9 月 12 日 21:43 断电后漏了 3 轮任务,我手工补跑加对账花了 2 小时 34 分。那次之后我把任务迁到华为云 ECS,北京四区 cn-north-4,规格 s6.large.2,2 vCPU / 4GiB,系统盘 40GB ESSD,按需计费,镜像还是 Ubuntu 22.04.4 LTS,Docker 24.0.7,Node.js 20.11.1,Playwright 1.45.0。

这个方案我一开始是拒绝的。

预算卡得很死,每月 300 元封顶,4GB 内存跑 Chromium 我心里发毛,CES 的短信阈值我最初设成失败率 8% 才报,怕夜里被告警打爆手机。

第一轮返工是浏览器根本起不来。我最早用 node:20-bookworm-slim,构建命令 docker build --no-cache -t shot-worker:2026-10-14 .,第一次 2 分 11 秒,第二次 2 分 19 秒。容器启动 4 秒就退出,日志第一屏是:

browserType.launch: Executable doesn't exist at /ms-playwright/chromium-1124/chrome-linux/chrome
error while loading shared libraries: libatk-1.0.so.0: cannot open shared object file: No such file or directory

我那时判断太乐观,以为补一个包就完事,结果进入连环报错。先加 libatk1.0-0,下一次变 error while loading shared libraries: libnss3.so;再加 libnss3,又变成 libxkbcommon.so.0;后面还追到了 libdrm.so.2。我连续打了 5 个镜像,单次构建从 2 分钟拖到 6 分钟上下,最慢 6 分 34 秒。现在回看这里其实有更好的做法,当时我应该直接跑一遍 ldd /ms-playwright/chromium-1124/chrome-linux/chrome | grep not\ found,我却是靠日志一条条补包,纯体力活。

收尾时我把依赖一次钉死,还把浏览器路径固定,Dockerfile 里保留这段后才稳定:FROM node:20-bookworm-slim;ENV PLAYWRIGHT_BROWSERS_PATH=/ms-playwright;RUN apt-get update && apt-get install -y --no-install-recommends ca-certificates wget gnupg libnss3 libatk1.0-0 libatk-bridge2.0-0 libcups2 libdrm2 libxkbcommon0 libxcomposite1 libxdamage1 libxfixes3 libxrandr2 libgbm1 libasound2 libxshmfence1 fonts-liberation && rm -rf /var/lib/apt/lists/*;RUN npx playwright@1.45.0 install chromium。镜像从 246MB 涨到 892MB,我当时很抗拒,但至少能跑。

这里还有一次失败尝试。我试过 mcr.microsoft.com/playwright:v1.45.0-jammy 省依赖,镜像直接 1.83GB,华为云私仓冷拉取平均 98 秒,最慢一轮 121 秒。我那版部署方式是每轮 docker run --rm 拉起一次,10 分钟间隔会和上一轮重叠,日志连续出现 Job skipped: previous run still active,上线 40 分钟就回滚。

第二轮返工更烦,任务能跑但每小时会挂几次,应用日志像网络抖动:

page.goto: Timeout 30000ms exceeded.
Error: browserType.launch: Target page, context or browser has been closed

我先改了超时,把 page.goto(url,{ waitUntil:'domcontentloaded', timeout:30000 }) 提到 90000,失败率只从 18.7% 降到 16.9%。我又试了一次错误方向,把 waitUntil 改成 networkidle,单轮耗时反而从 74 秒涨到 109 秒,失败率还回弹到 17.4%,这条改动当天就撤回。

后面盯 docker stats 才看明白是 /dev/shm 被打满,默认 64MB,3 并发时 Chromium 直接撞墙。dmesg -T 里这两条很关键:

[ERROR:platform_shared_memory_region_posix.cc(268)] Failed to reserve 16728064 bytes for shared memory.: No space left on device (28)
Memory cgroup out of memory: Killed process 23177 (chrome) total-vm:1453308kB

我把运行参数改成:docker run -d --name shot-worker --restart=always --shm-size=1g --memory=3g --cpus=1.5 -e CONCURRENCY=2 -e TZ=Asia/Shanghai registry.mycorp/shot-worker:2026-10-19。并发从 3 降到 2,容器内存上限写死 3GB,CPU 限 1.5 核,避免把整机拖死。Playwright 启动参数也固定了,args 增加 --disable-dev-shm-usage、--no-sandbox、--disable-gpu,外加 chromiumSandbox:false。这组参数上线 24 小时后,失败率从 18.7% 到 2.9%,单轮 74 秒降到 41 秒,CPU 峰值 1.3 核,内存峰值 2.6GB,夜里告警 11 条降到 2 条。

这一步我返工得很不情愿。

第三轮返工是字体问题。页面看起来正常,截图也能出,OCR 命中率却从 96% 掉到 81%,图像比对阈值从 0.08 飙到 0.31。Playwright 没报错,是我的比对服务在报 text_region_similarity below threshold,并且字段日志里出现过 expected=付款状态 actual=口口口口。我先只装 fonts-wqy-zenhei,命中率回到 88%,还不够;再补 fonts-noto-cjk locales tzdata,并把 locale 从 C.UTF-8 改到 zh_CN.UTF-8 才稳定,命中率回到 95.6% 到 96.2%。我保留的命令是:apt-get install -y --no-install-recommends fonts-wqy-zenhei fonts-noto-cjk locales tzdata、sed -i 's/# zh_CN.UTF-8 UTF-8/zh_CN.UTF-8 UTF-8/' /etc/locale.gen、locale-gen、fc-cache -fv,最后用 fc-list :lang=zh | head -n 5 验证字体真的进去了。

我还加了个土办法保命,if (round % 50 === 0) await browser.close() 后重建 context,这一步每 50 轮多花 1.7 秒,但 10 月 19 日凌晨 2:17 连续 6 次 goto 超时时,它确实把进程从坏状态里拉回来了。

线上参数和还在试的点

现在线上是单容器实例,并发 2,browser 复用 50 轮后 recycle。CES 我只盯 3 个指标:进程存活、5 分钟窗口失败率、单轮耗时 P95。短信阈值设失败率 > 5%,低于 5% 只发企业微信。最近 12 天总任务 10224,失败 137,失败率 1.34%;P95 耗时 49 秒,P99 72 秒。账单我每天都抄到表里,ECS 46.2 元,云硬盘 5.8 元,公网出流量 3.1 元,合计 55.1 元,离 300 元预算还有余量。

还没收口的点有两个。目标站点偶发验证码会把截图变成挑战页,当前只能靠模板匹配识别后重试,重试 3 次仍会漏;另一个是 ARM 规格更便宜,我在 aarch64 机器上用同版镜像跑官方 Chromium,偶发 Illegal instruction (core dumped),5 天里复现 7 次,内核是 5.15.0-1031-kunpeng。下周我准备把有验证码的站点拆到 x86 独立 worker,再补一轮 Firefox 兜底,看看能不能把失败率压到 1% 以内。

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

评论(0)

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

全部回复

上滑加载中

设置昵称

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

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

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