by Jack

Load balancing IIS to Apache Tomcat

Recently I discovered that the ISAPI redirector doesn’t work quite as I thought. If you need to load balance traffic between a few IIS servers, to a larger body of Tomcat App Servers (lets sat 2 IIS servers, 10 Tomcat servers), then the ISAPI redirector doesn’t do a great job. Well, it does if you use the ISAPI load balancing.

However, the application I’m using doesn’t handle errors quite right at the app layer. So, Tomcat will keep responding with a web page which has an error on it, however, the header indicates that it is a well formed web page, it’s not a 404 or whatever.

So instead we want to route the traffic through a clever load balancer, say and F5, and get it to inspect a page’s contents at regular intervals to determine if it’s responding correctly.

Great! However, the IIS ISAPI redirector opens one persistent connection to the database, so it only ever gets directed at one Tomcat server. You can add multiple threads to ISAPI, but then you need to create a huge burden.

There are two possible solutions.

  1. Use ARR – In IIS you can use URL rewite to redirect the web content through to Tomcat on port 8080 – this is what we do on It also means the traffic is stateless HTTP, so can be load balanced just fine.
  2. BonCode Tomcat Connector looks promising. It’s a replacement for the ISAPI connector. It uses .NET and creates up to 200 threads by default to connect to Tomcat. So it should give the impression of load balancing like Apache httpd does.

If using ARR the following sets up the redirect rule. This is in it’s simplest form, you can use Web Farms as well to create server groups for Static Content and Tomcat servers:

     <rule name="Static Content" patternSyntax="ECMAScript" stopProcessing="true">
         <match url="sipr/(.*\.(js|css|gif|jpg|jpeg|png|htm|html|php))$" ignoreCase="false" />
         <conditions logicalGrouping="MatchAll" trackAllCaptures="false" />
         <action type="Rewrite" url="https://site_url_or_static_web_farm/{R:0}" />
     <rule name="Tomcat Content" enabled="true" patternSyntax="ECMAScript" stopProcessing="true">
         <match url="(.*)/app_name/(.*)" />
         <conditions logicalGrouping="MatchAll" trackAllCaptures="false" />
         <action type="Rewrite" url="http://lb_tomcat_vip_or_dns:8080/{R:0}" />

The first rule redirects any image/js resources etc that have a URL under the redirected content. The second redirects to 8080 on the Tomcat server.