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

6,533

Solution 1

Sorry for anwer my own question, but I found this solution that is exactly what I was lookuing for... 3 years ago ;)

Basically, the idea is to have a init script for every pool, with few modifications it work like a charm.

Sorry if I dont repeat the steps here, but really, would just be a copy'n'paste from that link!

Further reading: php-fpm ondemand with systemd

Hope help someone ;)

Solution 2

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.

Solution 3

If you can't afford any downtime the only option is to add redundancy

  1. let some load balancer run in front of 2 (or more) servers.
  2. configure the hot-standby the way you want it
  3. switch over
  4. configure the "new" hot-standby the way you want it
  5. rince and repeat everytime you need a change

EDIT: it is very well possible to run a setup like this with just one piece of hardware. Just add more instances of nginx running on different IPs and create a failover setup between those. If this option makes sense for your use case isn't up to me to decide.

Share:
6,533
Strae
Author by

Strae

Updated on September 18, 2022

Comments

  • Strae
    Strae almost 2 years

    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?

  • Strae
    Strae almost 13 years
    Reading your answer looks like my intention to avoid downtimes is kinda paranoic; Do you think is a normal behavior to restart FPM every night in production? Im wondering if im the only whit this issue
  • Toby
    Toby almost 13 years
    I don't know what FPM is since I don't have nginx in the environment. But judging from the requirements it sounds like you want High Availability but don't quite want to get additional hardware to meet the requirements. I don't think it's a bad thing to restart servers, but it's a bad thing not to design a system that can cope with servers that will be restartet from time to time...
  • Strae
    Strae almost 13 years
    FPM is just a php-cgi manager/wrapper; You're right, im planning an applicatin and, in the first time, it will have very small resources: 1 server for everythings, and a cloud service for database mirroring.
  • Strae
    Strae almost 13 years
    LOL your last suggestion "One more option.." link to a post I wrote in nginx mailing list (I am the authot of that post) ;) Im already using that way (spawn a php-cgi process for new domains and reload fpm one a month/week), but i see it more like a trick than a solution. I'll try the graceful reload.
  • Toby
    Toby almost 13 years
    I'm sorry but with "1 server for everything" you should give up on the "I don't want downtime" requirement. How much downtime will you have from broken disks/ram/hardware as opposed to "How much time do I spend to get some random daemon to not go down for a second". Just buy another box and start designing a failover policy.