boutell: (Default)
[personal profile] boutell
Dear extremely amazing Apache geeks,

I don't ask much. I just want PHP to run in one process pool WITH a shared APC cache, and Apache to be in its own process pool as a front end so it can serve static stuff really, really fast, and not pin down a huge Apache process with mod_php in it when it's just serving something statically. Better yet I'd like to use the worker MPM so it's threaded and even more ridiculously fast.

But Apache's allegedly wonderful rewrite of fastcgi, fcgid, does not support passing more than one request to the same server. And PHP's bytecode cache won't share between processes unless they are all started by PHP's built-in fastcgi child process manager. That means vast amounts of wasted memory, which makes the whole thing pointless for me.

So I'm trying to use the real fastcgi, and I have to hand it to Ubuntu for making it pretty easy for me to enable this, all I had to do was turn on the multiverse repository in sources.list and I could enable the "not quite free enough for us" real fastcgi module.

But now I'm hitting new hassles. All I want is a single static fastcgi server, and I can't seem to get that. The fastcgi docs are full of stuff about how to set up dynamic servers for each .php file. Guh? Do not want. I want ONE server (well, one PHP parent process), so PHP stays running and APC stays cached. That's all. Please?

This is my latest attempt at fastcgi.conf:
<IfModule mod_fastcgi.c>
  AddType application/x-httpd-php5 .php
  FastCGIServer /usr/local/bin/php-cgi-wrapper
  Action application/x-httpd-php5 /usr/local/bin/php-cgi-wrapper

And this is /usr/local/bin/php-cgi-wrapper. Note that I'm asking php to spawn lots of kids (the number my RAM can accommodate). That's why I have a wrapper, which hopefully is spawned only once and respawned only if it dies, per the fastcgi docs. This way PHP owns all the kids and they share APC. No wrapper, no shared APC, according to quite a few posters.


# We want the same settings we formerly used for apache mod_php. -Tom
export PHPRC
# We can accommodate about 20 50mb processes. More than that
# will swap, making people wait and locking us out of our own box.
# Better idea: just make people wait to begin with. -Tom
exec /usr/bin/php-cgi

Alas, when I connect I get an interesting 404 Not Found error:

"The requested URL /usr/local/bin/php-cgi-wrapper/index.php was not found on this server."

Thanks for your advice!

Date: 2010-03-03 05:57 pm (UTC)
From: [identity profile]
I know this isn't answering your question, but is lighttpd an option instead of apache? Lighttpd would do pretty much exactly what you want, and it's what I do for some very huge sites. If you really need Apache for something, having lighttpd act as a backend and using Apache's proxy to forward requests to it (or the other way around even) works.

Date: 2010-03-03 07:09 pm (UTC)
From: [identity profile]
I thought about lighttpd, and it's probably a faster front end for the static stuff, but I still have to resolve the issue of PHP + fastcgi + APC if I go that road. Other replies seem to have the magic sauce though we shall see...

Date: 2010-03-03 07:14 pm (UTC)
From: [identity profile]
Lighttpd and fast CGI is really really easy, if you end up trying it.

