Learnosity Logo
Learnosity Banner Image

Railo on Tomcat revisited - mod_proxy

I've been doing some more work on configuring railo to work flexibly in the numerous different environments we work in, and also making it simpler to set up.

To that end I investigated the use of mod_proxy for linking it to apache instead of mod_jk.

Advantages of this approach are:

  • Simple - communications are in plain http
  • Flexible - Load balancing can be easily added at the apache layer
  • Simple - No compiling mod_jk

Here are the basic install instructions for Railo/Tomcat/Apache on Ubuntu.

Download & Install Tomcat

Download tomcat and extract content:

tar xvzf apache-tomcat-6.0.26.tar.gz

Move Tomcat to a more appropriate place:

sudo mv apache-tomcat-6.0.26 /opt/tomcat

Download Railo

Download Railo custom version jars file

Extract and move into Tomcat lib directory:

tar zxvf railo-3.1.2.001-jars.tar.gz
sudo mv railo-3.1.2.001-jars/* /opt/tomcat/lib

Make Tomcat and Railo work together by modifying the web config file:

sudo nano -w /opt/tomcat/conf/web.xml

add the following inside the <web-app> element:

<servlet>
<servlet-name>CFMLServlet</servlet-name>
<servlet-class>railo.loader.servlet.CFMLServlet</servlet-class>
<init-param>
<param-name>configuration</param-name>
<param-value>{web-root-directory}/WEB-INF/railo/</param-value>
<description>Configuraton directory</description>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>CFMLServlet</servlet-name>
<url-pattern>*.cfm</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>CFMLServlet</servlet-name>
<url-pattern>*.cfml</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>CFMLServlet</servlet-name>
<url-pattern>*.cfc</url-pattern>
</servlet-mapping>

add the following inside <welcome-file-list> element:

<welcome-file>index.cfm</welcome-file>
<welcome-file>index.cfml</welcome-file>

Start up tomcat:

/opt/tomcat/bin/startup.sh
Once this is done you should be able to access the railo admin by going to the following URL:

Back to Tomcat

To test our Railo installation, let's create a test site by adding a new virtual host in both Tomcat and Apache. We do this by modifying Tomcat server.xml file (/opt/tomcat/conf/server.xml )
<Host name="testsite.railo" appBase="webapps">
<Context path="" docBase="/vhosts/testsite.railo/www"/>
</Host>

Linking with Apache via Mod Proxy

Ensure the modules proxy and proxy_http are enabled. On Ubuntu this is done as follows:

sudo a2enmod proxy
sudo a2enmod proxy_http
sudo /etc/init.d/apache2 restart

Create vhost

Now we need to create a virtual host entry in Apache as well:
<VirtualHost *:80>
DocumentRoot /vhosts/testsite.railo/www
ServerName testsite.railo
DirectoryIndex index.cfm
   #Proxy .cfm requests to railo
   <IfModule mod_proxy.c>
      <Proxy *>
      Order deny,allow
      Allow from all
      </Proxy>
      ProxyPassMatch ^/(.*\.cfm)$ http://testsite.railo:8080/$1
      ProxyPassReverse / http://testsite.railo:8080/
   </IfModule>

   #Deny access to admin except for local/portforwarded clients
   <Location /railo-context/>
      Order deny,allow
      Deny from all
      Allow from 127.0.0.1
   </Location>
</VirtualHost>

This tells apache to forward all requests for CFM files to the railo instance.

Finally restart apache and railo and you should be good to go.

sudo /opt/tomcat/bin/shutdown.sh
sudo /opt/tomcat/bin/startup.sh
sudo /etc/init.d/apache2 restart

Upcoming book review - Tomcat 6 Developer's Guide

I've just received a copy of the Tomcat 6 Developer's Guide from packt publishing to review.

It's nice timing as I've been working with Tomcat 6 a bit lately and in the new year plan to move some of our production systems over to running Railo on top of Tomcat.

After the extremely busy year Learnosity has had I'm looking forward to reading a few books over the break and coming back in the New Year with lots more ideas and technology to implement.

Learnosity are looking for a Web Ninja at a Mid to Senior level

4 December 2009, Learnosity are looking for a Web Ninja at a Mid to Senior level.

About Learnosity

Learnosity develop cutting edge tools for teachers and educators. Our flagship product Learnosity Voice uses the telephone to enable language students and teachers to interact on a one to one level.

Our service:

  • Makes it practical for students to practice Oral and Aural skills
  • Is efficient and effective for teachers, as they can listen to each student individually at a time to suit them
  • Can be used for homework assignments or “High Stakes Assessments”

We are continuing to grow our core development team and we need another great developer to help us keep up with demand.

We need someone who can:

  • Use Javascript or Actionscript to create great user interfaces
  • Develop highly scalable web applications
  • Cut code with the best in the world

You will also need to be:

  • energetic with a butt kicking attitude
  • ready to create cutting edge web 2.0 apps
  • keen to continue learning new technologies
  • able to have a conversation with non technical people

You'll need:

  • 3 or more years of programming experience
  • Expert in at least on Client side language (Actionscript or AJAX)
  • Expert in at least one Server side language (eg PHP, Java, ColdFusion, etc)
  • Understanding of Object Oriented design
  • Understanding of XHTML and CSS

It would be good if you have:

  • A degree in Computer Science, Engineering or similar.
  • been working with open source tools
  • been playing around with iPhone/Android applications
  • experience with some of Linux/VOIP/SIP/Asterisk/Jabber/XMPP

This is a full time role and you will be working in a casual workplace with flexible hours in the Sydney CBD.

If this sounds like the job for you, email a covering letter explaining why you'll be great and your resume to mark@learnosity.com - no agencies please.

Chinese characters not working cfdocument for PDF exports - fixed

I've just spent quite a few hours grappling with an annoying PDF export issue where the font's were not displaying correctly. This is on a CFMX 7 (7.0.2) on Ubuntu Linux system.

All the DB storage and application was using UTF8 throughout, but the PDF exports were showing nothing when they should have been showing Chinese characters.

To fix this up you need to do the following:

1. Need fonts installed on system:

sudo apt-get install ttf-arphic-bsmi00lp ttf-arphic-gbsn00lp

2. Need fonts installed in CFAdmin

  • Go to CFAdmin and Font Management
  • Select directory /usr/share/fonts/truetype/arphic
  • Select "Add" and you should see 2 new fonts added.

3: CFdocument Hotfix for CF7.0.2

The CFDocument hotfix for 7.0.2 provides some essential fixes and makes this work - Follow the instructions to install: http://kb2.adobe.com/cps/402/kb402093.html

Configure cffont.properties file

The final step is to set the cffont.properties file so that it will check additional font sets for any characters it doesn't know about - i.e. Chinese characters. Each line in the file is like a CSS font-family rule, i.e. it will start at the left and look for the correct font to render the text. I appended the two extra font names to ensure they are checked, so the file looks like this:

defaultbasefont=
dialog=Arial, Helvetica, AR PL SungtiL GB,AR PL Mingti2L Big5
dialog.bold=Arial Bold, Helvetica-Bold, AR PL SungtiL GB,AR PL Mingti2L Big5
dialog.italic=Arial Italic, Helvetica-Oblique, AR PL SungtiL GB, AR PL Mingti2L Big5
dialog.bolditalic=Arial Bold Italic, Helvetica-BoldOblique, AR PL SungtiL GB, AR PL Mingti2L Big5
dialoginput=Courier New, Courier, AR PL SungtiL GB, AR PL Mingti2L Big5
dialoginput.bold=Courier New Bold, Courier-Bold, AR PL SungtiL GB, AR PL Mingti2L Big5
dialoginput.italic=Courier New Italic, Courier-Oblique, AR PL SungtiL GB, AR PL Mingti2L Big5
dialoginput.bolditalic=Courier New Bold Italic, Courier-BoldOblique, AR PL SungtiL GB, AR PL Mingti2L Big5
serif=Times New Roman, Times-Roman, AR PL SungtiL GB, AR PL Mingti2L Big5
serif.bold=Times New Roman Bold, Times-Bold, AR PL SungtiL GB, AR PL Mingti2L Big5
serif.italic=Times New Roman Italic, Times-Italic, AR PL SungtiL GB, AR PL Mingti2L Big5
serif.bolditalic=Times New Roman Bold Italic, Times-BoldItalic, AR PL SungtiL GB, AR PL Mingti2L Big5
sansserif=Arial, Helvetica, AR PL SungtiL GB, AR PL Mingti2L Big5
sansserif.bold=Arial Bold, Helvetica-Bold, AR PL SungtiL GB, AR PL Mingti2L Big5
sansserif.italic=Arial Italic, Helvetica-Oblique, AR PL SungtiL GB, AR PL Mingti2L Big5
sansserif.bolditalic=Arial Bold Italic, Helvetica-BoldOblique, AR PL SungtiL GB, AR PL Mingti2L Big5
monospaced=Courier New, Courier, AR PL SungtiL GB, AR PL Mingti2L Big5
monospaced.bold=Courier New Bold, Courier-Bold, AR PL SungtiL GB, AR PL Mingti2L Big5
monospaced.italic=Courier New Italic, Courier-Oblique, AR PL SungtiL GB, AR PL Mingti2L Big5
monospaced.bolditalic=Courier New Bold Italic, Courier-BoldOblique, AR PL SungtiL GB, AR PL Mingti2L Big5

The cffont.properties file is located in /opt/jrun4/servers/{instance name}/cfusion.ear/cfusion.war/WEB-INF/cfusion/lib on the jrun multiserver version.

5. Restart CF

Once you restart CF you documents should be coming out with their Chinese fonts intact.

I'm sure there are additional fonts to add to get it working natively with all the other asian languages, so I'll add to this as and when I need/discover them. Please feel free to post a comment if you find any more font's that should be added to the list.

CFMX Query Timeout Gotcha

NOTE: I found this blog post in my to be posted ones from 2008.

While doing some load testing a while back we came across a strange error while simulating the load that we were expecting. The simulated load had a large first peak, followed by a quieter period, followed by some more peaks.

During the load test we noticed a few query errors that we had never seen before, they related to the query connection timing out.

It turns out that the way CF times out datasource connections is slightly quirky as described below:

The other timeout setting in the CF Admin datasource detail page is just labeled as Timeout, with a paired setting for Interval. This timeout value is how long a connection should be idle before it is removed. So if a connection goes unused for this period of time, then the next time ColdFusion checks that connection it will be removed from the pool. The frequency that ColdFusion checks the connection idle time is set by the Interval setting. The default for the Timeout setting is 20 minutes and the Interval is 7 minutes, so every 7 minutes ColdFusion will check connections for that datasource and remove connections that have been idle for 20 minutes or more. The number of connections idle connections removed from the pool at each interval is hardcoded in ColdFusion to just five. Say you have 20 idle connections hanging around in a pool, this would require at least 28 minutes to be cleaned up.

Timeout (min)
The number of minutes that ColdFusion MX maintains an unused connection before destroying it.
Interval (min)
The time (in minutes) that the server waits between cycles to check for expired data source connections to close.

Cheers, Mark

ColdFusion per vhosts mappings

One of the features of CF8 that I was most interested in and most let down on was per application mappings. The reason I was so keen was so that we could keep core library application files out of the webroot for additional security, but still have different versions of the same codebase. I.e. some sites running farcry3 some running farcry5 for example.

This didn't transpire and so now we use the following technique on apache to map the folder in and then lock it down with apache.

In the vhost section add the following:

Alias /farcry /path/to/non-webfolder/farcry
<Location /farcry/>
Order Deny,Allow
Deny from all
</Location>

Note: it is important that there is no /farcry mapping defined in the CF Administrator or it will override this setting.

What the above does, is to map in the non-web accessible folder, but then locking it down so it cannot be browsed from the web. This seems pointless but CF can still see the files and correctly resolves the paths even though they are secure from the outside world.

This then allows us to version our sites independently - i.e. if we want to upgrade from farcry 5 to 5.1 we can do it one site at a time, instead of having to test them all at once.

Note - Railo already has per vhost mappings which solve the same problem as this. But if you are on CF7 or CF8 then this works a treat.

Cheers, Mark

Railo Useful links

I've been doing some research on Railo with a view to moving some of our sites to using it. I've found a few useful links along the way:

My evaluations of Railo are so far so good, with performance being one of the key issues and for our application I've seen performance 30% faster than CF7 and 25% faster than CF8.

If I find any major issues or benefits I'll post them here.

Cheers, Mark

Identifying which queries to tune with MSSQL

I've been doing some more work tuning and CF/MSSQL application and during figuring out which parts of the system is doing the most work (and hence a good candidate for tuning) I came across this gem which will show stats on the most run queries in the cache.

SELECT TOP 20 SUBSTRING(qt.text, (qs.statement_start_offset/2)+1,
((CASE qs.statement_end_offset
WHEN -1 THEN DATALENGTH(qt.text)
ELSE qs.statement_end_offset
END - qs.statement_start_offset)/2)+1),
qs.execution_count,
qs.total_logical_reads, qs.last_logical_reads,
qs.min_logical_reads, qs.max_logical_reads,
qs.total_elapsed_time, qs.last_elapsed_time,
qs.min_elapsed_time, qs.max_elapsed_time,
qs.last_execution_time,
qp.query_plan
FROM sys.dm_exec_query_stats qs
CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) qt
CROSS APPLY sys.dm_exec_query_plan(qs.plan_handle) qp
WHERE qt.encrypted=0
ORDER BY qs.total_logical_reads DESC

I found it in this excellent article on optimising MSSQL

The times that are returned from the queries are in micro seconds as documented on msdn.

Cheers, Mark

Clear MSSQL Query Caches

Found this useful little snippet for when you are load testing MSSQL Servers.

You can use it to clear the query cache - to ensure you are starting from a level playing field. Or if you are tuning queries in a application and want to ensure they are not cached run it before each run:

dbcc freeproccache
go
dbcc dropcleanbuffers
go

Cheers, Mark

Non-case sensitive filesystem on Linux - HOWTO

I was setting up a ColdFusion web application on my dev machine and ran into lots of errors because of the case sensitivity of Linux (which i was using) versus the non-case sensitivity of windows (where the application was developed).

I had a quick look to see if I could fix it up but quickly figured out that there were too many occurrences and so it was likely not worth fixing up at this point. To that end I set up a loopback vfat filesystem so that I could have a directory on my machine mounted as non-case sensitive.

Note: this is not recommended for production systems - but is a handy fix for a temporary development problem.

Create a virtual disk

dd if=/dev/zero of=virtual.dsk bs=1048576 count=150

Format it

mkfs.vfat virtual.dsk

Mount it

sudo mkdir /mnt/vfat
sudo mount virtual.dsk /mnt/vfat -t vfat -o loop,owner,group,umask=000

You can set this up to mount every time by putting the following line in your /etc/fstab

/path/to/virtual.dsk /mnt/vfat vfat loop,owner,group,umask=000 0 0

Note - the same trick works on OSX in reverse. I.e. if you are developing on a mac, but deploying to a linux production environment you can create a virtual disk with a case-sensitive filename, which will mean that any case sensitive issues get picked up on your dev machine, and not on your production/staging machines.

Cheers, Mark

More Entries