Skip to content

配置项与运维自省 ​

本文列出当前工程的全部运行时配置项与只读查询端点,用于部署、排障和「现在到底是哪个配置在生效」这类问题。

一、配置从哪里读 ​

配置项统一通过 EnvUtils.get 读取,优先级从高到低:

  1. EnvUtils 通道(系统属性、环境变量、app.properties 等,具体来源以框架的加载顺序为准);
  2. 服务自带的 browser.properties;
  3. 同一份 browser.properties 里的全大写下划线写法,例如 BROWSER_CHROME_PATH 等价于 browser.chrome.path,方便用环境变量覆盖。

代码里不要直接用 System.getenv 读环境变量:那样会绕过上面这套优先级,出现「配了却不生效」。

命令行覆盖示例:

shell
java -Dbrowser.engine=firefox -jar <发行包文件名>.jar
java -Dserver.port=10050 -jar <发行包文件名>.jar

二、配置项清单 ​

浏览器与 profile ​

配置项默认说明
browser.typeautostart 不传 browser 时的默认浏览器类型
browser.enginechromium引擎开关:chromium / firefox。是 browser.type 的子集,表达不了 Chrome 与 Edge 的区别
browser.chrome.enabledtrue是否使用本机 Google Chrome;false 时完全退回内置 Chromium
browser.chrome.path自动探测本机 Chrome 可执行文件;留空时按平台惯例探测(Windows 还会查注册表 App Paths\chrome.exe)
browser.chrome.userDataDir自动探测用户数据目录(User Data);旧启动路径在 useUserProfile=true 时使用,也供 profile 列表发现本机 Chrome 子目录
browser.chrome.profileDirectoryDefault用用户数据目录里的哪个子 profile;填 auto 读「上次使用的 profile」;填空串表示不传该参数
browser.chrome.useUserProfilefalse是否尝试直接用用户自己的 Chrome profile;不能绕过 Chrome 默认目录的远程调试限制,推荐独立克隆,见 39
browser.chrome.profileFallbacktrue旧配置路径的用户 profile 用不上时是否退回托管 profile;false 时直接报错。请求显式选择 profile 时不允许回退
browser.chrome.extraArgs空追加到 Chrome 命令行的额外参数,逗号分隔
browser.chrome.cdpProfileDir~/.config/browseruse/profiles/shared-default本机 Chrome 走 CDP 时用的托管 profile 目录。不按端口派生,换端口不换登录态;留空时显式配的 browser.profileDir 优先于它。见 05 第三节
browser.chrome.debugPort0CDP 调试端口。0 表示让浏览器自己挑空闲端口(一定在 10000 以上);需要固定端点时填 10000 以上的值。不要填 9222,原因见 27 第八节
browser.profileDir按端口派生托管 profile 目录(内置 Chromium 与 Firefox 用);显式配置优先,不受按端口派生影响。本机 Chrome 用上面的 cdpProfileDir
browser.profiles.dir~/.config/browseruse/profiles/named命名 profile 根目录;clone_profile 写入这里,start.profile 从这里解析,见 39
browser.profileDir.perPorttrue没显式配 browser.profileDir 时,目录名按服务端口派生(shared-<端口>)。只影响内置 Chromium 与 Firefox
browser.chromium.sandbox按平台true 始终开启 / false 始终关闭 / 不配按平台默认(非 Linux 开,Linux 关)
browser.edge.enabledtrue是否允许使用本机 Edge
browser.edge.path自动探测Edge 可执行文件
browser.edge.profileDir~/.config/browseruse/profiles/edgeEdge 专用托管 profile(与 Chrome 那份刻意分开)
browser.edge.extraArgs空追加到 Edge 命令行的额外参数
browser.firefox.path空(推荐留空)显式指定 Firefox 可执行文件;留空交给 Playwright 解析它自带的那份
browser.firefox.extraArgs空追加到 Firefox 命令行的额外参数

窗口与视口 ​

配置项默认说明
browser.viewportwindowwindow(跟随真实窗口)/ fixed(按屏幕算出的固定尺寸)/ 宽x高(如 1440x900)。见 06

