主题
处理崩溃(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 监控主进程,实现自动重启。
最佳实践
- 捕获关键区域的 panic:在自定义过滤器或处理函数中使用
catch_unwind
。 - 记录详细日志:包含线程信息、调用栈和上下文状态。
- 结合 systemd 或守护进程:确保主进程崩溃时自动重启。
- 避免 panic:尽量在业务逻辑中返回
Result
或Option
,将错误通过类型系统处理,而非依赖 panic。
通过合理捕获和记录 panic,Pingora 可以在遇到不可预期错误时保持服务稳定,同时便于后续调试和运维管理。