February 2015

Gavin Pickin

Pros and Cons of Mod_CFML with Tomcat for Lucee

Apache, CFML Server, Lucee, Migrating to Railo, Server Admin, Tools and IDEs

I have been talking a lot lately about different configuration options, since Lucee is the hot new thing since ‘POCKETS’. Everyone has been asking about best ways to work with Tomcat, versus other servlet containers, and so I have been playing… and have released a few posts on the matter. Every time I post anything on Tomcat, I always get asked about MOD_CFML, so I thought it was about time I wrote a post on what I knew about it, as always, I am not the expert, I am just sharing some of my knowledge, hopefully others will share too, and we can all learn.

What is Mod_CFML?

Mod_CFML is a connector tool to help IIS and Apache communicate with Tomcat and eliminate some of the additional overhead for Server Admins, by using a Tomcat Valve. It essentially passes information from Apache to Tomcat the first time a new “WEBSITE” is accessed since the last time Tomcat (which runs Railo/Lucee) was started up. It passed through the Server Name and the WebsiteRoot so Tomcat can setup a Virtual Host, similar to how Apache has its own Virtual Hosts. Mod_CFML is a community driven project, and I know Vivio’s Jordan Michael’s name is in the perl file, and he is very helpful regarding this subject on the google groups in Lucee, and previously with Railo.

Why do we need something like Mod_CFML?

One of the biggest issues we have with using Railo and now Lucee, has been the way it connects to Tomcat. In the good old days, you would install ColdFusion and whatever folder you setup IIS or your web server of choice, the web server would handle static content, and the ColdFusion engine would just work with the dynamic content. These days with Tomcat, being its own fully fledged Web Server, it isn’t as simple to setup, especially if you want something like Apache to still do the front, we have to PROXY that information through to Tomcat, so it can take care of the CFML requests, and send the info back to Apache (or IIS). Tomcat needs certain information, so it can be setup and ready to handle those requests, so we have several approaches to solve this problem, this is one of them.

Tomcat is known to be VERY SLOW on startup… ridiculously slow, and the most Hosts and Context, the more unpacking work that needs to be done, the worse it gets. Anything you can do to save yourself a restart of Tomcat was always a HUGE plus.

I have some information on speeding up a Tomcat 7 and Tomcat 8 startup, which will help most of us who use Tomcat for CFML engines only. I got my Tomcat startup down from 60 seconds to 3 seconds, with only 10 sites. With 50 sites, you could be waiting for 5-6 minutes normally, but we can reduce the startup to only a few seconds. I will be posting that very soon, so please check back for that blog post. Tony Junkes also released some information on speeding up your Tomcat 8 server too.

What are some of the other solutions?

  • We can manually create a HOST element in the Server.xml of Tomcat, and restart Tomcat.
  • We can setup an XML INCLUDE to hold manually created HOST elements which is included in Server.xml each time Tomcat is restarted. I have posted a few blogs on this approach, if you are doing manually created host elements, this is much easier than dealing with the XML directly. Read this post called Adding Goodies to Server.xml to make life easier with Lucee.
  • We can use a Catchall HOST in the Tomcat Server.xml and by passing relative path information in the ProxyPassMatch, Tomcat can serve the files back to Apache, with minimal difference. This is a solid practice for dev, but all of your sites are sharing one Context which is not recommended by J2EE standards, and it does affect the CGI Environment Variables. Although its not too difficult to reset those in your Application.cfc, with a / mapping for example. I wrote about this approach just a few days ago, one of the big pluses, is you do not have to restart Tomcat. Read Apache and Tomcat - Save yourself the XML Editing - No more Tomcat restarts

Why should I consider using Mod_CFML?

  • It creates the HOST record on the fly, you do not need to create it manually, as soon as a request to an Apache site is made, that proxies the request over to Tomcat, using the Valve setup, it will setup a new Host, and a new Context for that host, install the WEB-INF folder and your new site is up and running.
  • Unlike the Catchall Host approach above, it creates its own Context, so the site will get its own WEB-INF file and its own Web.xml, and it is compartmentalized properly, which is a big plus, especially in production.
  • It saves you a lot of messing with the conf files.
  • If you want more more “CUSTOMIZED” host files, you can still add them. Tomcat will use a Manually created Host element first, and only fall back to the Valve to create a virtual one if it does not exist. That is a very big plus I think. It means I could use Mod_CFML to get a site up and running quickly, using a Virtual Host element ( in memory) and then you can always update the Server.xml (or an file included in the Server.xml) for Tomcat’s next restart

What are some of the possible negatives of using Mod_CFML?

I’ll prefix this with, after playing with it, quite extensively, I was really impressed with it… so these are negatives, but every method has its negatives.
If the first request to Tomcat, quickly after its startup, is to a Host that does not exist, and the MOD_CFML has to use the Valve to create it, it sometimes spits out a blank page. If you hit a site with a Host element in the Server.xml, it seems to wait then process. The valve must be later in the startup process than the normal Hosts being loaded into memory… so if the Valve is not ready, it just white screens on you, refresh and it will load as expected.