启动、动作与留档 ​

配置项默认说明
tio.json.skipNull框架级默认 false框架的全局开关:序列化是否跳过 null 值字段。本项目在 app.properties 里打开了它(响应不再输出每一条都带的 msg / error 空字段)。取值只认 true(忽略大小写),写错按"关"处理。见 Json 转换 与统一命令接口
browser.json.skipNulltrue项目自己的同名开关,优先级高于上面那个;启动时用它对齐框架开关(Json.installSkipNull(..)),并回报到启动日志。设 false 可单独关掉本项目的跳过行为,不动别人的设置
browser.launch.timeoutMs60000启动超时。Playwright 自身给的默认值偏大,启动卡住时不会报错、只会一直等到超时,所以这里收到 60 秒
browser.action.timeoutMs5000按索引操作的超时。界面较慢的 SPA 上可调大,否则本来能成的点击会被判死
browser.action.jsFallbacktrueauto 普通失败且未发现遮挡时,是否允许最后尝试 JS 派发;对象释放异常不补点,见点击排障
browser.action.mouseFallbacktrueauto 普通失败且未发现遮挡时,是否尝试真实鼠标坐标点击;对象释放异常不补点
browser.capture.enabledfalse页面变化时是否自动留档截图。关掉后动作照常执行,只是不再落图(显式调 screenshot 不受影响)

正文与 Markdown 提取(见 17) ​

配置项默认说明
browser.extract.maxChars20000extract_structured_data 与 extract_markdown 的默认字符上限(两条共用同一个键)。公告类页面整页动辄三四万字符,默认值一到就截断,需要读全就调大;单次调用仍可用 maxChars 覆盖

读图与 OCR(见 11) ​

配置项默认说明
browser.ocr.enginewindowsocr_image 走哪条路:windows = 系统 OCR(Windows.Media.Ocr,擅长验证码这类短文本);command = 跑下面那条外部命令
browser.ocr.command空外部 OCR 命令模板,支持 {input}(图片路径)、{output}(结果文本路径)、{language} 三个占位符。带空格或中文的路径要用双引号包住;不写 {output} 就从 stdout 读结果
browser.ocr.timeoutMs120000外部命令超时(毫秒)

配了 engine=command 但 command 为空时不会装作生效:engineId() 退回 windows,而 get_config 的 ocr.describe 会明说「已退回系统 OCR」。

调用追踪(见 09) ​

配置项默认说明
browser.trace.enabledtrue是否把每次调用的请求与响应落盘
browser.trace.dir<启动目录>/logs/trace落盘根目录,按自然日分子目录
browser.trace.maxRecordChars8000000单次调用完整报文的字符上限,超了截断并打标记
browser.trace.redact.enabledtrue落盘前脱敏(手机号、身份证号、统一社会信用代码、邮箱、长数字)
browser.trace.redact空追加的自定义脱敏正则,逗号分隔(例如把公司名、商标名也掩掉)
browser.trace.redact.mask***脱敏后的替换文本

文件暂存(见 09) ​

配置项默认说明
browser.upload.enabledtrue是否开放 POST /playwright/upload。关掉之后上传文件只能靠服务端本来就有的路径
browser.upload.dir<启动目录>/upload暂存目录
browser.upload.maxBytes67108864单文件上限(字节),0 表示不限
browser.upload.overwritetrue同名文件是覆盖,还是自动改名(a.jpg → a-1.jpg)

配方与脚本 ​

配置项默认说明
browser.recipes.dir<启动目录>/recipes站点配方目录,见 10
browser.js.dir<启动目录>/scripts/jsexecute_js 的 bodyFile 只能从这个目录里读

以上共 38 个运行时可配项。另有 chromium.revision 属打包期配置(发行版内嵌浏览器的构建编号),运行时不改。

三、只读查询端点 ​

除唯一的控制端点外,服务还开了三个只读端点,方便脚本与浏览器直接打开:

