ΠœΠ΅Π½Π΅Π΄ΠΆΠ΅Ρ€ процСссов FastCGI (FPM)

Π‘ΠΎΠ΄Π΅Ρ€ΠΆΠ°Π½ΠΈΠ΅

FPM (FastCGI Process Manager, ΠΌΠ΅Π½Π΅Π΄ΠΆΠ΅Ρ€ процСссов интСрфСйса FastCGI) β€” основная рСализация интСрфСйса FastCGI для PHP, которая Π² основном содСрТит Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π», ΠΏΠΎΠ»Π΅Π·Π½Ρ‹ΠΉ для высоконагруТСнных сайтов.

Π­Ρ‚Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ Π²ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚:

  • ΠŸΡ€ΠΎΠ΄Π²ΠΈΠ½ΡƒΡ‚ΠΎΠ΅ ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ процСссами с ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½ΠΎΠΉ (graceful) ΠΏΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€ΠΎΠΉ остановки ΠΈ запуска;

  • ΠŸΡƒΠ»Ρ‹, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΡƒΠΌΠ΅ΡŽΡ‚ Π·Π°ΠΏΡƒΡΠΊΠ°Ρ‚ΡŒ Π²ΠΎΡ€ΠΊΠ΅Ρ€Ρ‹ с Ρ€Π°Π·Π½Ρ‹ΠΌΠΈ uid, gid, chroot ΠΈ ΠΎΠΊΡ€ΡƒΠΆΠ΅Π½ΠΈΠ΅ΠΌ Π·Π° счёт ΠΏΡ€ΠΎΡΠ»ΡƒΡˆΠΈΠ²Π°Π½ΠΈΡ Ρ€Π°Π·Π½Ρ‹Ρ… ΠΏΠΎΡ€Ρ‚ΠΎΠ² ΠΈ Ρ€Π°Π±ΠΎΡ‚Ρ‹ с Ρ€Π°Π·Π½Ρ‹ΠΌΠΈ Ρ„Π°ΠΉΠ»Π°ΠΌΠΈ php.ini (Π·Π°ΠΌΠ΅Ρ‰Π΅Π½ΠΈΠ΅ safe_mode);

  • НастраиваСмоС Π²Π΅Π΄Π΅Π½ΠΈΠ΅ ΠΆΡƒΡ€Π½Π°Π»Π° ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ² Π²Ρ‹Π²ΠΎΠ΄Π° (stdout) ΠΈ ошибок (stderr);

  • Аварийный пСрСзапуск Π² случаС Π²Π½Π΅Π·Π°ΠΏΠ½ΠΎΠ³ΠΎ Ρ€Π°Π·Ρ€ΡƒΡˆΠ΅Π½ΠΈΡ opcode-кСша;

  • ΠŸΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ° ускорСнной Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ (accelerated upload);

  • slowlog β€” Π»ΠΎΠ³ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ Π½Π΅ΠΎΠ±Ρ‹Ρ‡Π½ΠΎ ΠΌΠ΅Π΄Π»Π΅Π½Π½Ρ‹Ρ… скриптов; Π½Π΅ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΈΠΌΡ‘Π½, Π½ΠΎ ΠΈ PHP-трассировки, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ Π΄Π°Ρ‘Ρ‚ ΠΊΠΎΠΌΠ°Π½Π΄Π° ptrace ΠΈ Π΄Ρ€ΡƒΠ³ΠΈΠ΅ ΠΏΠΎΠ΄ΠΎΠ±Π½Ρ‹Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ чтСния исполняСмых Π΄Π°Π½Π½Ρ‹Ρ… (execute_data) ΡƒΠ΄Π°Π»Ρ‘Π½Π½Ρ‹Ρ… процСссов;

  • fastcgi_finish_request() β€” ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½Π°Ρ функция для Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΡ запроса ΠΈ сброса всСх Π±ΡƒΡ„Π΅Ρ€ΠΎΠ² Π΄Π°Π½Π½Ρ‹Ρ…, ΠΏΡ€ΠΈΡ‡Ρ‘ΠΌ процСсс смоТСт ΠΏΡ€ΠΎΠ΄ΠΎΠ»ΠΆΠ°Ρ‚ΡŒ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ Π΄Ρ€ΡƒΠ³ΠΈΡ… Π΄Π»ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Ρ… дСйствий (ΠΊΠΎΠ½Π²Π΅Ρ€Ρ‚ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ Π²ΠΈΠ΄Π΅ΠΎ, ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° статистики ΠΈ Ρ‚. ΠΏ.);

  • ДинамичСскоС, ΠΏΠΎ Ρ‚Ρ€Π΅Π±ΠΎΠ²Π°Π½ΠΈΡŽ ΠΈΠ»ΠΈ статичСскоС ΠΏΠΎΡ€ΠΎΠΆΠ΄Π΅Π½ΠΈΠ΅ Π΄ΠΎΡ‡Π΅Ρ€Π½ΠΈΡ… процСссов;

  • Базовая ΠΈ Ρ€Π°ΡΡˆΠΈΡ€Π΅Π½Π½Π°Ρ информация ΠΎ состоянии (Π°Π½Π°Π»ΠΎΠ³ΠΈΡ‡Π½ΠΎ ΠΌΠΎΠ΄ΡƒΠ»ΡŽ mod_status Π²Π΅Π±-сСрвСра Apache) с ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠΎΠΉ Ρ€Π°Π·Π½Ρ‹Ρ… Ρ„ΠΎΡ€ΠΌΠ°Ρ‚ΠΎΠ² Π½Π°ΠΏΠΎΠ΄ΠΎΠ±ΠΈΠ΅ json, xml ΠΈ openmetrics;

  • Π€Π°ΠΉΠ» ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΠΈ Π½Π° основС Ρ„Π°ΠΉΠ»Π° php.ini.

