logo
0
0
WeChat Login
refactor: 重构子包命名与目录结构

Process - 企业级 Go 进程管理框架

Go Version License Go Reference

Process 是一个专为现代化云原生环境设计的 Go 进程管理库。它不仅提供了基础的进程启停功能,更深度集成了 状态机控制拓扑依赖调度多维健康检查资源配额硬限制 (Linux prlimit/cgroups) 以及 RESTful 控制面板

无论是作为微服务的 Sidecar、自研 CI/CD Agent 的核心引擎,还是需要一个比 Supervisord 更轻量、更易于嵌入 Go 应用的进程管理组件,Process 都能提供生产级的稳定性与灵活性。


1. 目录

  1. 核心特性
  2. 快速开始
  3. 安装指南
  4. 核心架构与设计理念
  5. 功能详解
  6. HTTP API 与 实时监控
  7. 配置参考 (YAML Schema)
  8. 平台支持矩阵
  9. 性能基准与优化
  10. 安全建议与最佳实践
  11. 故障排查 (Troubleshooting)
  12. 示例索引
  13. 贡献指南
  14. 许可证

2. 核心特性

  • 原子状态机:严格的状态转换校验(Starting -> Running -> Stopping...),杜绝非法操作。
  • 链式构建器:提供 ProcessBuilder API,支持流式配置,内置参数校验。
  • 拓扑调度:基于 Kahn 算法的依赖管理,支持复杂的进程启动/停止链条。
  • 资源硬限制:在 Linux 上利用 prlimit 实现 CPU、内存、文件描述符的硬性配额,支持 SIGSTOP 预挂起技术防止资源逃逸。
  • 平滑重载:支持 GracefulReload,通过健康检查 readiness 握手确保新老进程无缝交替。
  • 实时推送:内置 SSE (Server-Sent Events) 支持,实时获取进程日志与状态变更。
  • 零依赖核心:核心库仅依赖标准库,轻量且稳定,易于集成。
  • 多后端日志:支持文件轮转、Syslog、内存通道、组合输出等多种日志策略。

3. 快速开始

3.1 极简模式

如果你只需要管理一个简单的进程,可以直接使用 NewProcess

