我正在运行一个典型的 LEMP 堆栈,其中有多个 PHP-FPM 池,每个位于 Rocky Linux 8 VPS 上的站点都有一个池。有时,其中一个站点上的一些恶意进程会导致 CPU 大幅飙升并减慢其他所有站点的速度。我尝试使用 cgroups 限制每个用户的 CPU 使用率,但由于 PHP-FPM 进程的分叉方式,它似乎不起作用。有没有办法限制每个 FPM 池的 CPU 使用率?
答案1
有效管理 CPU 使用率对于确保最佳性能和防止资源耗尽至关重要。实现此目的的一种方法是限制每个 PHP 池的 CPU 使用率。PHP 池是处理传入请求的 PHP 进程的集合。
要限制每个 PHP 池的 CPU 使用率,您可以利用 PHP 提供的进程控制 (PCNTL) 函数。这些函数允许您控制和监视服务器上运行的进程。以下是实现 CPU 使用率限制的步骤:
确定 PHP 池:首先确定要限制的特定 PHP 池。每个 PHP 池通常与特定网站或应用程序相关联。
实现 CPU 使用率限制逻辑:使用 PCNTL 函数来控制 CPU 使用率。pcntl_setrlimit() 函数允许您为特定进程设置资源限制。在本例中,您将使用 RLIMIT_CPU 常量设置 CPU 限制。
$cpuLimit = 50; // Percentage of CPU limit
// Convert percentage to microseconds
$microseconds = $cpuLimit * 10000;
// Set CPU limit for the current process
pcntl_setrlimit(RLIMIT_CPU, [$microseconds, $microseconds]);
上述代码将 CPU 限制设置为当前 PHP 进程可用 CPU 时间的 50%。
将限制应用于 PHP 池:要确保将限制应用于特定 PHP 池,可以使用进程分叉。分叉会创建继承父进程特征(包括 CPU 限制)的子进程。
// Identify the PHP pool you want to limit
$poolName = "pool1";
// Fork the current process
$pid = pcntl_fork();
if ($pid === -1) {
// Handle forking error
} elseif ($pid) {
// Parent process
// Monitor and manage the child process as needed
} else {
// Child process
// Set CPU limit for the child process
pcntl_setrlimit(RLIMIT_CPU, [$microseconds, $microseconds]);
// Execute the PHP pool logic
run_php_pool($poolName);
// Exit the child process
exit();
}
通过分叉进程,您可以确保 CPU 限制仅适用于您指定的 PHP 池。
监控和管理 PHP 池:实施 CPU 使用率限制后,您可以根据需要监控和管理 PHP 池。这包括跟踪 CPU 使用率、调整资源限制以及处理可能出现的任何异常或错误。
通过限制每个 CPU 的使用率PHP 开发池,可以防止单个池独占系统资源并影响其他应用程序或网站的性能。根据特定服务器容量和工作负载要求微调 CPU 限制很重要,以便在性能和资源分配之间取得适当的平衡。
答案2
当进程运行在同一个用户/同一个 cgroup 中时,我不知道有什么方法可以实现您的目标。初始化后,可以使用 cpulimit 来实现,可以通过看门狗类型的服务(fail2ban?)进行控制,但这是一个非常笨拙的解决方案。
强制执行严格的时间限制始终是一个好主意(这可以在您的网络服务器中根据每个脚本进行设置)。
您可以运行多个 php-fpm 实例,每个实例都有一个池,并且每个 fpm 位于不同的 cgroup 中。