I’ve had my eye on the advances that are being made in the Comet arena for a while now, but it was only this past weekend that I finally sat down and used it for a project. In doing so, there was a particular configuration problem I needed to address, and that was…uh, addressing.
Introducing Comet to an existing architecture assumes there is already a web server in the neighborhood, and that it is, in one way or another, receiving traffic from port 80. Due to the fact that many site visitors will likely be positioned behind a firewall unwilling to accept connections on ports other than 80 or 443, we also need to get our Comet server running on port 80 as well. This normally wouldn’t be much of a problem at all, unless you don’t want to fork over the money for an extra IP address. I don’t & I didn’t. So let me show you how I did so.
As I eluded to above, to solve this problem of running two services on the same port in the same server environment you would normally have two different IP addresses assigned to the same front-end server. This is typically a load balancer or firewall, but these could also be running on the same machine as a web server and Comet server. The load balancer would then accept requests for x.x.x.1:80 and send them to the web server, and requests for x.x.x.2:80 would go to the Comet server. However if we only have one IP address that means we have to route requests based on a higher network layer, the Application Layer (7). Now we route by domain name.
In fact, that is something most web servers can handle using name-based virtual hosts. “So why not set-up Apache to reverse-proxy requests to the Comet server?”, you ask. Well, that would work. The reason Comet servers even exists though, is because web server connection threads are too heavy to support the level of concurrency Comet requires (for a decent number of users). This is where the “high performance” part comes in. HAProxy is a fantastic high performance layer 7 load balancer. Using HAProxy’s ACL feature we can basically mimic Apache virtual hosts. Consider this example snippet from haproxy.cfg:
frontend www *:80 mode http acl comet hdr_beg(host) comet. use_backend meteor if comet default_backend apachebackend meteor mode http server server1 127.0.0.1:4670 backend apache mode http server server2 127.0.0.1:8080
As you can see, I set up a front-end to accept all connections on port 80. Then I use an ACL to examine the HOST header and see if it begins with comet. (e.g. http://comet.example.com). If it does, the request is sent to the comet server on port 4670, and if not, requests go to Apache on port 8080. And there you have it, a high performance Comet installation with no money out-of-pocket.