fREWdiculous!
8 Mar
In February of 2008 I figured out how to switch our servers from IIS to Apache. The main reason I did that was because if you print to STDERR in Perl while running under IIS the server would crash hard. In general it just took some research and motivation. All was well with the world…. For six months.
After switching to Apache we needed a way (previously accomplished with PerlEx from ActiveState) to run certain scripts persistently. I did some research and discovered that using mod_perl in win32 was feasible and you can indeed turn it on for parts of your site. Yet again, all was well with the world.
Unfortunately as time passed and we started using a deeper stack of Perl (we originally were just using DBI, the Perl database layer, and sometimes using Template::Toolkit, one of the most major Perl templating systems,) we started seeing Apache crashing or leaking memory. Unlike IIS crashes the cause and time till crash was unpredictable, but after some work the issue was found and fixed.
During this time I and all but one of my coworkers switched to the most excellent Strawberry Perl, the Windows Perl one might say. Logging in to the servers to install packages with PPM quickly soured for me and I spent probably 3 days worth of my time (half of which was unpaid!) trying to find a way to use Strawberry persistently. If we could use Strawberry on the servers installing dependencies would boil down to
1 | cpanm --installdeps . |
But I couldn’t seem to get mod_perl to build, mod_fcgid and mod_fastcgi were both unworkable (for me anyway,) and I couldn’t get lighttpd + FastCGI to work. So I gave up on that endeavor.
Nearly four months have passed since the crashing Apache issue was originally solved and just days ago we deployed our first Catalyst project (we have two more in the pipeline now!) We deployed onto mod_perl and Apache on Windows. I would never recommend deploying onto Windows, but I also realize that there are business reasons to do so and sometimes it’s just what you have to do.
And all was well with the world…for two page requests. It turns out that somewhere in our stack of Perl, Apache, mod_perl, and Windows there was an issue that made the server consistently crash after nearly every other request. I did some research, and even built up a replica of our deploy on my machine (linux) to see if the issue was generic mod_perl. If it were a problem in Linux it would be much easier to get free help from the community, but alas, it ran perfectly on my machine.
While I was driving to a friend’s recently I had a thought; why not just use the Catalyst development server or some other Perl based server and just proxy to it with Apache? Heck, it’s actually very similar to one of the recommended ways to deploy Catalyst in the Catalyst book.
Before I get into the details of this I need to point out that we are not using HTTP::Prefork, thanks to Windows. If you have a large site you really should not use Windows, for numerous reasons. That was the conclusion that my boss and I came to anyway.
First off, here is the Apache configuration we ended up with:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | ServerRoot "C:/Program Files (x86)/Apache Software Foundation/Apache2.2" ServerName "ourapp.foo.com" Listen 80 LoadModule alias_module modules/mod_alias.so LoadModule deflate_module modules/mod_deflate.so LoadModule expires_module modules/mod_expires.so LoadModule env_module modules/mod_env.so LoadModule log_config_module modules/mod_log_config.so LoadModule mime_module modules/mod_mime.so LoadModule setenvif_module modules/mod_setenvif.so LoadModule proxy_module modules/mod_proxy.so LoadModule proxy_http_module modules/mod_proxy_http.so LoadModule proxy_balancer_module modules/mod_proxy_balancer.so ExpiresActive On ProxyRequests Off <Proxy balancer://my_cluster> BalancerMember http://127.0.0.1:39564 BalancerMember http://127.0.0.1:39565 </Proxy> ProxyPass / balancer://my_cluster/ # we don't use this because our app is a single page # javascript application # ProxyPassReverse / balancer://my_cluster/ DocumentRoot "C:/myapp/root/" <Location /static> SetOutputFilter DEFLATE SetEnvIfNoCase Request_URI \.(?:gif|jpe?g|png)$ no-gzip dont-vary SetHandler default-handler </Location> LogLevel warn LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined LogFormat "%h %l %u %t \"%r\" %>s %b" common CustomLog "logs/access.log" common DefaultType text/plain TypesConfig conf/mime.types AddType application/x-compress .Z AddType application/x-gzip .gz .tgz |
So basically all we do in this configuration is have Apache serve the static files and then proxy the requests to a couple of catalyst dev servers. I used Srvany.exe and a couple of .bat files to start the catalyst dev servers. It works much better than using mod_perl, and each server sits at about 90M a piece. If we ended up getting a huge site and for some strange reason needed to keep our outfacing server windows, we could actually serve the catalyst parts on a linux server and have apache proxy to those, so it scales very nicely.
Anyway, here’s to the next 6 months of serving!
10 Responses for "The Rise and Fall of mod_perl"
I’m glad to see you resolved your issues.
I understand the that Engine::HTTP::Prefork doesn’t work on Win32. However, we also got an Engine::Plack, and Plack itself has a variety of server backends, like Stardust, Twiggy, which are probably less unix specific than Prefork and could have a better chance of running on Windows, without having to use Catalyst’s development-only server.
I could be wrong here but I thought that Stardust was a port of Unicorn, which is [apparently] decidedly unixy [1].
[1] http://tomayko.com/writings/unicorn-is-unix
[...] talks about using the catalyst dev server on Windows / Strawberry Perl due to problems with building mod_perl. Interestingly one of the [...]
I’ve really enjoyed reading your pieces related to CGI-ish frameworks in Perl, and your take on exception handling. It’s been very helpful as I look at various options myself, running into similar concerns.
Thanks for taking the time to do this, and in a way that reveals your exploration and questions along the way. And yes, the Perl people don’t blog enough, it seems.
I’ve experienced different sorts of issues with mod_perl2 on Windows, and after getting everything resolved I found that some of the problems came back on a 64-bit Windows 7 system.
Specifically, the problem I’ve not been able to resolve is to get DBD::Pg to load at all, even in Perl from the command-line (so I know it’s not a mod_perl2-specific issue).
On Unix (I use NetBSD primarily for all my production servers), all these annoying little problems that crop up at various unexpected times simply never come to light on Unix.
You might consider running VirtualBox.com on your Windows system to get the benefits of the Unix side of things running there. Heck, you can even mount an SMB resource into the web portion of your virtualized Unix system if you like, and then your developers won’t even notice that you’re transparently proxying all your .pl files to a virtualized system.
The solution you found is interesting, especially because of the scalability factors. Thanks for posting such an interesting article.
I guess I ran into similar issues, when I was using a mod_perl that was originally compiled for ActiveState and use that with Strawberry.
Since some time now, kmx managed to compile mod_perl with the StrawberryPerl build tools and this seems to work reliably, for me at least. You might want to check this out:
http://strawberryperl.com/package/kmx/mod_perl/
Mike B: Thanks for that helpful link. I see that there are pre-compiled Windows binaries for mod_perl2 there, along with libapreq2 (which I also use with my mod_perl2 projects).
I’ve played around with Strawberry Perl a few times, but couldn’t get mod_perl2 compiled before. Now that these pre-compiled modules available, I can start to look at Strawberry Perl seriously.
***UPDATE***
There’s a new release of mod_perl2 now (just last month in February 2011, I believe), which hopefully resolves these Windows issues.
[...] In the spirit of one of my other posts I’ve decided to chronicle my path with at least a couple event loops. [...]
***UPDATE***
I just read some news of another release candidate now in April 2013, this time for mod_perl2 v2.0.8. There have been multiple incremental updates and patches since my March 2011 posting, so it seems that mod_perl2 continues to be active.
Also, I’m still developing new web sites using mod_perl2, and it’s working well for supporting new advances in web technologies.
It’s so wonderful that mod_perl2 continues to be developed. Thanks to all who are maintaining and improving mod_perl2, your work is greatly appreciated.
Leave a reply