I was just reading Derick’s post about the recent get together with Microsoft, and it occurred to me that so far, I haven’t seen anyone mention anything about the single most important problem with running PHP in production on IIS. After a bit of digging, it looks like the problem has been sorted since the initial IIS 7 release (presumably, if you’re still running Windows Server 2003, you’re still screwed on this one), but I’d love to hear from folks who have definitely done this in production.
Let me explain the background first. When you run PHP apps using IIS, you’re much better off using IIS’s native CGI support (slow, but rock-solid as of Windows Server 2003 SP1) or the new FastCGI support that was released last year or the year before (faster, but I haven’t tested it personally under serious stress, as I’ve managed to move back to working exclusively on Linux this year). I’ve tried PHP via IIS’s ISAPI interface, but as that requires running PHP in a threaded environment, I’ve never had any luck in getting it working in a stable manner over the years. Besides, iirc, both Microsoft and Zend recommend running PHP using FastCGI on IIS anyways.
Running PHP via CGI and FastCGI means that IIS has to do the Windows equivalent of fork()ing off PHP processes to do the actual PHP bit. If your box has too many PHP processes running, the box will start to swap. Once a webserver starts swapping, you’ve no chance in hell of keeping up with all the incoming requests, and your websites on that particular webserver become unavailable in a matter of moments. Restarting IIS will clear off all the PHP processes, but if demand remains the same, the webserver will start swapping again very soon and you’re back to square one – your websites back to being unavailable to the outside world.
With Apache and mpm-prefork, mpm-peruser or mpm-itk, you can adjust Apache’s settings to make sure that your server never swaps. With Apache and PHP/FastCGI, you can do this too by adjusting the number of FastCGI processes created. (Although, atm, I don’t recommend using Apache + PHP/FastCGI in production environments).
But how, exactly, do you do this with IIS and PHP/CGI or PHP/FastCGI? The answer can be found in the IIS 7 documentation. It looks like you can limit the number of FastCGI instances per application pool (IIS best practice is to setup a separate application pool per website. IIS’s architecture is nothing like Apache). That’s fine for servers running just the one website, but is there a way to set a similar limit that applies across all application pools? It would be great if there was. And I’m not sure that there’s a way to do this with CGI, if you have problems with FastCGI crashing.
Love it or hate it, Windows Server is the right choice for many firms, and the better PHP runs in a Windows Server production environment, the more opportunities there are for firms and individuals that create PHP apps in the future.