Score:0

Limit CPU Usage per PHP Pool

sz flag

I'm running a typical LEMP stack where I have multiple PHP-FPM pools, one for each site that's on a Rocky Linux 8 VPS. Occasionally, some rogue process on one of the sites will cause a huge CPU spike and slow everything else down. I've tried limiting CPU usage per user with cgroups, but it appears it won't work due to the way that PHP-FPM processes are forked. Is there a way to limit CPU usage per FPM pool?

Score:0
mm flag

it can be crucial to effectively manage CPU usage to ensure optimal performance and prevent resource exhaustion. One way to accomplish this is by limiting the CPU usage per PHP pool. A PHP pool is a collection of PHP processes that handle incoming requests.

To limit CPU usage per PHP pool, you can leverage process control (PCNTL) functions provided by PHP. These functions allow you to control and monitor processes running on your server. Here are the steps to implement CPU usage limitation:

Identify the PHP pool: Begin by identifying the specific PHP pool you want to limit. Each PHP pool is typically associated with a specific website or application.

Implement CPU usage limitation logic: Use the PCNTL functions to control the CPU usage. The pcntl_setrlimit() function allows you to set resource limits for a specific process. In this case, you'll set the CPU limit using the RLIMIT_CPU constant.

$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]);

The above code sets the CPU limit to 50% of the available CPU time for the current PHP process.

Apply limitation to the PHP pool: To ensure that the limitation is applied to the specific PHP pool, you can use process forking. Forking creates child processes that inherit the characteristics of the parent process, including the CPU limitation.

// 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();
}

By forking the process, you can ensure that the CPU limitation is applied only to the PHP pool you specified.

Monitor and manage the PHP pool: After implementing the CPU usage limitation, you can monitor and manage the PHP pool as needed. This includes tracking CPU usage, adjusting resource limits, and handling any exceptions or errors that may arise.

By limiting the CPU usage per PHP development pool, you can prevent a single pool from monopolizing system resources and impacting the performance of other applications or websites. It's important to fine-tune the CPU limit based on your specific server capacity and workload requirements to strike the right balance between performance and resource allocation.

Score:0
ws flag

I am not aware of any way to achieve your objective when the processes are running the same user / in the same cgroup. Post-initialization this can be done with cpulimit, which could be controlled via watchdog type service (fail2ban?) however that is a very clunky solution.

Enforcing a strict time limit of executions is always a good idea (this can be set on a per-script basis in your webserver).

You could run multiple php-fpm instances, each with a single pool and have each fpm in different cgroups.

I sit in a Tesla and translated this thread with Ai:

mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.