package main import ( "cnb.cool/zishuo/process" "time" "fmt" ) func main() { // 创建并配置进程 proc := process.NewProcess( process.WithName("ping-test"), process.WithCommand("ping"), process.WithArgs("google.com", "-c", "10"), process.WithAutoStart(true), ) // 启动进程(非阻塞) proc.Start(false) // 实时获取状态 go func() { for { info := proc.GetProcessInfo() fmt.Printf("当前状态: %s, PID: %d\n", info.Statename, info.Pid) if info.State >= 100 { // Exited or Fatal break } time.Sleep(time.Second) } }() // 优雅停止(阻塞直到退出) proc.Stop(true) }

3.2 进程管理器模式 (推荐)

使用 Manager 可以获得批量控制、依赖管理和更强的可观测性:

package main import ( "cnb.cool/zishuo/process" "log" ) func main() { m := process.NewManager() // 使用链式 API 创建进程 _, err := m.Process("web-api"). Command("./server"). Args("--port=8080"). Directory("/var/www"). AutoRestart(process.AutoReStartUnexpected). StdoutLogFile("logs/web.log"). Build() if err != nil { log.Fatal(err) } // 启动所有标记为 AutoStart 的进程(按优先级和依赖顺序) m.StartAllProcessesInOrder(true) // 停止所有进程 defer m.StopAllProcesses() }

4. 安装指南

要求 Go 1.23 或更高版本。

go get cnb.cool/zishuo/process

5. 核心架构与设计理念

5.1 状态机模型

Process 内部维护了一个严谨的状态机,确保进程行为的可预测性。

状态说明
Stopped0初始状态或已完全停止
Starting10正在执行启动逻辑,尚未达到 StartSecs 判定时间
Running20进程已成功运行并超过判定时间
Backoff30启动失败,正在等待重试间隔
Stopping40正在发送停止信号并等待退出
Exited100进程自然退出(非用户手动停止)
Fatal200达到最大重试次数后彻底失败

5.2 并发模型与线程安全

  • 原子状态:使用 atomic.Int32 维护进程状态,确保跨 Goroutine 读取的一致性。
  • 写保护:关键操作(如 Start/Stop)受互斥锁保护,防止重复启动或竞态。
  • 信号安全:通过 cmdWaitDone 通道确保不会向已经彻底销毁的进程发送信号。
  • 线程安全 Map:内置 safemap 确保在管理成百上千个进程时,并发读写 Manager 依然稳定。

5.3 平台能力抽象

Process 自动探测当前操作系统的能力边界:

  • Linux:完整支持(ResourceLimits, CGroups, UserSwitch, Reaper)。
  • macOS:支持基础管理与用户切换,不支持资源硬限制。
  • Windows:支持基础管理,不支持资源限制与用户切换。

6. 功能详解

6.1 进程创建与构建器

除了基础的 NewProcess 函数,ProcessBuilder 提供了更直观的链式配置接口,并内置了路径校验、资源限制负值检查等逻辑。

方式 A:函数式选项 (Functional Options)

proc := process.NewProcess( process.WithName("my-service"), process.WithCommand("./bin/app"), process.WithArgs("--config", "prod.yaml"), process.WithAutoStart(true), )

方式 B:链式构建器 (ProcessBuilder)

proc, err := manager.Process("worker-01"). Command("python3"). Args("worker.py"). Directory("/app/workers"). Env("REDIS_URL", "redis://localhost:6379"). Priority(10). AutoRestart(process.AutoReStartTrue). StdoutLogFile("logs/worker.log"). Build()

方式 C:Shell 命令模式

// 内部会自动处理 shell 解析逻辑 proc := process.NewProcessCmd("cd /tmp && ls -l > out.txt", nil)

6.2 生命周期管理

  • Start(wait bool):启动进程。如果 wait=true,将阻塞直到进程进入 Running 状态或启动失败。
  • Stop(wait bool):停止进程。支持发送自定义信号序列(默认 TERM -> KILL)。
  • Signal(sig syscall.Signal, group bool):向进程或进程组发送特定信号。
  • GracefulReload():平滑重载。它会先启动一个新进程,通过健康检查确认新进程 Ready 后,再优雅关闭旧进程。

6.3 依赖关系调度

基于 Kahn 算法实现,支持复杂的有向无环图 (DAG) 调度。

m.AddDependency("app", "mysql") m.AddDependency("app", "redis") // 启动:mysql & redis 并行启动 -> app 启动 m.StartAllProcessesInOrder(true) // 停止:app 停止 -> mysql & redis 停止 m.StopProcessWithDependents("mysql", true)

6.4 多维健康检查

健康检查结果存储在 O(1) 的环形缓冲区中,支持历史回溯。

  • HTTPChecker:检查 URL 响应码、Header。
  • TCPChecker:检查端口是否可连接。
  • CommandChecker:执行外部脚本,退出码 0 为健康。安全警告:请确保脚本来源可信。
  • CustomChecker:传入 func(context.Context) *HealthCheckResult
checker := process.NewHTTPHealthChecker("http://localhost:8080/health", 2*time.Second) checker.ExpectedStatus = 200 proc.SetHealthCheck(&process.HealthCheckConfig{ Checker: checker, Interval: 15 * time.Second, FailThreshold: 3, })

6.5 资源限制 (Resource Limits)

仅限 Linux。Process 采用了一种独特的安全启动序列:

  1. fork 子进程。
  2. 子进程立即发送 SIGSTOP 挂起自己。
  3. 父进程通过 prlimit 设置资源限制。
  4. 父进程发送 SIGCONT 恢复子进程。 这确保了资源限制在子进程执行任何用户代码前就已经生效。
limits := &process.ResourceLimits{ MemoryLimit: 512 * 1024 * 1024, // 512MB CPUTimeLimit: 3600, // 1小时 CPU 时间 OpenFilesLimit: 1024, // 最大文件打开数 CoreDumpSize: 0, // 禁用 Core Dump }

6.6 用户切换与安全权限

支持以特定 UID/GID 运行子进程。

  • 权限预检:在 Linux 上会检查 CAP_SETUID/CAP_SETGID
  • 环境变量清理:自动识别并警告危险的环境变量(如 LD_PRELOAD)。

6.7 日志系统与 IO 重定向

logsink 包提供了工业级的日志处理能力:

  • FileLogger:支持按大小切分、保留备份数。
  • SysLogger:支持将日志发送到系统 Syslog 服务。
  • CompositeLogger:支持同时输出到多个目标(如文件 + 标准输出)。
  • NullLogger:为空日志或显式丢弃输出提供稳定兜底。
// 配置标准输出到文件,50MB 切分,保留 10 个备份 process.WithStdoutLog("/var/log/app.log", "50MB", 10)

6.8 配置文件与热重载

process/config 子包提供文件配置加载、保存、监听与热重载编排能力。

更完整的接入说明见 config/README.md

import processconfig "cnb.cool/zishuo/process/config" cm, _ := processconfig.NewManager(manager, "config.yaml", processconfig.ApplyStrategyReload) cm.Start() // 开始监控

7. 配置项全参考 (Options Reference)

选项说明默认值
WithName进程唯一标识名必填
WithCommand可执行文件路径必填
WithArgs命令行参数列表
WithDirectory工作目录当前目录
WithUser运行用户 (Linux/macOS)当前用户
WithPriority启动优先级 (越小越早)999
WithAutoStart是否随管理器启动true
WithStartSecs判定启动成功的稳定运行时间1s
WithStartRetries启动失败最大重试次数3
WithRestartPause重启前的等待间隔0s
WithAutoReStart重启策略 (true, false, unexpected)true
WithExitCodes视为正常退出的状态码列表[0, 2]
WithStopSignal停止信号序列["TERM"]
WithStopWaitSecs发送信号后等待退出的时间10s
WithKillWaitSecs强制杀死前的最终等待时间2s
WithStopAsGroup是否向整个进程组发送信号false
WithStdoutLog标准输出日志配置 (路径, 大小, 备份数)
WithRedirectStderr是否将错误输出合并到标准输出false

8. HTTP API 与 实时监控

7.1 RESTful 接口规范

Process 提供了一个基于标准库 net/http 的 API 适配器。

方法路径说明
GET/api/v1/processes获取所有进程列表及简要状态
POST/api/v1/processes创建新进程
GET/api/v1/processes/{name}获取特定进程的详细配置与运行时信息
POST/api/v1/processes/{name}/start启动进程 (异步,返回 202)
POST/api/v1/processes/{name}/stop停止进程
GET/api/v1/operations/{id}查询异步操作(如启动)的执行进度

7.2 异步操作与状态轮询

为了防止 HTTP 请求因进程启动过慢(如 Java 应用预热)而超时,启动接口采用异步模式。返回的 operation_id 可用于轮询最终结果。

7.3 SSE 实时日志与状态推送

通过 GET /api/v1/processes/{name}/sse,客户端可以获得一个持久连接,实时接收:

  • 进程标准输出/错误输出。
  • 状态变更事件(如 Running -> Exited)。
  • 健康检查结果变更。

8. 配置参考 (YAML)

processes: - name: web-server command: ./server args: ["--port=8080"] directory: /var/www autostart: true autorestart: unexpected exit_codes: [0, 2] startretries: 3 startsecs: 5 stopsignal: TERM stopwaitsecs: 10 environment: DB_HOST: localhost depends_on: [database] healthcheck: type: http http_url: http://localhost:8080/health interval: 10 timeout: 5 resource_limits: memory_limit: 536870912 stdout_logfile: /var/log/app.log stdout_logfile_maxbytes: 50MB stdout_logfile_backups: 10

9. 平台支持矩阵

特性LinuxmacOS (Darwin)Windows
基础生命周期
资源限制 (prlimit)
用户切换 (Setuid)
进程组信号⚠️ (有限)
孤儿进程回收 (Reaper)
信号序列 (TERM->KILL)⚠️ (仅支持 KILL)

10. 性能基准与优化

  • 低开销:每个进程实例的常驻内存 (RSS) 增量约 1.5MB。
  • 高并发:在单台 4 核机器上可稳定管理 500+ 并发进程。
  • IO 优化:日志写入采用带缓冲的异步模式,避免磁盘 IO 阻塞进程管理主逻辑。

11. 安全建议与最佳实践

  1. 最小权限原则:如果 Manager 以 root 运行,务必通过 WithUser 为子进程降权。
  2. SSRF 防护:在使用 HTTPHealthChecker 时,确保目标 URL 不受外部用户直接控制。
  3. 僵尸进程处理:在 Linux 上,如果 Process 是 PID 1,它会自动启动 Reaper 协程回收孤儿进程。
  4. 优雅关闭:始终建议为应用实现 SIGTERM 处理逻辑,并将 StopWaitSecs 设置为大于应用清理所需的时间。

12. 故障排查

  • 状态卡在 Starting:检查 WithStartSecs 是否设置过长,或进程是否在启动后迅速崩溃。
  • Resource Limit Error:确保内核支持 prlimit64,且当前用户有权修改 hard limit。
  • 配置热重载失效:检查 YAML 语法,并确认 process/config.Manager 的策略是否为 ApplyStrategyRestart
  • macOS 信号失效:macOS 不支持进程组信号的某些特性,建议使用优雅关闭信号序列。

13. 示例索引

目录演示内容
examples/lifecycle基础进程启停、健康检查与状态查询
examples/dependencies复杂的拓扑启动顺序演示
examples/healthcheck四种健康检查器的配置与历史记录获取
examples/control_httpapi如何集成 REST 控制面板与认证中间件
examples/resource_limitsLinux 下的内存与 CPU 限制实战
examples/sse实时日志推送与前端对接演示
examples/config_hot_reload配置文件监控与热重载策略

14. 贡献指南

我们欢迎任何形式的贡献!

  1. 提交 Issue:报告 Bug 或提出新功能建议。
  2. 提交 PR:请确保代码通过 golangci-lint 检查,并附带必要的单元测试。
  3. 完善文档:修正错别字或增加使用案例。

15. 许可证

本项目采用 MIT 许可证。详见 LICENSE 文件。


相关项目

  • supervisord (Python) - 经典的进程管理工具。
  • pm2 (Node.js) - 强大的 JS 进程管理器。
  • systemd (Linux) - 现代 Linux 系统的基石。