Tuning linux, nginx, php-fpm and Share PHP Sessions on Multiple Memcached to Scaling to 12 Million Concurrent Connections

Fonte: https://stackoverflow.com/questions/7325211/tuning-nginx-worker-process-to-obtain-100k-hits-per-min </p> Fonte: https://geekflare.com/php-fpm-optimization/ </p> Fonte: https://mrotaru.wordpress.com/2013/10/10/scaling-to-12-million-concurrent-connections-how-migratorydata-did-it/ </p> Fonte: https://www.digitalocean.com/community/tutorials/how-to-share-php-sessions-on-multiple-memcached-servers-on-ubuntu-14-04

Tuning nginx worker_process to obtain 100k hits per min

worker_processes  4;  # 2 * Number of CPUs

events {
    worker_connections  19000;  # It's the key to high performance - have a lot of connections available
}

worker_rlimit_nofile    20000;  # Each connection needs a filehandle (or 2 if you are proxying)


# Total amount of users you can serve = worker_processes * worker_connections

Optimizing PHP-FPM for High Performance

     location ~ \.php$ {
        try_files $uri =404;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass unix:/run/php/php7.2-fpm.sock;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;
    }

/etc/php/7.2/fpm/php-fpm.conf

;;;;;;;;;;;;;;;;;;;;;
; FPM Configuration ;
;;;;;;;;;;;;;;;;;;;;;

; All relative paths in this configuration file are relative to PHP's install
; prefix (/usr). This prefix can be dynamically changed by using the
; '-p' argument from the command line.

;;;;;;;;;;;;;;;;;;
; Global Options ;
;;;;;;;;;;;;;;;;;;

[global]
; Pid file
; Note: the default prefix is /var
; Default Value: none
pid = /run/php/php7.2-fpm.pid

; Error log file
; If it's set to "syslog", log is sent to syslogd instead of being written
; into a local file.
; Note: the default prefix is /var
; Default Value: log/php-fpm.log
error_log = /var/log/php7.2-fpm.log

Inside this file, add three more variables like this:

emergency_restart_threshold 10
emergency_restart_interval 1m
process_control_timeout 10s

/etc/php/7.2/fpm/pool.d/www.conf.

Let’s see what this file starts like:

; Start a new pool named 'www'.
; the variable $pool can be used in any directive and will be replaced by the
; pool name ('www' here)
[www]

; Per pool prefix
; It only applies on the following directives:
; - 'access.log'
; - 'slowlog'
; - 'listen' (unixsocket)
; - 'chroot'
; - 'chdir'
; - 'php_values'
; - 'php_admin_values'
; When not set, the global prefix (or /usr) applies instead.
; Note: This directive can also be relative to the global prefix.
; Default Value: none
;prefix = /path/to/pools/$pool

; Unix user/group of processes
; Note: The user is mandatory. If the group is not set, the default user's group
;       will be used.
user = www-data
group = www-data

Finally, we arrive at the source of the matter, the process manager (pm) setting. Generally, you’ll see the defaults as something like this:

pm = dynamic
pm.max_children = 5
pm.start_servers = 3
pm.min_spare_servers = 2
pm.max_spare_servers = 4
pm.max_requests = 200

So, what does “dynamic” here mean? I think the official docs best explain this (I mean, this should already be part of the file you’re editing, but I’ve reproduced it here just in case it isn’t):

 ; Choose how the process manager will control the number of child processes.
; Possible Values:
;   static  - a fixed number (pm.max_children) of child processes;
;   dynamic - the number of child processes are set dynamically based on the
;             following directives. With this process management, there will be
;             always at least 1 children.
;             pm.max_children      - the maximum number of children that can
;                                    be alive at the same time.
;             pm.start_servers     - the number of children created on startup.
;             pm.min_spare_servers - the minimum number of children in 'idle'
;                                    state (waiting to process). If the number
;                                    of 'idle' processes is less than this
;                                    number then some children will be created.
;             pm.max_spare_servers - the maximum number of children in 'idle'
;                                    state (waiting to process). If the number
;                                    of 'idle' processes is greater than this
;                                    number then some children will be killed.
;  ondemand - no children are created at startup. Children will be forked when
;             new requests will connect. The following parameter are used:
;             pm.max_children           - the maximum number of children that
;                                         can be alive at the same time.
;             pm.process_idle_timeout   - The number of seconds after which
;                                         an idle process will be killed.
; Note: This value is mandatory.

So, we see that there are three possible values:

  • Static: A fixed number of PHP processes will be maintained no matter what.
  • Dynamic: We get to specify the minimum and a maximum number of processes that php-fpm will keep alive at any given point in time.
  • ondemand: Processes are created and destroyed, well, on demand.

So, how do these settings matter?

In simple terms, if you have a website with low traffic, the “dynamic” setting is a waste of resources most of the time. Assuming that you have pm.min_spare_servers set to 3, three PHP processes will be created and maintained even when there’s no traffic on the website. In such cases, “ondemand” is a better option, letting the system decide when to launch new processes.

On the other hand, websites that handle large amounts of traffic or must respond quickly will get punished in this setting. Creating a new PHP process, making it part of a pool, and monitoring it, is extra overhead that is best avoided.

Using pm = static fixes the number of child processes, letting maximum system resources to be used in serving the requests rather than managing PHP. If you do go this route, beware that it has its guidelines and pitfalls. A rather dense but highly useful article about it is here.