οΌ‹Π”ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ

ΠŸΡ€ΠΈΠΌΠ΅Ρ‡Π°Π½ΠΈΡ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅ΠΉ 11 notes

up
23
info at f1-outsourcing dot eu ΒΆ
7 years ago
It looks like the php-fpm daemon is not able to use its groups it is running with.

https://bugs.php.net/bug.php?id=77837
up
22
ganlvtech at qq dot com ΒΆ
8 years ago
php-fpm is not avaliable on Windows, but you can use IIS or Apache as the "fastcgi process manager".

If you have to use Nginx, here is a solution. Nginx provides a load balancing module. We can distribute the request to different php-cgi.exe process.

<http://nginx.org/en/docs/http/load_balancing.html>
<http://nginx.org/en/docs/http/ngx_http_upstream_module.html>

This is the origin nginx conf.
```
location ~ \.php$ {
    try_files  $uri = 404;
    fastcgi_pass  127.0.0.1:9000;
    fastcgi_index  index.php;
    include  fastcgi.conf;
}
```

You can replace it by
```
upstream php {
    server  127.0.0.1:9000;
    server  127.0.0.1:9001;
    server  127.0.0.1:9002;
    server  127.0.0.1:9003;
}

location ~ \.php$ {
    try_files  $uri = 404;
    fastcgi_pass  php;
    fastcgi_index  index.php;
    include  fastcgi.conf;
}
```

CAUTION!!

php-cgi.exe process will die after several requests, so you have to restart the php-cgi.exe manually to keep a process listening the port.

DON'T USE THIS SOLUTION IN PRODUCTION!!
up
21
robin at robinwinslow dot co dot uk ΒΆ
15 years ago
Init script setup
===

You will probably want to create an init script for your new php-fpm. Fortunately, PHP 5.3.3 provides one for you, which you should copy to your init directory and change permissions:

$ cp <php-5.3.3-source-dir>/sapi/fpm/init.d.php-fpm.in /etc/init.d/php-fpm
$ chmod 755 /etc/init.d/php-fpm

It requires a certain amount of setup. First of all, make sure your php-fpm.conf file is set up to  create a PID file when php-fpm starts. E.g.:
----
pid = /var/run/php-fpm.pid
----
(also make sure your php-fpm user has permission to create this file).

Now open up your new init script (/etc/init.d/php-fpm) and set the variables at the top to their relevant values. E.g.:
---
prefix=
exec_prefix=
php_fpm_BIN=/sbin/php-fpm
php_fpm_CONF=/etc/php-fpm.conf
php_fpm_PID=/var/run/php-fpm.pid
---

Your init script is now ready. You should now be able to start, stop and reload php-fpm:

$ /etc/init.d/php-fpm start
$ /etc/init.d/php-fpm stop
$ /etc/init.d/php-fpm reload

The one remaining thing you may wish to do is to add your new php-fpm init script to system start-up. E.g. in CentOS:

$ /sbin/chkconfig php-fpm on

===========

