--- title: 利用 UNIX SIGTERM 信号实现 CLI 程序平滑重启 date: 2025-02-07 09:54:00 +0800 categories: [PHP] tags: [] pin: false --- ## 一、引言 当我们开发后台任务或服务时,如何优雅地终止程序是一个绕不开的话题。特别是在频繁更新代码的场景下,程序突然中断可能导致任务中断或数据不一致的问题。 本文以简单的 `PHP CLI` 为示例,将从 **SIGTERM 信号** 的基本概念讲起,逐步深入,带你掌握如何在 **PHP CLI 程序** 中实现优雅的平滑重启。 ## 二、SIGTERM 信号的基本概念 ### 2.1 什么是 SIGTERM 信号? **SIGTERM** 是 Unix 和类 Unix 系统中用于终止进程的信号之一。它的特别之处在于,进程在收到该信号时,有机会决定如何应对: 1. **直接退出**:如果程序没有捕获或处理 SIGTERM,操作系统会按照默认行为,直接终止进程。 2. **优雅退出**:程序可以通过捕获 SIGTERM,执行一些必要的清理逻辑,例如保存状态、释放资源等,然后再退出。 与其他信号相比: - **SIGINT**(通常由用户按下 `Ctrl + C` 触发)用于交互式中断。 - **SIGKILL** 则无法被捕获,直接强制终止进程。 ### 2.2 SIGTERM 在应用程序中的意义 在应用程序中,优雅地终止进程非常重要,尤其是在以下场景中: 1. **后台任务处理**:防止任务中断,保证关键操作的完整性。 2. **服务热更新**:当部署新版本时,旧实例需要平稳退出,避免中途终止正在处理的请求。 3. **资源释放**:如关闭数据库连接、文件句柄等,防止资源泄漏。 现代工具如 **Kubernetes** 和 **supervisord**,在停止容器或重启服务时,都会发送 SIGTERM 信号。这使得进程有时间完成未完成的任务,再优雅地退出。 ## 三、如何在 PHP CLI 程序中实现优雅重启? 为了让 PHP CLI 程序能够捕获 SIGTERM 信号,并在收到信号时优雅退出,可以使用 PHP 提供的 **`pcntl_signal`** 和 **`pcntl_async_signals`** 函数。 ### 3.1 基本实现:捕获 SIGTERM 信号 以下代码展示了如何捕获 SIGTERM 信号并进行清理: ```php