How LinkedIn used Node.js and HTML5 to build a better, faster app
venturebeat.com
venturebeat.com
Though Rails is not known of being high performance, this sentence rings a warning sign in my mind that something must be terribly wrong with their Rails implementation.
The JSON that's generated with all that data is converted to backbone objects instantaneously in a browser, and the few database calls are instantaneous - it's all Ruby. I will probably need to create custom lightweight objects just because ruby is so darn slow. Much of the time is spent in gsub resolving paths for paperclip attachments - work that would take most languages a few milliseconds can take 10 seconds in ruby. I know there are many ways to optimize this but I should not have to at this point.
I find with ruby I constantly run into performance bottlenecks and need to revert to optimization that I would not have to do on other platforms.
Yours is the typical answer from rails fans. But what could be wrong with his Rails implementation that could be that slow, assuming they are reasonably competent - a valid assumption I think given their successful port to node?
Agree. Ruby tends to be more likely to be CPU-bound than other languages. That demands a more indepth understanding of Ruby itself. For example, as simple as string concatenation of use '+' vs '<<' can easily fail lots of people.
Yours is the typical answer from rails fans.
I don't quite like the tone of this statement. Although I've been working with Rails at work for the past five years, I don't consider myself a Rails fanboy. I consider it a valuable tool to bring along high productivity. I am quite aware of its strength and weakness.
But what could be wrong with his Rails implementation that could be that slow, assuming they are reasonably competent - a valid assumption I think given their successful port to node?
We all know that scaling up Rails is doable though not an easy task. To handle webscale traffic like LinkedIn in Rails, you can not go very far following the traditional ActiveRecord way. Very likely, you will introduce a high performance middleware to prepare the data for rendering say in Java/C/C#. For the frontend, you have jQuery or whatever Javascript library you like. You just leave Rails to handle routings. Though some people may challenge that if it is necessary to have Rails in this architecture. I think Rails can still make a case even in such scenarios, which is basically what github does.
To be fair, Node.js also has its own quirks, besides the callback maintenance issues, I also mentioned in another post that Node.js is not as scalable as a lot of people present it to be.
Nice to see an example of Node in the wild. It's so fun and easy to develop in Node, that it sometimes feels like a toy.
and using CoffeeScript makes it even easier!
I'm not a big fan of leaky abstractions, and right now that's what CoffeeScript is. It will be somewhat less leaky once this has been resolved:
https://bugzilla.mozilla.org/show_bug.cgi?id=618650
…for all browsers.
I'm happy for CoffeeScript to exist, to be able to play with it, and to see its syntax inform the work on JS.next. It has a way to go before I'd be happy to use it in a production environment.
Also, the issue is being fixed for Chrome/Firefox, which is good enough for dev work.
Javascript: if (opposite) number = -42;
How is coffeescript an advantage in this example? The javascript seems more readable to me as it more closely follows regular english grammar.
CoffeeScript: square = (x) -> x * x
Javascript: square = function(x) { return x * x; }
In this example, again the javascript seems more clear. The function actually has the word function in the declaration. I like that. Essentially coffeescript took out the word 'function' and 'return' and replaced curly braces with other symbols.
That's surprising -- my impression has been that one tradeoff with Node.js vs. frameworks like Rails & Django is a lot more work to implement functionality they ship with out of the box -- it works at a much lower level.
It also tends to be slower going for a while as you get accustomed to the non-procedural approach.
We were able to develop this quickly for a couple of reasons. One was that we already knew rails. We used a lot of rails patterns throughout our project. Any rails dev who looked at our directory structure would be feel at home. Another reason was that we had a good understanding of our domain. We were able to anticipate many features and tasks that would have been been expensive (time-wise) to implement later. Another reason is that had 2 week release cycles with demo-able features at the end. This kept things moving at a good pace.
And of course, we have high caliber staff ;-)
So your opinion, so far, is that it is easier to modify the application, after it's launched, in Rails than it is in Node?
I don't mean to hi-jack Node thread but I'm curious since I use Java day-to-day and would love to hear more about non-web-app framework type of activities in Java.
Is using JMS make programming more clumsy? listener vs pure async.
What about the RPC stuff, do you have to write a custom serialization ?
Not to bad-mouth Node.js here. Just to give some counter examples to anybody who wants to try Node.js in production.
It seems running multiple instance of node.js and use a more updated version would helps (maybe).
Anyway, I always think that lack of threading support is definitely a feature instead of incompetency. Threading is hard and average developers should avoid it. (Unless you are doing scientific computing). If you need to scale, eventually you will need multiple servers anyway.
In other evented frameworks, it's hard to make sure that all of your code is asynchronous (especially when you use existing libraries). If your server runs into a slow, synchronous function at a critical time, it might come to a screeching halt and then fall over.
Let's say I have a few services, Service A that does Invoicing, Service B that does Payments, and the system has to communicate with 2-3 web-services as well. Let's say there is a need to create some sort of "portal"-ish solution (mobile or not). In this situation, what would be the advantage using Node?
Would you mind to share when Node is not the right choice as well?
I'm interested to know more about Node :)
UPDATE: Thank you for the replies.
FYI, I do understand the concept of node.js in terms of the async callback and the argument of client-side and server-side use the same code.
I'm not a heavy Rails user (more of a Java/Python guy) but when it comes to creating a typical CRUD web-app, Rails would be more productive?
For example, say your portal needs to collect info from 3 sources A, B, and C. In a synchronous system, you would have to request service A, wait for a response, then request B, wait, and so on. This means your request is utilizing the system for all that time, unable to serve other requests, without extra threads or processes.
Node, and other async systems, when they call for IO, like a service, a callback is registered for the result. So instead of having to wait for the result, the system becomes available for other actions, like other requests. So in this case you could request service A, B, and C all at once, and while you are waiting for the responses, the system can be handling other requests. When any of those services completes, it calls back to your code so you can handle the results, and give a response to the client.
So the advantage is that instead of a request taking A + B + C + extra time, it can take max(A, B, C) + extra time to serve the request, while serving other requests concurrently.
Node is not the only way to achieve this, many async systems exist like Tornado for python, EventMachine for ruby, and many others. But the JavaScript in node can be particularly fun to work with especially if you are also doing the front-end JavaScript, as it pretty much brings the context-switching in your brain to almost nothing.
For instance, if you switch from Rails to EventMachine, will you get most of the benefits of Node, or will you still be bogged down by Ruby's speed and resource consumption?
function get(source, callback) {
var result = getData(source);
callback(result);
}
get(A, function(result) {
get(B, function(result) {
get(C, function(result) {
// CREATE RESPONSE WITH A, B, AND C HERE
});
});
});
Wouldn't you have to wait for the data to be retrieved before running the next callback resulting in a time of A + B + C anyways? Am I missing something about the way to retrieve data from multiple sources? I don't see how max(A, B, C) is possible while still knowing for sure when all the data has been collected.https://github.com/joyent/node/wiki/modules#wiki-async-flow
For a specific example, look at async.parallel: https://github.com/caolan/async
Here's a very simple version (which I admit to still using occasionally)
RequestHandler = {
numberOfRequests: 3
makeRequests: function() {
var __this = this;
a(function() {
// Parse Data
__this.completeRequest();
})
b(function() {
// Parse Data
__this.completeRequest();
})
c(function() {
// Parse Data
__this.completeRequest();
})
},
completeRequest: function() {
this.numberOfRequests--;
if(this.numberOfRequests == 0 ) this.doDone();
}
doDone: function() {
// We now have all data, do what we will.
}
}
RequestHandler.makeRequests();(as always with Node, you can achieve the same benefit using nonblocking I/O frameworks for other languages, e.g. Twisted or gevent in Python, EventMachine in Ruby, etc)
Services are software built to handle requests. You can build both consumers and providers of requests using Node.JS.
Tried to at least give you some small idea to get you started. The explanation is NOT perfect by any means. In fact I think I may have down played it. Either way, read the docs.
I enjoy Node.JS alot.
Isn't Node.js single threaded ? Would it not under-perform , say compared to Erlang or Netty, in a multi-core CPU.
As a result, for example, although it's possible, it's not trivial to proxy WebSocket connections, which are commonly used with node.js apps. Streaming uploads/downloads have similar challenges.
Non-sequitur. WebSocket protocol is not HTTP/1.1.
WebSocket does have HTTP-like handshake as a hack, but it does not give required behavior in spec-compliant HTTP/1.1 clients, e.g. RFC 2616 requires connection to be closed after Upgrade is sent. WebSockets needs it open. HTTP requires proxies seeing Connection:Upgrade to remove the Upgrade header. WebSocket clients require this header to be present.
So basically a fully HTTP/1.1 compliant proxy is unable to proxy WebSocket connections by design.
If you need only fast downstream communication, you can use Server-Sent Events though.
Yes (for now, we might take up V8 isolates).
> Would it not under-perform , say compared to Erlang or Netty, in a multi-core CPU.
No. You can spin up multiple processes and handle the load with (for example) cluster[1].
Which is what I speculate they're doing, as they say they're running just four instances. Probably, they have servers capable of running 4 threads at the same time.
Some issues Ruby/Rails faces is due to both the language and the framework. It is not uncommon for JEE apps to pull back 10k objects, show 10 to a user and pitch the rest. ORMs like Hibernate tend to be fairly quick, especially when tuned. As a result synch code is not that problematic.
This might start to change with the advent of Scala in JVM on the server. The actors it provides MIGHT make Oracle rethink the spec a bit. But I doubt it.
http://java.sun.com/developer/technicalArticles/JavaEE/JavaE...