Disclaimer: Although I did just do this on my own server about 20 mins ago, everything I've written here is off the top of my head, so it may not be 100% correct. Also, allow for differences in system setup. Some understanding of what you are doing is assumed.
up
17
dreamcat4 at gmail dot com ΒΆ
12 years ago
Doesn't work? Enable logging!

The php-fpm.log file is a great place to fault-find errors and get to the bottom of a problem. But be sure to enable logging for your specific worker pool. Or you won't see anything!

Example:

To enable error logging for the default [www] worker pool, add this line in the [www] section of your php-fpm.conf:

[www]
catch_workers_output = yes
up
18
joel k ΒΆ
14 years ago
the fpm process supports the USER2 signal, which is used to reload the config file.

kill -USR2 [pid]

should do the trick.
up
13
user at NOSPAM dot example dot com ΒΆ
8 years ago
It is important to note that FPM is not built with the windows binaries.  Many of the guides you may find online rely on php-cgi.exe.  Unfortunately they call it FPM but this is incorrect!

The executable php-cgi.exe that is bundled with the windows binaries is a FastCGI interface but it is *not* FPM (Fastcgi Process Manager).  php-cgi.exe does not have multi-threading or concurrent request support, nor support for any of the FPM configuration options.

The only solid information I've gathered into why FPM is not available is a bug report explaining that FPM is built around fork(), which is not natively available on windows (https://bugs.php.net/bug.php?id=62447).
up
11
ikrabbe dot ask at gmail dot com ΒΆ
8 years ago
I'm very unhappy with the way php-fpm handles requests.
There isn't even some SCRIPT_FILENAME in the RFC for CGI, an that's the only standard I found to handle the requests.

Actually what you are doing with PATH_TRANSLATED is supposed to translate to the path, which is broken by media wikis, as they use the PATH_INFO to find the ressource, not some script.

In the original CGI context, the PATH_INFO is passed to the CGI binary to specify some ressource argument. So actually

    SCRIPT_NAME  ~ argv0
    PATH_INFO      ~ argv1

in command context.

Conclusion: We should rewrite php-fpm to obey the rfc3875 CGI standard.
Having SCRIPT_NAME pointing to /something.php, must translate to 

    CWD/something.php

CWD is the working directory where php-fpm is started (or configured to change to).

In case of chroot CWD = "".

In any case the SCRIPT_NAME php script can be found with ./SCRIPT_NAME, from the CWD. So the undocumented not standardized SCRIPT_FILENAME should vanish! It breaks the CGI standard.
up
12
kokushibyou at gmail dot com ΒΆ
13 years ago
PHP-FPM is FAST - but be wary of using it while your code base is stored on NFS - under average load your NFS server will feel some serious strain. I have yet to find a work around for this bug: https://bugs.php.net/bug.php?id=52312
up
2
&#34;atesin&#34; at the free google mail service ΒΆ
2 years ago
in response to "ikrabbe dot ask at gmail dot com" about SCRIPT_NAME and PATH_INFO being empty, this could be related...

while configuring php-fpm with nginx in debian (actually raspberry pi), a comment line in .conf grabbed my attention

there is a "feature" (that looks more like a bug) reported about 10 years ago in http://trac.nginx.org/nginx/ticket/321 ... in which "try_files" could reset the contents of $fastcgi_script_name and $fastcgi_path_info ... this is a workaround mentioned in forums by user "zakaria"

<?php /* not actual php code but nginx .conf */
location ~ [^/]\.php(/|$)
{
fastcgi_split_path_info ^(.+?\.php)(/.*)$;
# Save the $fastcgi_path_info before try_files clear it
set $path_info $fastcgi_path_info;
fastcgi_param PATH_INFO $path_info;
try_files $fastcgi_script_name =404;

fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
}
?>
up
1
jpmkn.iki.fi ΒΆ
2 years ago
@ ikrabbe you might want to look at mod_rewrite to address the environment variable variation(!) between cgi and cli php.
up
0
&#34;atesin&#34; at the free google mail service ΒΆ
2 years ago
in response to "dreamcat4 at gmail dot com" about enabling logs in php-fpm

i *hate* going blind, so enabling logs is generally the first thing i do...

by doing dreamcat4 suggestion, logs got enabled but mixed with php process logs ... instead doing that and to isolate logs from [www] worker pool in its own file, these directives worked for me in "www" worker .ini file (you have to set directories and permissions before)

php_admin_flag[log_errors] = on
php_admin_value[error_log] = /var/log/php-fpm/www-error.log