Nginx – How to add a pool to FPM (nginx) without reload/restart fpm itself

cgifastcginginxphp-fpmphp5

Im building an environment (on a ubuntu 10.04.02 machine) to handle a website with many (should support at least 1000) subdomains, each of them served by a different FPM pool, with a different user.

So nothing new; My problem is to create (and start) a new fpm pool without having to reload/restart FPM, wich will cause a (i know, really fast) downtime.

I have wrote a python daemon, that when needed:

  1. Create the system user
  2. Setup the web root of the subdomains
  3. Create the subdomain.conf into my /etc/php5/fpm/fpm.d/ folder

I googled around but i didnt find a way to invoke fpm using one pool, that could be a 'temporary' solution: the main fpm instance run all the pools, evey new one get his own fpm instance, then with a cron i stop and reload fpm every week/month/dontknowyet

If does matter, the server is running on nginx, configured to use unix socket to fcgi, this is my nginx test configuration:

server{
    listen          80;
    server_name     ~^(?<domain>.+)\.test\.local$; # foo.test.local > myapp_foo
    root            /var/www/myapp/subdomains/myapp_$domain/htdocs;
    location / {
        index index.php;
    }
    location ~* \.(gif|jpg|png|ico)$ {
        expires 30d;
    }
    location ~ \.php$ {
        fastcgi_pass    unix:/var/web-sock/myapp_$domain-fpm.sock;
        fastcgi_param   SCRIPT_FILENAME     $document_root$fastcgi_script_name;
        include         fastcgi_params;
    }
}

..and my subdomain-fpm.conf:

[myapp_foo]
listen = /var/web-sock/myapp_foo-fpm.sock

user = myapp_foo
group = myapp_foo

pm = dynamic
pm.max_children = 30
pm.start_servers = 1
pm.min_spare_servers = 1
pm.max_spare_servers = 30

I've tryed to use php5-cgi and/or spawn-fcgi to the new subdomains, but is a bit unstable and often crashes when the concurrency level grow a bit.

Any idea?

Best Answer

I don't believe there is any way to add a pool without restarting/reloading (as per this).

I do think that redundancy is the best approach to this, I do believe, that you might accomplish what you want with reload. Since it is a graceful reload it should wait for the processes to finish.

Essentially, pass the SIGUSR2 signal to php-fpm, and it will gracefully reload all workers + reload the fpm conf/binary.

I believe that amounts to

kill -USR2 `cat $php_fpm_PID`

So, you modify the conf - and reload - shouldn't result in noticeable downtime.

Another option is to run one process per user - you can add new users without terminating existing processes, but the resource requirements are significantly higher (and, for 1000+ users aren't likely to be practical).

One more option is to create a temporary php-cgi process for the new user, and delay reloading the server until later (i.e. low load period, or when you have multiple users to add). This would reduce downtime, but still bring up the new user's subdomain immediately.

None of the above are exactly ideal, and the only practical solution to no downtime would be the multiple server approach.