Cara menggunakan php-fpm cpu limit

If you are using a NGinx webserver with PHP-FPM most likely you will have to adjust the "out of the box" settings of php-fpm. If your php-fpm.log file contains the following error:

[26-Mar-2018 10:10:04] WARNING: [pool www] server reached pm.max_children setting (35), consider raising it
[26-Mar-2018 12:04:52] WARNING: [pool www] seems busy (you may need to increase pm.start_servers, or pm.min/max_spare_servers)

This means you do not have enough processes available for php-fpm.

Based on your realtime logging data, it is easy to determine the correct settings for the php-fpm configuration on your server. The exact settings are based on the memory available to your cloud server, but be aware that you also have to take the other processes into account, they also nibble on those resources (examples: MariaDB, MySQL, Redis). Never simply use 100% memory available in the cloud server!

The following steps need to be adjusted in the /etc/php/fpm/pool.d/www.conf file (typical location on Debian although the path may vary):

pm.max_children = 5
pm.start_servers = 2
pm.min_spare_servers = 4
pm.max_spare_servers = 8

To find the correct values, you will have to measure how much memory a proces consumes. Be aware, this is only possible on a server where the website has a stable memory usage per process, in other words for a shared hosting environment with different websites and different developped code the memory usage per proces will seriously fluctuate!
The following line (executed in shell) will give you valuable output:

ps -ylC php-fpm --sort:rss

The name php-fpm matches your process name. If it possible it has a different name on your server, it depends on the PHP packages used.

The column RSS contains the average memory usage in kilobytes per process. 

S   UID   PID  PPID  C PRI  NI   RSS    SZ WCHAN  TTY          TIME CMD
S     0 24439     1  0  80   0  6364 57236 -      ?        00:00:00 php-fpm
S    33 24701 24439  2  80   0 61588 63335 -      ?        00:04:07 php-fpm
S    33 25319 24439  2  80   0 61620 63314 -      ?        00:02:35 php-fpm

In this example 61588 kilobytes or converted about +- 60 Mb per process.

Another option is to get the average of one php-fpm process:

ps --no-headers -o "rss,cmd" -C php-fpm | awk '{ sum+=$1 } END { printf ("%d%s\n", sum/NR/1024,"Mb") }'

To get the correct value for the number of pm.max_children we will have to check how much memory our cloud server can use for the php-fpm process and divide that total by the average size in Mb of our just checked process.

An example: if our cloud server has 4 GB RAM and a MariaDB database service is running as well that consumes at least 1 GB our best aim is to get 4 - 1 - 0,5 (marge) GB = 2,5 GB RAM or 2560 Mb.

pm.max_children brings us to 2560 Mb / 60 Mb = 42 max_children

We have made the following changes in our www.conf file in the php-fpm pool:

pm.max_children = 40
pm.start_servers = 15
pm.min_spare_servers = 15
pm.max_spare_servers = 25
pm.max_requests = 500

Restart the php-fpm service and see if the server behaves in a correct manner and allocates memory as configured.

Seperti yang sudah dibahas pada tutorial – tutorial sebelumnya, web server Nginx dapat digunakan sebagai reverse proxy dan Nginx dapat melayani aplikasi PHP melalui protokol FastCGI (sebagai server backend).

Terdapat 2 cara komunikasi antara Nginx dengan PHP-FPM diantaranya

  1. Menggunakan Unix Socket
  2. Menggunakan TCP/IP

Secara default di CentOS 8 jika dilihat konfigurasi default PHP-FPM listen menggunakana Unix Socket

1
2
3
4
5
6
7
8
9
10
11
; The address on which to accept FastCGI requests.
; Valid syntaxes are:
; 'ip.add.re.ss:port' - to listen on a TCP socket to a specific IPv4 address on
; a specific port;
; '[ip:6:addr:ess]:port' - to listen on a TCP socket to a specific IPv6 address on
; a specific port;
; 'port' - to listen on a TCP socket to all addresses
; (IPv6 and IPv4-mapped) on a specific port;
; '/path/to/unix/socket' - to listen on a unix socket.
; Note: This value is mandatory.
listen = /run/php-fpm/www.sock

Lalu apa bedanya Unix socket dengan TCP/IP?.

Berikut perbedannya.

Jika menggunakan unix socket komunikasi Nginx ke PHP-FPM menggunakan 1 file yang sama (nginx.sock). Jika Anda menggunakan unix socket, maka dari segi proses kecepatan performa sangat baik, namun perlu diperhatikan juga resource IO dan CPU serta Memory nya semakin banyak beban server maka proses nya juga akan menurun. Perlu di garis bawahi unix socket tidak fleksibel misalnya Anda mempunyai website belajarlinux.id di CentOS menggunakan unix socket dan Anda migrate belajarlinux.id ke OS Ubuntu, tentunya Anda perlu melakukan perubahan konfigurasi karena antara OS Ubuntu dan CentOS berbeda.

