nginx and Perl: FastCGI vs reverse proxy (PSGI/Starman)

aaa90210 picture aaa90210 · Oct 23, 2010 · Viewed 8.8k times · Source

A very popular choice for running Perl web applications these days seems to be behind a nginx webserver proxying requests to either a FastCGI daemon or a PSGI enabled webserver (e.g. Starman).

There have been lots of question as to why one would do this in general (e.g. Why use nginx with Catalyst/Plack/Starman?) and the answers seem to apply in both cases (e.g. allow nginx to serve static content, easy restart of application server, load balancing, etc.)

However, I am specifically interested in the pros/cons of using FastCGI vs a reverse-proxy approach. It seems that Starman is widely considered to be the fastest and best Perl PSGI application/web server out there, and I am struggling to see any advantages to using FastCGI at all. Both approaches seem to support:

  • UNIX domain sockets aswell as TCP sockets
  • fork/process manager style servers aswell as non-blocking event-based (e.g. AnyEvent) servers.
  • Signal handling/graceful restart
  • PSGI

Similarly, nginx configuration for either option is very similar.

So why you would choose one over the other?

Answer

jpetazzo picture jpetazzo · Mar 5, 2011

A reverse proxy setup (e.g. nginx forwarding HTTP requests to Starman) has the following advantages:

  • things are a bit easier to debug, since you can easily hit directly the backend server;

  • if you need to scale your backend server, you can easily use something like pound/haproxy between the frontend (static-serving) HTTP and your backends (Zope is often deployed like that);

  • it can be a nice sidekick if you are also using some kind of outward-facing, caching, reverse proxy (like Varnish or Squid) since it allows to bypass it very easily.

However, it has the following downsides:

  • the backend server has to figure out the real originating IP, since all it will see is the frontend server address (generally localhost); there is almost an easy way to find out the client IP address in the HTTP headers, but that's something extra to figure out;

  • the backend server does not generally know the orignal "Host:" HTTP header, and therefore, cannot automatically generated an absolute URL to a local resource; Zope addresses this with special URLs to embed the original protocol, host and port in the request to the backend, but it's something you don't have to do with FastCGI/Plack/...;

  • the frontend cannot automatically spawn backend processes, like it could do with FastCGI for instance.

Pick your favourites pros/cons and make your choice, I guess ;-)