I assume that overloaded server still serves some requests. But my assumption could be wrong, so if you have experience with that -- please share your knowledge.
Another thing that baffles me: if I introduce new supernode that is sitting on new IP address -- why would all the traffic suddenly hit that node?
Shouldn't it be just gradual increase in requests while more and more Skype clients discover that new supernode?
As to your second point, I think you are right. I assume that is what the mega-supernode is: a network of machines who's resources are as high as can be to handle all of the connections and try to beat the bottlenecks.
See http://en.wikipedia.org/wiki/Thundering_herd_problem
Many types of systems need a warm up period before they can realize their full performance. In web applications a controlled warm up is often needed to prime the caches. In P2P applications - which you can't easily "reboot" as a whole - the restoration of a steady state can be much more complex.
Shouldn't it be just gradual increase in requests while more and more Skype clients discover that new supernode?
In theory, yes. In practice this seems to be a case of http://en.wikipedia.org/wiki/Cascading_failure
The remaining supernodes either can't handle the aggregate load alone. Or they are being overwhelmed because the re-connection attempts from clients are not evenly distributed.
Shouldn't it be just gradual increase in requests while more and more Skype clients discover that new supernode?
In theory, yes. In practice there's probably a lot of http://en.wikipedia.org/wiki/Positive_feedback and perhaps even http://en.wikipedia.org/wiki/Monster_wave going on in the skype network right now.
The GP's question is valid: there's no reason why server software should crash when overloaded instead of simply degrading service.
Made-up Scenario: My cluster can handle XXXk users with an SLA of YYms response time. In degraded mode, I'm only handling XXk users with YYYYms response times.
I'm not meeting my SLA for the remaining number of users so I am, in essence, offline.
As to your specific point of "crashing", look at what happened with 37s. Should the server have crashed? No but there was a bug. The reason you add more capacity in the FIRST place is because the existing number of nodes cannot handle the volume. Depending on any number of bugs, issues or configuration your degraded capacity is for all intents and purposes "crashed".
Made-up scenario #2: A single server in your apache configuration can handle 200k concurrent connections reliably with fast response times. Double that load and response times are so long that various devices on the path are timing out the connections as stale. Apache hasn't crashed but it's not really doing anything.
Fast failure is an accepted best practice. Shit, it's baked into Erlang. Kill the process, start a new one and move on. Depending on the nature of the crash, you're doing nothing but churning processes and not actually servicing requests.
The bigger problem is that people don't design for this type of scenario. Static landing pages. Decoupled services instead of monolithic all-in-one containers. Look at github. That's an awesome example of how to degrade service during an outage. Only certain components are "crashed" because everything is fairly decoupled.
Meanwhile there's a guy over here running 4 apps in the same tomcat container that communicate over memory transport with each other or even if he had the common sense to decouple each app, didn't bother to fail fast and was busy spinning up threads trying to communicate with the rest of the services that he can't actually respond to anything externally.
Degrading service, or more accurately, serving the maximum number of clients you can serve and no more is absolutely not the same thing as being down.
Failing/crashing rather than limiting the number of clients you serve is absolutely not established best practice. It's poor practice, in fact.
The skype outage probably not. This was in response to the thread going on about overloaded webapps - thundering herd is a common issue there.
The GP's question is valid: there's no reason why server software should crash when overloaded instead of simply degrading service.
Nobody used the word "crash" but graceful degradation is quite hard. You have to understand the problems at heart, plan and build for it. That is more than enough reason for most apps to not degrade very gracefully.
Graceful degradation is not hard. Serve N clients, and no more. It's an extra conditional in the event loop. Am I serving N or more clients right now? Then don't accept new connections (or accept(2) them and immediately close them to avoid a backup in the listen queue).
The accept()-issue you're referring to is merely a popular manifestation of the thundering herd problem.
The term is nowadays also used in a broader sense to describe similar situations in distributed systems.
It's not a common reason why servers crash when overloaded.
Again, nobody is talking about servers crashing here.
We are talking about web applications (which usually consist of multiple servers talking to each other) degrading to the point of not serving a meaningful rate of requests anymore.
In that context the role of the "thundering herd" is often taken by your own users, who will furiously smash their reload-buttons to get past those 500-errors.
It's an extra conditional in the event loop. Am I serving N or more clients right now?
You're talking about implementation details of a socket server. I was talking about entire applications.
When servers are getting overloaded, you need to throttle the incoming requests aggressively and early, to keep response time reasonable.