Jika menggunakan TCP/IP maka komunikasi Nginx ke PHP-FPM menggunakan Network Address (alamat IP) walaupun dalam localhost (127.0.0.1), lalu dari segi portabilitas TCP/IP socket sangat bagus karena jika kita ingin memindahkan website ke server yang baru kita hanya permu menyesuaikan alamat IP nya saja tanpa perlu mengubah konfigurasi yang lainnya. Dengan menggunakan TCP/IP dari segi proses sangat cocok bagi Anda yang tidak terlalu membutuhkan performance yang cepat namun stabil dalam menghandle ribuan request terlebih server Anda standalone (1 server saja).

Kesimpulannya adalah jika menggunakan unix socket tidak sama dengan menggunakan socket TCP/IP terkait kinerja, beberapa pengujian dan tolok ukur telah membuktikan unix socket lebih cepat. Kelemahan utama dari unix socket adalah dari segi fleksibilitas karena Anda perlu memindahkan file (.sock) dari server lama ke server baru jika misalnya melakukan migrasi website ke OS yang berbeda, website tersebut masih bisa diakses oleh OS apapun dengan syarat OS tersebut sudah support socket.

Selanjutya kita akan mencoba konfigurasi nginx supaya dapat terhubung dengan php-fpm baik menggunakan Unix socket ataupun TCP/IP socket.

# Menggunakan Unix Socket

Pertama Anda perlu konfigurasi php-fpm terlebih dahulu, seperti yang sudah disampaikan diawal default konfigurasi php-fpm CentOS 8 berada di /etc/php-fpm.d/www.conf contohnya sebagai berikut

Cara menggunakan php-fpm cpu limit

Kemudian, atur listener owner dan group php-fpm menjadi nginx seperti berikut

Cara menggunakan php-fpm cpu limit

Jika sudah selanjutnya Anda perlu mengatur server block nginx menggunakan unix socket konfigurasinya seperti berikut

1
fastcgi_pass unix:/run/php-fpm/www.sock;

Detail server block nya seperti berikut

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
server {
        listen 80;
        server_name unix-socket.nurhamim.my.id;
        root /var/www/belajarlinux;
        index index.php index.html index.htm;

        location / {
                try_files $uri $uri/ /index.php?$query_string;
        }

        location ~ \.php {
                include fastcgi.conf;
                fastcgi_split_path_info ^(.+\.php)(/.+)$;
                fastcgi_pass unix:/run/php-fpm/www.sock;
        }
        location ~ /\.ht {
                deny all;
        }
}

Dari kode diatas perhatikan bagian location ~ .php { .

# Menggunakan TCP/IP Socket

Sama halnya dengan unix socket pertama kita perlu menambahkan listen IP yang kita inginkan terlebih dahulu contohnya seperti berikut

Cara menggunakan php-fpm cpu limit

Noted: Pengalamatan IP Address dapat disesuaikan dengan keinginan Anda

Selanjutnya sesuaikan server block Nginx, Anda hanya perlu mengubah fastcgi_pass nya saja dari

1
fastcgi_pass unix:/run/php-fpm/www.sock;

ke

1
fastcgi_pass 127.0.0.3:9001;

Berikut full server block nya

; The address on which to accept FastCGI requests.
; Valid syntaxes are:
; 'ip.add.re.ss:port' - to listen on a TCP socket to a specific IPv4 address on
; a specific port;
; '[ip:6:addr:ess]:port' - to listen on a TCP socket to a specific IPv6 address on
; a specific port;
; 'port' - to listen on a TCP socket to all addresses
; (IPv6 and IPv4-mapped) on a specific port;
; '/path/to/unix/socket' - to listen on a unix socket.
; Note: This value is mandatory.
listen = /run/php-fpm/www.sock
0
; The address on which to accept FastCGI requests.
; Valid syntaxes are:
; 'ip.add.re.ss:port' - to listen on a TCP socket to a specific IPv4 address on
; a specific port;
; '[ip:6:addr:ess]:port' - to listen on a TCP socket to a specific IPv6 address on
; a specific port;
; 'port' - to listen on a TCP socket to all addresses
; (IPv6 and IPv4-mapped) on a specific port;
; '/path/to/unix/socket' - to listen on a unix socket.
; Note: This value is mandatory.
listen = /run/php-fpm/www.sock
1

Jika sudah bisa di simpan dan pastikan tidak ada miss atau kesalahan konfigurasi gunakan perintah nginx -t