教程 pingora tutorial

处理崩溃(Panic)

在 Rust 中,panic 表示程序遇到不可恢复的错误。Pingora 提供了机制来捕获和处理 panic,避免服务因单个错误而完全中断。

默认行为

当 Pingora 内部发生 panic 时:

  • 当前线程会终止;
  • 异步任务可能被取消;
  • 主服务进程通常会记录错误并继续运行其他线程(依赖 Tokio 异步运行时)。

捕获 panic

可以通过 Rust 提供的 std::panic::set_hook 自定义 panic 处理逻辑:

rust
use std::panic;

fn main() {
    panic::set_hook(Box::new(|info| {
        eprintln!("Pingora 捕获到 panic: {:?}", info);
        // 可以在这里写日志、统计或报警
    }));

    // 启动 Pingora 服务
    let mut server = pingora::Server::new(None).unwrap();
    server.bootstrap();
    server.run_forever(pingora::http_proxy_service(None)).unwrap();
}

`

日志记录

Pingora 会将 panic 信息写入日志文件中(如果配置了 logging.file),方便运维排查问题。

配置示例:

yaml
logging:
  level: error
  file: /var/log/pingora.log

进程恢复

即使某个线程 panic,Pingora 的主进程通常不会退出:

  • Tokio 异步运行时会继续运行其他任务;
  • 可通过 supervisor 或 systemd 监控主进程,实现自动重启。

最佳实践

  1. 捕获关键区域的 panic:在自定义过滤器或处理函数中使用 catch_unwind。
  2. 记录详细日志:包含线程信息、调用栈和上下文状态。
  3. 结合 systemd 或守护进程:确保主进程崩溃时自动重启。
  4. 避免 panic:尽量在业务逻辑中返回 Result 或 Option,将错误通过类型系统处理,而非依赖 panic。

通过合理捕获和记录 panic,Pingora 可以在遇到不可预期错误时保持服务稳定,同时便于后续调试和运维管理。