The first request to Tomcat for the Host that needs to be created, takes about 10-12 seconds to complete its work. If you intend to never create manual host elements for your sites, and rely on MOD_CFML to create them every time that Tomcat is restarted, you need to be aware that it takes a significant amount of time for that first request. You might want to consider a script that hits all your sites after a restart, or periodically, or something, to make sure its not a customer hitting it first. Once it is created, it flies… so its just the first request.

If you are thinking, it takes 10-12 seconds per site anyways, using mod_cfml will help the startup time… you are partially right… but normally, the startup time is affected by approximately 5 seconds per site (before the performance improvements coming in my next post) plus 3-4 for the first connection to your site. If the first request is to a non existent Host, and its after the Valves are ready for this type of request, it seems to take the 3-4 seconds for a first connection to the site, plus the 10-12 seconds.

When Tomcat is restarted, all of these In Memory Hosts are lost, and they are only created again when needed. This also means you cannot create special rules, like additional Aliases Virtual Directories/Context etc. One plus with that though, if you don’t have 300 Host elements for sites that are no longer used, or rarely used… so that might be a performance saver too. Although, I’m not sure how Tomcat deals with sleeping sites etc… it might explain the 3-4 second INITIALIZATION it seems to go through on “FIRST” connects, even to existing Host elements. Another note, if you need more than the Host Name and the WebRoot in the Host/Context, you can always manually Add a Host element for future use… which I think is awesome.

Another thing is, if you messed up your Apache Conf, and had the right host name… but had the wrong folder,… updating the Apache conf and restarting Apache will not FIX the Tomcat Host. It is only set on FIRST CONNECT so you would have to restart Tomcat, otherwise, you would be serving static files from one directory and cfml from another, and trust me, that will not work out so good for you. 
I might be wrong about this, but my testing found this to be true. If anyone knows of another way to force the valve to remove the host and add the new one, please let me know… I couldn’t get it to work.

Why does Gavin not use it currently?

This is a good question. I was always advised to manually create the Host element and contexts, and using the built in AJP with ProxyPassMatch worked, why did I need the overhead of a Perl Module. It has very load overhead apparently, and I guess if I ever get that much traffic for any of my servers, I’ll be doing well enough to have a Server.xml DUDE on staff :)
Also, with the complicated mess of trying to run CF9 CF10 and CF11 with multiple versions of Railo and a Railo Cluster, and now Lucee, I didn’t think it would be flexible enough to handle some requests, while leaving others alone. I assumed I had to leave the Perl config in the body of the httpd.conf file, and not in each VirtualHost, but I found out I could in fact include it on a per VirtualHost to VirtualHost basis. I also found out, that having that Perl conf in my main httpd.conf file, it didn’t affect my multi-engine setup, I just tested it, with CF9, CF10, CF11, and Lucee… all the code all in apache all at the same time… seemed to work just fine.

Is Gavin going to start using it?

Absolutely… most of the reasons I had for not using it have changed, or I misunderstood to begin with. Now I have tested it more thoroughly, I have a much better understanding, of the pros and cons, and this is how I’ll be using it and why.

  1. No restart - I can get up and running with a new site, and if I’m adding it, I’m testing it, so the first load, will be me… I can wait a few seconds.
  2. I can manually create a Host element and Context for all the speed and flexibility long term, after Tomcat restarts, it will kick in.
  3. I can use it with all my crazy engine configurations and it doesn’t seem to have any issues.
  4. Its easier than the relative pathing in my apache conf, and you do not have to worry about all of the quirks of using relatives paths

Thanks to everyone who kept asking me about it. It made me really dive in and see what was “different”. I think I have given it a pretty good test run… and found a lot of pros and cons, of this solution, and the others.

If I missed anything, or anything is not accurate, please let me know.

Next post, will be how to drop your Tomcat startup time from minutes to seconds.

Next problem to solve, how the hell can we get ErrorDocument 404 /404.cfm pass all the information we need to make a useful 404.cfm. Apache usually passes Headers to your 404 file is it is on the same server, and getting this to translate over to Lucee is troublesome. 
We have been playing with this a bit, we’re trying to not introduce another complication into the problem, if you want to chime in, join the conversation here.
Lucee Google Group Discussion -!topic/lucee/AAwD8wX1k18

by Jamie Jackson
02/12/2015 12:43:55 PM

You came around. ;-)

Thanks for the follow-up. Looking forward to your post on speeding up Tomcat startup.

by Gavin
02/12/2015 03:28:04 PM

Yes I did, I swear there was conflict / complication with other servers... but maybe that's no longer the case, or I was confused. I will look for that at some point though lol.

We will use it to help with getting a site setup quickly, but with the slow first request, we will manually write the Host elements for long term use to eliminate that 10+ second delay.

by Jamie Jackson
02/13/2015 07:36:25 AM

The one thing that's been bugging me is that in my local environment (which runs in a Vagrant-managed VM), I sometimes get the "Welcome to the Railo world!" default site instead of the intended site. I finally got around to asking about it:

Blog Search