配置项与运维自省
本文列出当前工程的全部运行时配置项与只读查询端点,用于部署、排障和「现在到底是哪个配置在生效」这类问题。
一、配置从哪里读
配置项统一通过 EnvUtils.get 读取,优先级从高到低:
EnvUtils通道(系统属性、环境变量、app.properties等,具体来源以框架的加载顺序为准);- 服务自带的
browser.properties; - 同一份
browser.properties里的全大写下划线写法,例如BROWSER_CHROME_PATH等价于browser.chrome.path,方便用环境变量覆盖。
代码里不要直接用 System.getenv 读环境变量:那样会绕过上面这套优先级,出现「配了却不生效」。
命令行覆盖示例:
java -Dbrowser.engine=firefox -jar <发行包文件名>.jar
java -Dserver.port=10050 -jar <发行包文件名>.jar
二、配置项清单
浏览器与 profile
| 配置项 | 默认 | 说明 |
|---|---|---|
browser.type | auto | start 不传 browser 时的默认浏览器类型 |
browser.engine | chromium | 引擎开关:chromium / firefox。是 browser.type 的子集,表达不了 Chrome 与 Edge 的区别 |
browser.chrome.enabled | true | 是否使用本机 Google Chrome;false 时完全退回内置 Chromium |
browser.chrome.path | 自动探测 | 本机 Chrome 可执行文件;留空时按平台惯例探测(Windows 还会查注册表 App Paths\chrome.exe) |
browser.chrome.userDataDir | 自动探测 | 用户数据目录(User Data),只有 useUserProfile=true 时才用到 |
browser.chrome.profileDirectory | Default | 用用户数据目录里的哪个子 profile;填 auto 读「上次使用的 profile」;填空串表示不传该参数 |
browser.chrome.useUserProfile | false | 是否直接用用户自己那份 Chrome profile(需要放开默认目录的远程调试,见 09) |
browser.chrome.profileFallback | true | 用户 profile 用不上时是否退回托管 profile;false 时直接报错 |
browser.chrome.extraArgs | 空 | 追加到 Chrome 命令行的额外参数,逗号分隔 |
browser.profileDir | 按端口派生 | 托管 profile 目录;显式配置优先,不受按端口派生影响 |
browser.profileDir.perPort | true | 没显式配 browser.profileDir 时,目录名按服务端口派生(shared-<端口>) |
browser.chromium.sandbox | 按平台 | true 始终开启 / false 始终关闭 / 不配按平台默认(非 Linux 开,Linux 关) |
browser.edge.enabled | true | 是否允许使用本机 Edge |
browser.edge.path | 自动探测 | Edge 可执行文件 |
browser.edge.profileDir | ~/.config/browseruse/profiles/edge | Edge 专用托管 profile(与 Chrome 那份刻意分开) |
browser.edge.extraArgs | 空 | 追加到 Edge 命令行的额外参数 |
browser.firefox.path | 空(推荐留空) | 显式指定 Firefox 可执行文件;留空交给 Playwright 解析它自带的那份 |
browser.firefox.extraArgs | 空 | 追加到 Firefox 命令行的额外参数 |
窗口与视口
| 配置项 | 默认 | 说明 |
|---|---|---|
browser.viewport | window | window(跟随真实窗口)/ fixed(按屏幕算出的固定尺寸)/ 宽x高(如 1440x900)。见 10 |
启动、动作与留档
| 配置项 | 默认 | 说明 |
|---|---|---|
browser.launch.timeoutMs | 60000 | 启动超时。Playwright 自身给的默认值偏大,启动卡住时不会报错、只会一直等到超时,所以这里收到 60 秒 |
browser.action.timeoutMs | 5000 | 按索引操作的超时。界面较慢的 SPA 上可调大,否则本来能成的点击会被判死 |
browser.action.jsFallback | true | auto 普通失败且未发现遮挡时,是否允许最后尝试 JS 派发;对象释放异常不补点,见点击排障 |
browser.action.mouseFallback | true | auto 普通失败且未发现遮挡时,是否尝试真实鼠标坐标点击;对象释放异常不补点 |
browser.capture.enabled | true | 页面变化时是否自动留档截图。关掉后动作照常执行,只是不再落图(显式调 screenshot 不受影响) |
调用追踪(见 12)
| 配置项 | 默认 | 说明 |
|---|---|---|
browser.trace.enabled | true | 是否把每次调用的请求与响应落盘 |
browser.trace.dir | <启动目录>/logs/trace | 落盘根目录,按自然日分子目录 |
browser.trace.maxRecordChars | 8000000 | 单次调用完整报文的字符上限,超了截断并打标记 |
browser.trace.redact.enabled | true | 落盘前脱敏(手机号、身份证号、统一社会信用代码、邮箱、长数字) |
browser.trace.redact | 空 | 追加的自定义脱敏正则,逗号分隔(例如把公司名、商标名也掩掉) |
browser.trace.redact.mask | *** | 脱敏后的替换文本 |
文件暂存(见 12)
| 配置项 | 默认 | 说明 |
|---|---|---|
browser.upload.enabled | true | 是否开放 POST /playwright/upload。关掉之后上传文件只能靠服务端本来就有的路径 |
browser.upload.dir | <启动目录>/upload | 暂存目录 |
browser.upload.maxBytes | 67108864 | 单文件上限(字节),0 表示不限 |
browser.upload.overwrite | true | 同名文件是覆盖,还是自动改名(a.jpg → a-1.jpg) |
配方与脚本
| 配置项 | 默认 | 说明 |
|---|---|---|
browser.recipes.dir | <启动目录>/recipes | 站点配方目录,见 14 |
browser.js.dir | <启动目录>/scripts/js | execute_js 的 bodyFile 只能从这个目录里读 |
以上共 36 个运行时可配项。另有 chromium.revision 属打包期配置(发行版内嵌浏览器的构建编号),运行时不改。
三、只读查询端点
除唯一的控制端点外,服务还开了三个只读端点,方便脚本与浏览器直接打开:
| 端点 | 用途 |
|---|---|
GET /playwright/health | 健康检查,返回服务名。用于启动脚本的等待与存活探测 |
GET /playwright/methods | 全部方法名清单(与 list_methods 同一份数据),不必靠猜 |
GET /playwright/tasks | 当前活着的任务与共享浏览器状态;排查「孤儿浏览器占着 profile」「任务没关干净」先看它 |
GET /playwright/config | 服务端生效的配置:引擎、实际浏览器类型、解析后的 profile 目录、上传与追踪目录、各超时与降级开关、命令数 |
另外两个非 /playwright/ 前缀的路由:
| 路由 | 说明 |
|---|---|
POST /playwright/command | 唯一的浏览器控制端点,见 08 |
/playwright/upload | 文件暂存,支持 GET 列出 / POST 上传 / DELETE 删除,见 12 |
/data/** | 截图与结构化文本的静态文件服务,data/<id>/<序号>.png 与 .txt 可以直接 GET |
get_config 的返回结构
{"data":{
"engine":"chromium",
"configuredType":"auto",
"typeChoices":["auto","chromium","chrome","edge","firefox"],
"profileDir":{"configured":null,"perPort":true,"resolved":"<托管 profile 绝对路径>","note":"..."},
"upload":{"dir":"<暂存目录>","enabled":true,"maxBytes":"67108864"},
"jsDir":"<execute_js 脚本目录>",
"trace":{"dir":"<追踪目录>","enabled":true,"redact":true},
"launchTimeoutMs":60000,
"action":{"timeoutMs":5000,"jsFallback":true,"mouseFallback":true},
"workDir":"<服务工作目录>",
"tasks":0,
"commands":["start","close","shutdown","..."]
}}
响应里还有 java 与 playwright 两个运行时与依赖版本字段,部署时可用于核对环境,本文不列举具体版本。
profileDir.configured 是显式配置值(没配就是空),resolved 才是这次真正用的目录 —— 排查「配置看着对、登录态却没了」时看 resolved。
四、维护类方法
| 方法 | 用途 |
|---|---|
list_tasks | 当前任务与共享浏览器状态(GET /playwright/tasks 同一份数据) |
cleanup | 清理 data/ 等运行期产物。默认只预演,要真删必须显式传 dryRun:false |
shutdown | 关掉全部任务与共享浏览器,服务进程不退出 —— 停服务前先调它,可以避免留下孤儿浏览器 |
五、启动与停止
# 开发态
cd playwright-server
mvn spring-boot:run
# 发行版
java -jar <发行包文件名>.jar
# Windows 上后台启动 / 干净停止(推荐)
scripts\run\start-server.cmd -Port 10049 -Engine chromium
scripts\run\stop-server.cmd -Port 10049
启动脚本会等健康检查通过,并把实际生效的引擎与 profile 目录打出来。停止脚本先 shutdown(关任务与共享浏览器)再按端口结束整棵进程树。
停服务前先关任务。 浏览器是独立进程:强杀服务不会关掉它启动的浏览器,残留的浏览器会一直占着 profile 目录,下一次 start 可能卡到启动超时。已经留下了孤儿时,先结束残留的浏览器进程再重启服务;服务侧也有兜底(清理 profile 里的残留锁标记,并在首次启动失败后重建驱动重试一次)。
另外两点:
- 重启服务是有代价的:关掉最后一个任务时浏览器就退出了,session cookie 型的登录态会随之失效,人工得重新登录一次;持久 cookie 不受影响。所以「顺手重启一下」之前先想清楚有没有正在进行的登录环节。
- 别直接关掉那个后台黑窗口:窗口寿命等于进程寿命,关窗口就是杀进程。要停服务请用停止脚本。
六、安全提示
- 服务没有鉴权。
execute_js能执行任意脚本,/data/**能读到所有截图与页面文本,POST /playwright/upload能往服务端磁盘写文件(只能写进暂存目录、文件名会被清洗,但文件内容不限;browser.upload.enabled=false可关掉这个接口)。 - 默认只监听本机。对外暴露前必须自己加访问控制,并且不要把
/data/**直接放到公网。 data/、logs/trace/与upload/里的文件都不会自动清理,长期运行要自己定期清理(或定期调cleanup)。- 追踪日志默认脱敏,但这是尽力而为:按模式认不出来的个人信息(姓名、门牌号)不会被掩掉,交付或共享日志前自己过一眼。详见 12。
