Bill Clementson's Blog

Bits and pieces (mostly Lisp-related) that I collect from the ether.

October 2004
Sun Mon Tue Wed Thu Fri Sat
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
Sep  Nov

CL Web Server Options

Sunday, October 17, 2004

There was recently a very good discussion on c.l.l. about the different CL-based web server alternatives that are available. The thread highlighted the fact that there are a wealth of options available if you want to use a CL-based web server; however, the number of different alternatives sometimes tends to confuse people as it is not always apparent what the pros and cons of different options are. I'll try to identify the options that are available and where they might be most appropriate in this post.

First of all, there are 3 broad categories of CL-based web server packages:

  1. Stand-alone Lisp web servers
  2. Lisp servers that interact with another web server
  3. Lisp servers that interact with a Java servlet container
I'll describe each of these categories and the options available for each category (Note: I'll try to list the different options in order of most commonly used product first; however, this is highly subjective and should be considered a rough ordering only as I have no statistics on CL web server usage):
  1. Stand-alone Lisp web servers: This category represents those CL packages that are completely stand-alone and do not rely on another web server product for functionality - all requests/responses and both static and dynamic pages are served up by the Lisp web server. The advantage of this approach is that you have full control over your HTTP server in Lisp and your entire solution can be Lisp-based. In addition, having the httpd in lisp gives you an extra level of control that you can't get in a cross-language solution (for example, your httpd can have a REPL, and any HTTP errors can bring up your CL debugger so that you can fix them dynamically.). Another benefit is that setup is greatly simplified. The disadvantage of this approach is that it is a harder solution to "sell" in many companies and you lose the benefits of using a "standard" solution (e.g. -- skill sets required, utilities available, security, etc.). However, in scenarios where you have greater control over the technical decisions and operations, a stand-alone Lisp web server can be an attractive option. AllegroServe is probably the most widely used option; however, Araneida seems to be getting more interest lately. Here are some of the more common solutions available in this category:
    • AllegroServe: Initially developed by John Foderaro of Franz for ACL, this product was released by Franz as Open Source and subsequently ported to multiple CL implementations. Apparently, AllegroServe can also be used in conjunction with Apache (probably using mod_proxy); however, I have not seen any documentation that explains how to do this (Update-2004-10-26: This page explains how to use AllegroServe with Apache). Marc Battyani has recently speculated about how AllegroServe could be used with mod_lisp and Apache as well.
    • Araneida: Developed by Daniel Barlow for SBCL but ported to multiple CL implementations by Brian Mastenbrook (it now also runs on Win32). In addition to being used stand-alone, Araneida can be used behind Apache using mod_proxy to forward requests.
    • CL-HTTP: Originally developed by John Mallery, the CL-HTTP web server was probably the first generally-available CL web server. It is supported on a number of CL implementations.
    • HTTP: http.lsp is a simple, object-oriented web server developed for CLISP and MCL by Erann Gat. I don't think it is being actively used by anyone; however, it is one of the few stand-alone CLISP options available and it is very small, making it a good example to examine if you're interested in learning how to write an object-oriented web server in CL.
  2. Lisp servers that interact with another web server: These packages rely on Apache (or another web server) for base web server functionality and for some specific content requests (e.g. -- often static pages are handled by Apache but dynamic page requests are passed on to the Lisp process) but provide the ability to delegate to a CL program to run CL application logic as "servlets". The advantage of this approach is that a web server is often already in use in many companies and it would be very difficult to get a company to accept a CL-based alternative instead of the existing choice. In addition, Apache (in particular) is a heavily used and tested web server solution and there are a lot of people working to enhance, optimize and secure it. The disadvantage of this approach is that it is more complicated and requires multiple product (and, potentially, programming language) skills. Marc Battyani (the author of mod_lisp) identifies succinctly the main advantage of this approach:
    "The major interest of mod_lisp is not technical it's a marketing/political one. When you want to make web applications for clients, and get paid for that, the fact that there is a mod_lisp that runs with Apache is often the easiest way and sometimes the only way to be accepted in a corporate environment. For instance lots of big corps (the ones which have money) have developed a secured Linux distribution where you are not allowed to install anything else than Apache. The fact that the application writes things in the Apache logs through mod_lisp makes their sys admin teams (and all their scripts) happy."
    So, here are the different alternative options for Lisp servers that interact with another web server:
    • mod_lisp: An Apache " module" written by Marc Battyani for writing dynamic web applications in CL, mod_lisp uses sockets to communicate with Apache using a custom low-level protocol. According to Marc:
      "mod_lisp does not use a sexp over a socket protocol. It's even simpler than that. The protocol is only key\nvalue\n So that you don't have to call #'read just #'read-line. It's faster and avoids potential security problems. At the beginning it was really like mod_jserv which served me as a model (but mod_lisp is much faster now). At the functional level, mod_jserv/FastCGI/mod_cgid/etc. all do the same thing. They transfer the request decoded by Apache to some outside process. The difference is mostly that the mod_lisp protocol is much more Lisp friendly (in fact it is much more friendly for other languages too ;-) and generally much faster as it keeps an open socket to the Lisp process."
      One of the difficulties with mod_lisp is that there is only a fairly simple example of how to use it included in the distribution. However, Chris Beggy has written a tutorial on "Creating Dynamic Websites with Lisp and Apache" that describes really nicely how to setup and use mod_lisp with Apache.

      The mod_lisp package implements a very low-level protocol that communicates with Apache. There are several add-on packages that build on mod_lisp and make it easier to write applications using mod_lisp (listed in alphabetical order):
      • cl-modlisp: A library written by Kevin Rosenberg, cl-modlisp sits on mod_lisp. It creates a multi-threaded handler for HTTP requests forwarded by mod_lisp and provides a higher level of abstraction than the low-level interface provided by mod_lisp.
      • TBNL: A library written by Edi Weitz and similar to cl-modlisp, TBNL also sits on top of mod_lisp and provides a higher level of abstraction than the low-level interface provided by mod_lisp.
      • UnCommon Web: Marco Baringer's UnCommon Web (UCW) can use either mod_lisp+Apache or portable AllegroServe as the HTTP server backend. UCW's design borrows (in part) ideas from the Smalltalk-based Seaside web application framework as well as ideas from Cocoon and Struts. One of UCW's unique features (at least for a CL web application framework) is the use of Continuations to manage state. I've previously posted about continuation-based web application frameworks and some of the advantages of this approach.
    • mod_proxy: A standard Apache module, mod_proxy can be configured as a reverse proxy, so that web clients connect to Apache, which connects to the Lisp httpd. This is similar to mod_lisp; however, instead of speaking mod_lisp's protocol, Apache and Lisp communicate using http. You get the control of a Lisp httpd, with the ability to also use Apache for serving static content or handling other requests. Araneida (for example) can be used in this manner. 
    • FastCGI: There is FastCGI support for CLISP (through an FFI binding) and CMUCL (through a library). FastCGI works with many different standard web servers including Apache and Microsoft's IIS.
    • Pound: The Pound program is a reverse proxy, load balancer and HTTPS front-end for Web server(s). Pound was developed to enable distributing the load among several Web-servers and to allow for a convenient SSL wrapper for those Web servers that do not offer it natively. Brian Mastenbrook indicates that it works well with Araneida.
  3. Lisp servers that interact with a Java servlet container: A Java servlet container can be used in conjunction with either Apache or a Java web server. The advantage of this approach is that it allows for direct interaction between the Java servlet container (which may be passing some of the requests to Java programs) and a Lisp process.
    • Lisplets: Lisplets were developed by Rich Hickey and provides a lightweight mechanism for communicating between a Java servlet and Common Lisp or Scheme using s-expressions over sockets. It enables easy integration of Common Lisp or Scheme into a Java servlet container, such as Tomcat, Resin, Jetty, JRun, WebLogic, WebSphere and others. In many ways, Lisplets is similar to mod_lisp but provides a better interaction mechanism when dealing with Java servlet containers. Rich describes how it compares with mod_lisp as well as some of the benefits of Lisplets:
      "Lisplets are much richer - session management, session state, application state, user authentication, user roles, portability, scalability etc. And they are to become richer still, as I am writing a Lisp interface to JDBC that will be accessible within Lisplet calls.

      The one clarification I would like to make is that, while Lisplets should be immediately useful to Lisp developers already used to using Tomcat, Weblogic, etc, I think that these servlet containers provide so much utility that they are worth exploring by anyone who wants to do Lisp apps with HTTP interfaces.

      You can use Lisplets with great success and write no Java or JSP code whatsoever. So, even for those who have no interest at all in Java, Lisplets provide a way to leverage huge chunks of multi-platform, multi-vendor, scalable infrastructure code, so you can stop writing plumbing (like Lisplets ;-) and get on with writing the intersting parts of your programs in Lisp."
