3

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
  • 457
  • 1
  • 8
  • 22

4 Answers4

5

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.

cyberx86
  • 20,805
  • 1
  • 62
  • 81
  • 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. – Strae Jul 06 '11 at 23:34
2

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.

serverhorror
  • 6,478
  • 2
  • 25
  • 42
  • 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 – Strae Jul 05 '11 at 07:43
  • 2
    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... – serverhorror Jul 05 '11 at 18:40
  • 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 Jul 06 '11 at 10:22
  • 2
    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. – serverhorror Jul 07 '11 at 23:25
0

It sounds like you're stuck for resources. Why not run two webservers on the same hardware?

Try something like this:

+---------------+
|    nginx :80  |
|   /     \     |
| :8081  :8080  |
+---------------+

In this way your load balancing service (nginx in this case) can route between two ports. In this way you can take a service up or down as often as you'd like (for updates) etc.

Of course you'd need two FPM pools, two users, etc.

Joseph Kern
  • 9,899
  • 4
  • 32
  • 56
0

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 ;)

Strae
  • 457
  • 1
  • 8
  • 22