Also posted here: https://stackoverflow.com/questions/8839295/long-polling-options-nginx-php-node-js
I'm designing a long-polling app to broadcast small changes very rapidly to, possibly, a large number of users. The app will run in tandem with a website running a fairly standard cms. They'll both be running on one server, and to begin with so will the database.
I come very much from a LAMP environment and I'm definitely a developer and not a sys-admin. That said I'm not afraid to try out some new things.
I've spent the day researching my options and I'm hoping people can answer some questions and give me some recommendations.
I have narrowed it down to these:
A. Apache and php for the website, Node.js for the app (running on a separate ip)
B. Nginx and php for both the website and app
C. Nginx and php for website, Nginx and Node.js for the app
So the questions:
- How does Nginx handle PHP's non-multi-threadingness ;). Will PHP prove as much a bottleneck as Apache would have for long polling?
- I've heard it suggested that I use nginx as a reverse proxy in front of Apache and Node.js, is that a better solution than just nginx? If so, why?
- Which option have you used/would recommend?
Bear in mind that ease of set-up could be a factor, I'm fairly comfortable with Apache but I've only played with Node (I have strong javascript) and I've never installed Nginx.
I'll happily provide clarifications if anyone needs them.
Having just completed an app involving lots of nginx reverse proxying, I would be more inclined to go with either your second or third option. ...or maybe something slightly different. Lets break it down to individual points to consider:
Static Files
For serving static files (for either the website or the app), node and nginx are the clear choices as they don't fork themselves for each new request like Apache does. Node is faster than nginx at serving static files, but depending on the amount of traffic you'll see, this might not be a meaningful difference.
I would choose nginx as the public-facing server and reverse proxy requests to other things as necessary. Even though it is slightly slower than node at serving static files, its flexibility and ease of configuration make up for it. PHP, if you choose to use it, is faster (configured properly) with nginx than with Apache, and nginx's configuration files are similar to Apache's but more concise. It shouldn't be too foreign-looking when you dive into it.
SSL
If you are planning to use SSL, save yourself the trouble now and get the latest version of nginx so that you can utilize the latest version of Google's SPDY module. Currently, the latest version is 1.7.3. Some package managers are behind quite a bit, so you may have to compile from source. If this is the case, make sure that the
--with-http_spdy_module --with-http_ssl_module
flags are used, among others. Here is a guide for that as well as setting up the configuration files to use SPDY.Because all your requests go through nginx and a single domain name, you only have to set up SSL in one place. Any reverse proxied requests do not need to be over HTTPS because they happen internally. If you make node.js run your app, you just have to make sure it only listens on localhost and doesn't serve external requests directly.
Application
Node is a good choice for the application code and the long polling that you wish to accomplish. It is also fairly straightforward to proxy these long polling requests through nginx. With these two nginx options...
... you can adjust the timeout of requests. You will want to make sure your application code puts an end to the requests before nginx does. Otherwise, you will get a
504 Gateway Timeout
instead of a200 ok
. If the nginx timeout is set to 60 seconds, you should end and restart a long polling request every 55 seconds or so.Website
If you aren't set in stone with using PHP, node.js or a static site generator written in node.js could also work for your needs. Docpad is one that I use, but there are many great options. Node packages like Grunt make deployment automation easy. A few of the things I use it for are HTML, CSS, and JavaScript minification and cache busting.