首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >从反复手动拉起服务到开机自启:跨平台进程管理器的实现过程

从反复手动拉起服务到开机自启:跨平台进程管理器的实现过程

原创
作者头像
用户11751595
发布于 2026-11-10 18:00:24
发布于 2026-11-10 18:00:24
790
举报

我有台机器常年开着,上面跑几个自建服务:一个同步脚本、一个本地 API,偶尔还有 WSL 里的东西。麻烦的不是让它们跑起来,而是每天开机之后那几分钟,挨个进目录、敲命令、确认端口没被占。试过几个现成的进程管理工具,要么只认某一个系统,要么配置文件比它要管的那几个进程加起来还长。

后来索性自己写了一个,叫 ProcHub,Wails 加 Go 加 Vue 3,Apache 2.0 开源。下面按我实际的推进顺序,把遇到的问题、当时的选择和后来的结果摊开说一遍。

先把边界划出来

动手之前得先说清楚不做什么,否则很容易滑向一个半成品 PaaS。

我定下的范围是单机、单用户、绿色可执行文件。不做容器编排,不做远程多机调度,也不做 Web 面板。这些需求都有成熟方案,而我真正常用的只是「开机把这些进程拉起来,出了问题能马上看到日志」这一小段路径。

选型时先排掉了系统自带的方案。以 systemd 为主的发行版可以直接写 unit,macOS 有 launchd,Windows 有服务控制管理器,各自都能跑。问题是三套机制不通用,我手头既有 Linux 又有 macOS 和 Windows,写三份配置去维护同一批进程,比现在的处境更麻烦。

还有一个决定:图形界面和命令行共用同一份进程状态,不让命令行再经过本地端口去问后台。少一层转发,排查时少一个怀疑对象。

选型:Wails 和 Electron 之间

Wails 的好处是前端照 Vue 写,后端是纯 Go,最后打成一个可执行文件,不额外装运行时。代价是构建链比单语言项目长:目前要求 Go 1.23、Node 18 和 Wails CLI,三者版本得互相对得上,前端依赖装错版本会先卡在编译上。

Electron 也考虑过。生态更全,但一个常驻托盘的进程管理器再背一份浏览器内核,我觉得不划算。Wails 复用系统的 WebView,Linux 上则是 WebKitGTK,省掉打包内核这一块。代价是三个系统的 WebView 版本不一致,前端要避开一部分新特性。

进程模型与重启策略

实现上没有包装系统服务管理器,而是自己维护一张进程表。每条记录存命令、参数、工作目录、重启策略和运行状态。启动走 exec,停止先发信号等它自己退,超时再强杀。这一步做完,界面上就能看到 PID、重启次数和最近一次错误,排查时不用去翻别的窗口。

重启策略给了三档:always、on_failure、never。自用的服务大多设 always,一次性脚本设 never,只有真需要兜底的设 on_failure。

ProcHub 主界面进程列表
ProcHub 主界面进程列表

自启按系统分别实现

这是跨平台工具最容易偷懒的地方。macOS 写 LaunchAgent 的 plist,放在用户的 LaunchAgents 目录;Linux 用 XDG Autostart,往 autostart 目录里放一个 desktop 文件;Windows 走注册表,在用户级的 Run 项下写一条启动命令。三套机制的名字、目录、生效时机都不一样,抽象不出一个通用接口,只能各写一份。

同一件事在三处的表现也不同。LaunchAgent 是登录时由 launchd 拉起,desktop 文件要看桌面环境的实现,注册表项则在用户登录后由系统执行。界面上只是一个开关,底下是三条互不相干的路径。

ProcHub 设置页,主题、语言与开机自启
ProcHub 设置页,主题、语言与开机自启

日志不能只留在内存里

早期版本日志只在界面上滚,窗口一关就没了,出问题基本等于没法查。后来改成落文件:每个进程按 id 在数据目录下存一份,滚动写入,保留份数可配置。stdout 和 stderr 分开捕获,实时流照样推给界面。

界面关掉之后,直接去数据目录翻最近的记录,看到的和界面里是同一份。

命令行是同一份能力的另一张脸

带子命令启动就走 CLI,不带就开窗口,用的是同一个可执行文件。

代码语言:bash
复制
# 查看当前托管的进程
prochub process list

# 启动与停止
prochub process start <name>
prochub process stop <name>

# 先看最后 100 行,再持续跟踪
prochub logs <name> --tail 100 --follow

# 读取与修改配置
prochub config get theme
prochub config set language zh-CN

# WSL 相关
prochub wsl status
prochub wsl start
prochub autostart-wsl off

# 整体状态与版本号
prochub status
prochub version

WSL 这里有两组命令。wsl 那一组管的是 WSL 本体的启停,autostart-wsl 单独控制开机要不要顺手把 WSL 拉起来。这两件事经常被混成一件,但需求不一样:有人希望开机就进环境,有人只想在需要时手动起。

命令行这层更多是给脚本用的。开机脚本、CI 里的临时验证、ssh 上去查一眼,都犯不上开窗口。

怎么验证

每改完一轮,我主要看三件事。

第一,重启策略是不是真的按配置走。用 process list 拿到 PID,手动 kill 掉 always 的进程,看它会不会自动回来;再把 on_failure 的进程正常退出,确认不该拉起的时候它确实没动。

第二,日志是不是落到了预期位置。关掉窗口,按进程 id 去数据目录找文件,看滚动和保留份数是否符合配置。

第三,自启在三个系统上是否都生效。macOS 用 launchctl list 看条目在不在,Linux 检查 autostart 目录里的 desktop 文件,Windows 重启后看注册表项对应的程序有没有起来。

三个平台的差异往往就出在这一步:界面显示已开启,实际没写进去,或者写进去了但系统没执行。

还没做和暂时不做的

没有做进程之间的依赖编排,比如 A 起来之后才起 B。目前靠重启策略加上手动顺序顶着,够用,但也只是够用。

没有做多机管理。把同一份配置同步到几台机器上的需求我遇到过,不占多数,先放着。

WSL 那组命令是后来加的,验证范围比别的功能窄,只在几个常见发行版上试过。

小结

整个过程没有特别难的技术点,主要是把一件小事拆成能各自验证的几块:进程表、启动停止、重启策略、日志落盘、系统自启、命令行入口。每一块单独跑通,拼起来才不容易散。

目前最想补的还是依赖编排那一块,等哪天手动排顺序真的排烦了再说。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

目录
  • 先把边界划出来
  • 选型:Wails 和 Electron 之间
  • 进程模型与重启策略
  • 自启按系统分别实现
  • 日志不能只留在内存里
  • 命令行是同一份能力的另一张脸
  • 怎么验证
  • 还没做和暂时不做的
  • 小结
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档