端点用途
GET /playwright/health健康检查,返回服务名。用于启动脚本的等待与存活探测
GET /playwright/methods全部方法名清单(与 list_methods 同一份数据),不必靠猜
GET /playwright/tasks当前活着的任务与共享浏览器状态;排查「孤儿浏览器占着 profile」「任务没关干净」先看它
GET /playwright/config服务端生效的配置:引擎、实际浏览器类型、解析后的 profile 目录、上传与追踪目录、各超时与降级开关、命令数

另外两个非 /playwright/ 前缀的路由:

路由说明
POST /playwright/command唯一的浏览器控制端点,见 04
/playwright/upload文件暂存,支持 GET 列出 / POST 上传 / DELETE 删除,见 09
/data/**截图与结构化文本的静态文件服务,data/<id>/<序号>.png 与 .txt 可以直接 GET

get_config 的返回结构 ​

json
{"data":{
  "engine":"chromium",
  "configuredType":"auto",
  "typeChoices":["auto","chromium","chrome","edge","firefox"],
  "profileDir":{"resolved":"<这次真正会用的 profile 绝对路径>","forType":"chrome","perPort":true,
    "configured":null,"cdpConfigured":null,"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 与 cdpConfigured 是显式配置值(没配就是空),resolved 才是这次真正用的目录,forType 说明它是按哪个浏览器类型解析出来的 —— 排查「配置看着对、登录态却没了」时看 resolved,未显式选 profile 时可与 start 回执里的 data.browser.profileDir 对照;请求中的 profile 或 userDataDir / profileDirectory 是单次选择,以启动回执为准。注意 browser.type=chrome 时 resolved 是那条 CDP 路径的目录,不是 shared-<端口>(见 05 第三节)。

四、维护类方法 ​

方法用途
list_profiles发现命名托管与本机 Chrome profile,返回 data.profiles;不启动浏览器
clone_profile将所选子 profile 离线克隆到命名根目录;参数和安全限制见 39
list_tasks当前任务与共享浏览器状态(GET /playwright/tasks 同一份数据)
cleanup清理 data/ 等运行期产物。默认只预演,要真删必须显式传 dryRun:false
shutdown关掉全部任务与共享浏览器,服务进程不退出 —— 停服务前先调它,可以避免留下孤儿浏览器

五、启动与停止 ​

shell
# 开发态
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 会失败 —— 走 CDP 那条路(本机 Chrome / Edge)时报的是「浏览器启动后立即退出(退出码 21):(Chrome 没有输出)」,原因是新进程把命令行交给已有实例后自己退出、连输出也被那个实例吃掉了(见 27 第八节);走持久化上下文时则表现为卡到启动超时。已经留下了孤儿时,先结束残留的浏览器进程再重启服务;服务侧也有兜底(清理 profile 里的残留锁标记,并在首次启动失败后重建驱动重试一次)。

另外两点:

  • 重启服务是有代价的:普通 close 保留最后一个任务的浏览器;显式关闭浏览器或重启服务可能使 session cookie 型的登录态失效,人工得重新登录一次;持久 cookie 不受影响。所以「顺手重启一下」之前先想清楚有没有正在进行的登录环节。
  • 别直接关掉那个后台黑窗口:窗口寿命等于进程寿命,关窗口就是杀进程。要停服务请用停止脚本。

六、安全提示 ​

  • 服务没有鉴权。execute_js 能执行任意脚本,/data/** 能读到所有截图与页面文本,POST /playwright/upload 能往服务端磁盘写文件(只能写进暂存目录、文件名会被清洗,但文件内容不限;browser.upload.enabled=false 可关掉这个接口)。
  • 示例通过 localhost 访问,但应用配置只明确了端口,不能据此认定服务仅绑定回环地址。部署时检查实际监听地址;对外暴露前增加访问控制,不要把 /data/** 直接放到公网。
  • data/、logs/trace/ 与 upload/ 里的文件都不会自动清理,长期运行要自己定期清理(或定期调 cleanup)。
  • 追踪日志默认脱敏,但这是尽力而为:按模式认不出来的个人信息(姓名、门牌号)不会被掩掉,交付或共享日志前自己过一眼。详见 09。