# bakserver **Repository Path**: zinface/bakserver ## Basic Information - **Project Name**: bakserver - **Description**: 轻量 HTTP 服务,每次请求时将指定目录实时打包为 tar 流返回。 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-07-20 - **Last Updated**: 2026-07-21 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # bakserver 轻量 HTTP 服务,每次请求时将指定目录实时打包为 tar 流返回。 ## 构建 ```bash go build -o bakserver ``` ## 使用 ```bash ./bakserver -port 8080 -dir /path/to/dir ``` 拉取归档: ```bash curl -o backup.tar http://localhost:8080/ ``` ## 程序设计 ### 整体架构 ``` HTTP 请求 │ ▼ 启动 tar cf - 进程 │ ▼ tar stdout ──pipe──→ HTTP ResponseWriter │ ▼ 等待 拷贝完成 或 客户端断开 ``` ### 逻辑考虑 #### 1. 流式传输 vs 全量缓存 tar 输出通过 `StdoutPipe` 直连 `ResponseWriter`,用 `io.Copy` 在内核缓冲区层面流式转发,避免将整个归档写入内存再一次性 flush。对大目录场景内存开销恒定。 #### 2. 客户端断开时的进程清理 HTTP 请求的 `context` 在客户端断开连接时自动取消。通过 `select` 同时监听两个信号: - `r.Context().Done()` — 客户端断开,立即 `cmd.Process.Kill()` 杀掉 tar 进程 - `copyDone` — `io.Copy` 正常结束 避免了客户端断开后 tar 进程继续在后台空跑。 #### 3. 进程生命周期管理 ``` cmd.Start() → 拷贝 goroutine 启动 → 等待 select → cmd.Wait() ``` `cmd.Wait()` 确保子进程的僵尸回收(reap),防止进程泄漏。 #### 4. 错误处理 - 管道创建或进程启动失败 → 直接返回 500,不启动无用拷贝 - `io.Copy` 写入失败(如客户端断连)→ 仅日志记录,不阻塞请求结束 - tar 非零退出 → 日志记录,不影响 HTTP 响应(可能已输出部分数据) #### 5. 竞态安全 `cmd.Process.Kill()` 与 `io.Copy` 之间的竞态由 `select` 保证只会进入一个分支;若拷贝在 Kill 前瞬间完成,`Kill` 调用会返回错误(进程已退出),此错误被忽略,行为正确。