# systemd_reload: Rust应用零停机进程管理

高性能Rust库，提供systemd风格的进程管理，支持零停机滚动更新、优雅关闭和自动故障恢复。

## 目录

- [功能特性](#功能特性)
- [快速开始](#快速开始)
- [API参考](#api参考)
- [架构设计](#架构设计)
- [技术栈](#技术栈)
- [项目结构](#项目结构)
- [使用示例](#使用示例)
- [历史背景](#历史背景)

## 功能特性

- **零停机滚动更新**: 无缝替换运行中的进程，不中断服务
- **优雅关闭**: 正确处理信号，确保进程干净退出
- **自动恢复**: 自动重启失败的进程
- **高性能**: 使用crossfire异步消息队列，开销极小
- **信号管理**: 处理SIGHUP重载、SIGTERM/SIGINT关闭
- **Worker模式检测**: 防止进程生成时的无限递归

## 快速开始

添加到 `Cargo.toml`:

```toml
[dependencies]
systemd_reload = "0.1.0"
```

基本用法:

```rust
use systemd_reload::{run, is_worker};

#[tokio::main]
async fn main() {
    if is_worker() {
        // Worker进程：运行主要应用逻辑
        run_application().await;
    } else {
        // 监督者进程：管理worker
        run().await;
    }
}

async fn run_application() {
    // 实际的应用代码放在这里
    println!("Worker进程启动，PID: {}", std::process::id());
    
    // 示例：Web服务器、后台任务等
    loop {
        // 业务逻辑
        tokio::time::sleep(tokio::time::Duration::from_secs(1)).await;
    }
}
```

## API参考

### 核心类型

#### `Run`
主进程管理器，处理worker生命周期。

```rust
impl Run {
    pub fn new() -> Self
    pub async fn run(mut self)
}
```

#### `Exit`
表示进程退出信息。

```rust
pub struct Exit {
    pub pid: u32,
    pub code: Option<i32>,
}
```

### 函数

#### `is_worker() -> bool`
通过检查 `SYSTEMD_RELOAD_WORKER` 环境变量来检测当前进程是否运行在worker模式。

## 架构设计

库实现了监督者-工作者模式，使用异步消息传递：

```mermaid
graph TD
    A[监督者进程] --> B[信号处理器]
    A --> C[Worker管理器]
    A --> D[消息队列]
    
    B --> E[SIGHUP: 滚动更新]
    B --> F[SIGTERM/SIGINT: 关闭]
    
    C --> G[生成Worker]
    C --> H[监控Worker]
    C --> I[处理退出]
    
    G --> J[Worker进程1]
    G --> K[Worker进程2]
    
    H --> D
    I --> D
    
    D --> L[进程事件]
    L --> M[失败时重启]
    L --> N[优雅关闭]
```

### 处理流程

1. **初始化**: 监督者启动并生成初始worker进程
2. **信号监控**: 监听系统信号和worker退出事件
3. **滚动更新**: 收到SIGHUP时，生成新worker并优雅终止旧worker
4. **故障恢复**: 自动重启意外退出的worker
5. **优雅关闭**: 收到SIGTERM/SIGINT时，终止所有worker并退出

## 技术栈

- **异步运行时**: Tokio提供async/await支持
- **消息队列**: Crossfire提供高性能进程间通信
- **信号处理**: signal-hook-tokio提供异步信号处理
- **进程管理**: Tokio进程生成和监控
- **日志记录**: 集成标准Rust log crate

## 项目结构

```
systemd_reload/
├── src/
│   └── lib.rs          # 核心实现
├── tests/
│   └── main.rs         # 集成测试
├── readme/
│   ├── en.md          # 英文文档
│   └── zh.md          # 中文文档
└── Cargo.toml         # 项目配置
```

## 使用示例

### Web服务器示例

```rust
use systemd_reload::{run, is_worker};
use log::info;

#[tokio::main]
async fn main() {
    if is_worker() {
        // Worker进程：运行Web服务器
        start_web_server().await;
    } else {
        // 监督者进程：管理worker
        info!("启动监督者");
        run().await;
    }
}

async fn start_web_server() {
    info!("Web服务器启动，PID: {}", std::process::id());
    
    // Web服务器设置示例
    // let app = axum::Router::new().route("/", axum::routing::get(handler));
    // axum::Server::bind(&"0.0.0.0:3000".parse().unwrap())
    //     .serve(app.into_make_service())
    //     .await
    //     .unwrap();
    
    // 演示用占位符
    loop {
        tokio::time::sleep(tokio::time::Duration::from_secs(1)).await;
    }
}
```

### 测试Worker检测

```rust
use systemd_reload::is_worker;
use std::env;

fn main() {
    // 初始状态不是worker
    assert!(!is_worker());
    
    // 设置环境变量
    unsafe {
        env::set_var("SYSTEMD_RELOAD_WORKER", "true");
    }
    assert!(is_worker());
    
    // 清理
    unsafe {
        env::remove_var("SYSTEMD_RELOAD_WORKER");
    }
    assert!(!is_worker());
}
```

## 历史背景

零停机部署的概念起源于1960年代的电信和关键任务系统。"热插拔"一词最初指在不关闭系统的情况下更换硬件组件的能力。

在软件领域，这种模式的发展历程：

- **1970年代**: IBM大型机引入动态程序替换
- **1990年代**: Erlang/OTP为电信系统开创了热代码交换
- **2000年代**: nginx等Web服务器普及了优雅重载
- **2010年代**: 容器编排(Kubernetes)使滚动更新成为主流

systemd于2010年发布，通过socket激活和服务重载将这种模式带到Linux系统服务中。本库将类似功能引入Rust应用，利用现代异步编程模式实现高性能进程管理。

这里使用的监督者-工作者模式受到Erlang"让它崩溃"哲学的启发，监督者监控并重启失败的工作者，通过隔离和恢复而非预防来确保系统弹性。