Fixing random PHP crashes on IIS 6 recorded as PHP memory leaks
September 30th, 2007
I recently came accross a serious problem that seems to be relativly un-documented bar other people raising bug tickets on bugs.php.net.
If you are having problems with PHP on IIS where you get a couple page views from your application then you just get a blank screen? If so then read on….
There was nothing in the Event Log for applicatons or system, so I tried re-starting IIS; with no luck. This particular problem seemed to be happening tottaly silently with absolutly no record anywhere (php_error.log et al). I them re-started the whole box, and upon boot up I checked the Event viewer and there was an entry in the application log detailing a memory leak in “php.exe”. So, a memory leak I thought, great…
Trawling the web I then found a document detailing how windows server kills off processes it deems to be at all ‘dangerous’. It does this silently (which is unbeliviably handy) and fitted with the problems I was encountering. Going on the presumption that it was indeed killing the PHP process (or more specifically the worker threads) I turned to the application pool configuration… And broke out alll my PHP apps into a seperate application pool. When they stoped working, I could just recycle the pool and they worked again for two requests. NB: Ive seen other peoples configurations take a couple more than 2 requests so bear that in mind if your having this problem.
So, by now I knew that it was windows killing of the process causing the problems, however I wasnst sure how to fix it.
I looked at the loaded modules in my PHP.ini, and found that removing all non-essential modules solved the problem. I then brought in one by one each PHP module, and found that it was not actually the modules them selves that were leaking, but just the order in which they were loaded causing the problem.
Yes, thats very crap. I couldnt find a more elegant solution to this, and I really hope this helps someone as I must have wasted a day of my life trying to solve this bloody problem! lol
Making IIS play nice with Apache on windows server 2003
September 21st, 2007
Now, being a unix man through and through, I do see the irony that my first blog post is about winows; such is life!
Anyway…
Typically IIS and Apache do not work well together at all, as IIS hogs all IPs (both physical and ARP) on any given win 2003 machine which is why when trying to run anything else on port 80 on any IP can be a total nightmare.
I recently had to do an install on a win 2003 box where the client wanted to support some of their legacy ASP applications, PHP, but then allowing scope in the future to run Rails, Seam and Django applications. This means running:
- Apache with mod_python (for Django)
- Apache proxying to mongrel (for Rails)
- JBoss for Seam (EJB configuration)
- IIS for ASP/ASP.NET
IIS has no real ability to proxy to other backends (which in this instance we need due to the rails requirment) in the way Apache 2.2 does, so I chose to run Apache out front binding to one of my avalible 5 on this machine. Apache then uses proxy pass (or proxy balencer for rails) to pass PHP and ASP requests to IIS. No doubt there are people out there who would have chosen to run PHP on Apache, but due to the way the legacy applications were written, PHP and IIS were already installed so it made sense to leave it “as is” - no need to make more work for myself, especially as i only had one night to do the install!
Step 1
IIS however requires a bit of wrangling before we can get on with the install of Apache…Make sure you have your win 2003 install discs with you; as you’ll need to install the support tools (found in support > tools on the cd). It is however possible to do this without the support tools, but it involves hacking around in the registry. Once you have the support tools installed, were going to be making some changes to let IIS know what exact IP address it can bind too. If you have the support tools installed you can the use the httpcfg tool like so (note: if using RDP you might need to logout then login to get support tools on your PATH)
httpcfg set iplisten -i 555.555.555.555 (where this is your IP address)
If you do not have the support tools (or your just too lazy to dig out that disc from the depths of the server room) you can edit the following registry key:
HKEYLOCALMACHINE/SYSTEM/CurrentControlSet/Services/HTTP/Paramaters in there is a paramater called ListenOnlyList from which you can edit with the list of IP’s IIS should listen to.
Once youve done that, restart IIS as usual from the MMC.
Then you can do a netstat -ano to see that IIS only binds to the IP you set. Simple.
Step 2
Next up you need to download apache. I went with apache 2.2.4 without SSL, which i grabbed from here
Run the installer, and make sure you choose on port 80 as a server for all users when installing.
Once apache is installed, you’ll need to set up port listening and IP address binding. This is a well discussed topic in the apache manuals so I wont labour the point here. See the apache docs.
I then set up some virtual hosting to hand my requests off to IIS. Granted, I could have done this with rewrite rules for .asp extensions, but I chose to proxy it on domains, due to my particular circumstances. Heres what my virtual host looks like:
<VirtualHost *:80>
ServerName www.domain.co.uk
ServerAlias domain.co.uk
ProxyPreserveHost On
ProxyPass / http://172.16.1.11:3000/
</VirtualHost>
(Where my site definition within IIS was running on port 3000)
Step 3
I then downloaded Python and installed it. And then I followed the very good instructions on setting up mod_python on google groups
Step 4
Do the usual rails install bits and bobs - this is so well document I wont pollute the blogsphere any more :)
Step 5
Java time…. Download and run the JEMS installer. At this point we only want to install JBoss on the box with an EJB configuration; it will take a couple more posts to go into the configuration required to get JBoss Seam up and running so we shant discuss that here.
Summary
Thats pretty much it. Its not too difficult, you can proxy off to any service you want to (within reason) and you can have all the latest and greatest web serving technologys happily co-exsisting!