What about the performance of the various options? Although there is no comprehensive set of benchmarks that can be used to compare the different options (and in some respects, the different options are not directly comparable), there have been a number of "informal" tests done by different people. Marc Battyani did some tests using the Portable AllegroServe home page as HTML data. His testing with LispWorks showed mod_lisp and Apache performing much better than a stand-alone portable AllegroServe on the same hardware. However, Torkel Holm did some additional tests (see here and here) with AllegroServe and ACL and came up with some pretty decent results for the stand-alone CL web server option (although still not as good as Apache with mod_lisp). There were also comments on c.l.l. recently about earlier AllegroServe benchmarks showing competitive performance to Apache in some scenarios. So, although it would appear that Apache with mod_lisp performs better than AllegroServe (at least for some types of web server requests), I suspect that performance alone will not be the overriding criterion for most people when selecting which option to use.

So, the $50,000 question - which one is best? Unfortunately (or, fortunately, depending on your point of view), I don't think there is a single "best" choice. A lot will depend on the company (or individual) that will be using the web server and on the skills of the individual(s) who will be developing and/or maintaining the site. Tim Bradshaw highlighted this in a recent post:
"I think it's always dangerous to underestimate how good a system which has had the amount of battle testing that Apache has can be.

On the other hand, it can also be fairly dangerous to go for some heavily layered system where you have, say, a couple of layers of apaches (caches and then actual front-end servers) forwarding stuff to application servers which in turn may have several layers, and will probably themselves talk to some backend database.  And each of these layers will have some replication for redundancy, of course. This is pretty much what the classic modern e-commerce system looks like as far as I can see.  Each of these layers adds latency; each of them can independently go wrong; logging and debugging is exciting in a fairly bad way; deployment is *very* exciting unless you have a really solid system, which almost no-one does.  I've fairly seriously suggested the single-huge-server approach: it costs a lot but it might actually work..."
I believe that it is always important to choose " horses for courses". I was reminded of this by a recent interview with John Witchel about their development of Red Gorilla:
"If you could go back and change anything, would Red Gorilla still be in business today?

Yes. I would start small and grow as the demand grew. That's what I'm doing now.

Back then we planned to be huge from the outset. So we built this monster platform on BEA, Sun and Oracle. We had huge dedicated connectivity pipes. We had two full racks clustered and fully redundant. We had E450's with RAID-5 and all 4 CPU slots filled, E250s, F5 load balancers...the cost of keeping that system on was enormous. The headcount to keep it humming was enormous too.

The truth is, we could have run the whole company on my laptop using a cable modem connection."
Therefore, although it can be confusing for someone new to CL web servers, the availability of multiple different web server options for CL is really an asset. You can choose the web server option that best meets your immediate requirements with the knowledge that you can take your CL application logic with you if you need to move to an alternative web server in the future. As is often the case with CL, web server selection is a matter of choice - choosing the "best" solution based on your own particular requirements.

emacs Copyright © 2005 by Bill Clementson