Nginx-1.4.0 stable version has been released
nginx.org
nginx.org
I ended up going with
proxy_read_timeout 31536000;
--meaning that a client can hold open a websocket without the server needing to say anything for a year at a time. I'm not sure whether that's a good idea in all cases, though; it means you won't detect silent backend netsplits (i.e. the network cable getting cut to your appserver box without giving it a chance to FIN) since the TCP connection will still look open.The more cautious solution might be to use a lower timeout (120s or so) but to have the server send heartbeats over the websocket when it's not doing anything. (If you're using socket.io, you're already getting this behavior for free; if you're using sock.js, you can enable it.) This breaks down at true scale, though: when you have 100000 idle clients you might want to announce to at any time, but don't usually have anything to say to most of them, sending heartbeats to every client in that pool can saturate your link.
A compromise is probably to set the long timeout, but then use a cluster-monitoring service which will push a new config to your load-balancers in response to observed network-toplogy changes.
Scaling the heartbeat is actually not a big issue. If you're actively using the socket for things, the overhead of that is likely much higher than supporting pings. You'll actually hit port limitations first (if you can support ~65k connected clients per machine), in our experience. 3000 pings a second isn't too bad (that's 100k clients, pinging every 30 seconds or so). You can also change how fast the client is pinging based on client activity.
This isn't actually a limit, by the way. The port limitation is a uniqueness constraint on full (source IP, source port, dest IP, dest port) tuples; it just means one client can't have more than 65k connections open to your server (which tends to trip people up, because they see themselves running into the limit when benchmarking parallelism--because they're sending all the requests from their own computer.)
What you'll usually hit first is the open file descriptor ulimit.
edit: I thought too fast. Amfy's reply to you is correct (and what I have seen previously). When proxying with nginx, you use up the ports locally (unless I'm missing something?).
Again, you're not "using up" local ports, just (IP/port, IP/port) pairs--so increasing the number of remote ports you want to talk to allows you to make more connections just as well as if you could increase the number of local ports used to talk to them.
(This might not be so simple for some servers which expect to only listen on one port; the workaround is to use multiple IPs for the backend server, and make sure the backend process is listening on 0.0.0.0. They don't have to be real IPs--you can just as well do port-forwarding on the backend box from one-IP:lots-of-ports to lots-of-virtual-IPs:one-port. It's simple enough to listen on multiple ports in both Node and Erlang, though, so this probably doesn't matter for most people writing websocket servers.)
An active websocket connection does have a faster response time than a regular HTTP connection ([1]). The difference here isn't a ton, but may affect real-time applications. The packets are also smaller, so less overhead if you're sending many.
The biggest difference I saw is that when the client or server needs to send several quick requests (many within a couple second), long polling breaks down. From the spec ([2]), "Once the server sends a long poll response, typically the client immediately sends a new long poll request." This delay can add up, and is not pure full duplex. Chunked responses help for server -> client, but client -> server still has the same issues.
[1] http://eng.42go.com/secure-websockets-vs-https-benchmark/
[2] http://tools.ietf.org/html/draft-loreto-http-bidirectional-0...
thank you
EDIT: it's the proxy_send_timeout directive.
proxy_read_timeout times out reads from the upstream. It will trigger when a backend server goes AWOL, not when a client falls off the net.
If you want to detect client-side disconnection, you want proxy_send_timeout.
You can emulate this by having server sent heartbeats with a proxy_read_timeout with the client required to respond to them before the server will send any more, thus going read-silent whenever the client fails to respond, but why not just have the client do the pinging? Then the server doesn't have to say anything in response most of the time.
That's exactly what i meant. Sorry if it was unclear. I accidentally switched proxy_send_timeout and proxy_read_timeout.
If you do want timeouts like this, an alternative is to handle this on the application layer, and not rely on nginx to drop connections.
See: https://github.com/vkholodkov/nginx-upload-module/issues/41
http://www.howtoforge.com/forums/showthread.php?p=296263#pos...
Please note that I am not 100% sure if its nginx related.
cat access.log.1 | wc -l
1054423 # no static objects served here
cat error.log.1 | grep timed
For PHP-FPM we use static pm and unix domain sockets. This virtual host if fairly busy with some slow (~200 ms) requests, therefore it uses 96 processes per pool. listen.backlog = -1 in php-fpm.ini for letting the kernel decide the size of the actual connection backlog. UDS is getting filled faster than TCP and nginx starts responding with 502's. Throw net.core.somaxconn = 65535 somewhere in /etc/sysctl.d for increasing the actual backlog since even if you specify a high listen.backlog value, the actual value is truncated to SOMAXCONN. Couple of years ago I wrote an article about stuff like this: http://www.saltwaterc.eu/nginx-php-fpm-for-high-loaded-websi... (shameless plug, I know, but you may get some useful info). As a side note, I am curious how the backend persistency for nginx is playing. Our production still uses the same config since 2011 as it isn't broken, but it may be more efficient.Thanks.
Thanks.
I will update you on this after observing my server for 24 hours.
The name referred to API/module stability, more than production-worthy-ness.
GL with your deploy!
nginx[20116]: nginx: [emerg] the "spdy" parameter requires ngx_http_spdy_module in /etc/nginx/nginx.conf:26
Seems the Arch package was built without SPDY support?"This module is not built by default, it should be enabled with the --with-http_spdy_module configuration parameter."
So unless you go with an unofficial binary, you'll have to compile it in yourself.
But really, the burden of a 'custom compile' is small. Nginx configuration is simple, it has minimal dependencies, and it builds quickly. You will need zlib-dev and openssl-dev.
EDIT: looks like spdy (on same port as https) requires openssl >= 1.0.1. centos has 1.0.0. nuts.
For sure, the configuration file format is different, but it's not terribly complicated.
I use this code to open a unix socket in production at tmp/socket : https://gist.github.com/lgbr/5453355
And use a configuration like this for nginx (replace /etc/nginx/sites-available/default with this): https://gist.github.com/lgbr/5453375
sudo apt-get install nginx
$BROWSER http://wiki.nginx.org/Configuration
$EDITOR /etc/nginx/nginx.conf
man nginx
man upstart
sudo start nginx
$BROWSER http://localhost:$PORT/If you want the newest version, nginx has their own deb repository[1]. It seems to get security updates faster, too.
[1] http://wiki.nginx.org/Install#Official_Debian.2FUbuntu_packa...
EDIT: Not the PPA because it's "maintained by volunteers and is not distributed by nginx.org." Their repository:
deb http://nginx.org/packages/ubuntu/ yourOScodename nginx
Nginx was written from the ground up in the modern web era, when we had already learned about the common ways that real websites worked (dynamic, high throughput, tied into other technology like php or rails, possibly living on multiple servers, etc.) Nginx is designed for efficiency and low overhead. It's also designed to live within an ecosystem rather than live as the container of an ecosystem, at its heart it's not a web-server it's a proxy. And all of this makes nginx easier to set up, easier to configure, and generally more efficient with superior performance compared to apache.
Here's an example. I have a server set up with a couple different sites, some of them are fronted by varnish (for caching), several run on php, and another runs on rails. With nginx this is all fairly easy to do. Instead of installing modules as you would tend to do with apache you set up php and rails as standalone socket-based servers (e.g. php-fpm and unicorn) and then in your nginx configuration you simply tell the web server where those are and how to use them.
Nginx also funnels you into a pattern which makes it easier to scale. Because nginx is just part of an ecosystem and not the container of an ecosystem you can easily migrate components to other servers as necessary. In my example I could push varnish off to another server, push each php app off onto its own server, push rails off onto separate servers, etc. The configuration changes would be fairly minimal and it would all still just work.
Apache is catching up with its evented MPM and proxy support, but I still wouldn't go back to Apache though. The main selling point that the OP should get is the fact that evented servers have much better memory usage under the same load as the threaded servers or (cough) process based servers.
Just be absolutely sure that you never need the additional features that Apache Httpd provides, and Nginx will probably be a good choice.
Read http://stackoverflow.com/a/3635081/309483 There is also a linked 100+ vote question, but I think it has too much noise.
I'm an Apache guy too. If you know how to configure it, there's not much reason to switch from Apache.
I use Nginx because I find it easier to configure and more lightweight out of the box.
For example, Apache is chock full of modules with a certain richness to them, they do everything and everything you could possibly think of, with a verbose configuration that usually comes filled with "defaults" by the maintainer, and plenty of options to choose between processes and threads; Nginx is "lean and mean", strictly event-based and minimalistic in almost every way, is usually compiled to include just what you need (and still feels un-monolithic despite modules being statically compiled), comes with sensible defaults and is usually bundled with almost no config.
Some rough analogues: Nginx is to Apache what (Varnish, Postfix, Go, Git) is to (Squid, Exim, C++, Subversion).
The reason I included Exim is that it's a huge monolithic chunk (at least as I remember it, it's been a while) with a very long history (and lots of legacy quirks), whereas Postfix is designed from the beginning to be modern and modular.