fastcgi.server = ( ".php" =>
(( "socket" => "/tmp/php-fastcgi.socket",
"bin-path" => "/usr/local/bin/php"

I'm running a site that's getting >75,000 hits/sec going through lighttpd and fastcgi-php. It works *really* well for this.

Date: 2010-03-03 08:03 pm (UTC)
From: [identity profile]
Doesn't sound like you're getting the benefits of APC in this situation. Maybe it's not a framework site with a lot of classes to be compiled?

Date: 2010-03-03 08:08 pm (UTC)
From: [identity profile]
We use eaccelerator in shared memory mode, where all fastcgi processes share a single cache.

APC can work this way too if you tell the web server to just spawn one PHP process (using PHP_FCGI_CHILDREN). That PHP process initializes APC, then spawns a bunch of children so that they all share a cache.

Date: 2010-03-03 06:34 pm (UTC)
From: [identity profile]
Generally speaking, Apache and FCGI don't really play nice. If you really want to use fcgi, you should probably consider nginx or (the now slightly stale) lighttpd.

But in this case, I think your problem is probably that the fcgi handler app actually has to be in your docroot and the path it's trying to use is relative to that. So obviously it doesn't find it.

But with apache, the standard way to achieve what you're talking about is actually to have a frontend apache with limited modules enabled (no php, for example) with mod_proxy doing reverse proxying to the backend server that runs php.

Date: 2010-03-03 06:43 pm (UTC)
From: [identity profile]
Yeah, you need to rename it .fcgi, put it somewhere in your docroot, and add this config:
AddHandler fastcgi-script .fcgi
Action application/x-httpd-php5 /php.fcgi

Date: 2010-03-03 07:08 pm (UTC)
From: [identity profile]
Cool. What happens if someone hits it directly?

Date: 2010-03-03 07:35 pm (UTC)
From: [identity profile]
That works if I add an AddType directive to define .php files as that mime type.

However, it occurs to me that this still doesn't help me if I have multiple sites all heavily using the same PHP classes and I want them to share a single fastcgi/APC pool, because it's specific to the docroot if each individual site.

Is this sadly true?

If so I need to get cracking on a "reverse proxy for PHP, static delivery for non-PHP" setup.

Date: 2010-03-03 07:44 pm (UTC)
From: [identity profile]
I'm not sure if it'll pool the fcgi processes properly or not. I'd say there's a good chance not. The next step would be to manage the fcgi process yourself externally and use FastCgiExternalServer. But honestly, if apache is what you need to use, I would seriously reconsider and go the reverse proxy route.

Date: 2010-03-03 08:00 pm (UTC)
From: [identity profile]
Since the file has to be in the document root, and each site has its *own* document root, I don't see how it can work unless I use external server. Which is unfortunate.

Date: 2010-03-03 08:02 pm (UTC)
From: [identity profile]
Actually, the documentation of the FastCgiServer option suggests it might work the way I want (you can use a leading / to put it outside the document root).

But that's how I wound up with my original error!

Date: 2010-03-03 08:04 pm (UTC)
From: [identity profile]
If you use FastCgiServer, you're just giving it a virtual path and then telling it either a unix domain socket or an ip and port to connect to. You then run your fastcgi app separately as a daemon and it listens on that port/socket.

It's a more complicated setup.

Date: 2010-03-03 08:06 pm (UTC)
From: [identity profile]
Sorry, was thinking about FastCgiExternalServer there.

I think the docs are probably just wrong there. But like I said, fastcgi and apache are one hell of a mess. Pretty much anyone who still uses fastcgi has moved on to nginx by now.

Date: 2010-03-03 09:53 pm (UTC)
From: [identity profile]
Oh, I see.

Sounds like I could probably make that work then, but would be better advised to get apache going as a front end for apache, or nginx as a front end for apache, etc., with the front end serving static files directly.

Cool. Thanks. Will let you know how that goes. I built something not entirely unlike it for hosting.

Date: 2010-03-03 07:08 pm (UTC)
From: [identity profile]
I've been thinking about that reverse proxy approach (possibly with nginx instead of apache in front, as you say). Thanks.

What happens if the fcgi handler app is in the docroot and someone goes to it directly?

Date: 2010-03-03 07:12 pm (UTC)
From: [identity profile]
I would actually use apache on the frontend. Nothing beats it for static file serving, imo.

Should be nothing. Or a 404 error. It'll send the request to the fcgi app, which will get a bit confused since the SCRIPT_PATH points to something that isn't a php script, but it won't do anything dumb like give them the file itself.

September 2014

2122232425 2627

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Oct. 17th, 2017 10:03 pm
Powered by Dreamwidth Studios