a server-side JavaScript environment that uses an asynchronous event-driven model and designed for writing scalable internet applications, notably web servers. This allows Node.js to get excellent performance based on the architectures of many Internet applications. Programs are written in JavaScript, using event-driven, asynchronous I/O to minimize overhead and maximize scalability. Node.js is being hailed as “the new Ruby on Rails” by some in the developer community. But it’s not a magic bullet, nor is it appropriate for all programming scenarios. JavaScript has traditionally only run in the web browser, but recently there has been considerable interest in bringing it to the server side as well, thanks to the CommonJS project. Other server-side JavaScript environments include Jaxer and Narwhal. However, Node.js is a bit different from these solutions, because it is event-based rather than thread based. Web servers like Apache that are used to serve PHP and other CGI scripts are thread based because they spawn a system thread for every incoming request. While this is fine for many applications, the thread based model does not scale well with many long-lived connections like you would need in order to serve real-time applications like Friendfeed or Google Wave.
instead of threads, and is able to scale to millions of concurrent connections. It takes advantage of the fact that servers spend most of their time waiting for I/O operations, like reading a file from a hard drive, accessing an external web service or waiting for a file to finish being uploaded, because these operations are much slower than in memory operations. Every I/O operation in Node.js is asynchronous, meaning that the server can continue to process incoming requests while the I/O operation is taking place. JavaScript is extremely well suited to event-based programming because it has anonymous functions and closures which make defining inline callbacks a cinch, and JavaScript developers already know how to program in this way. This event-based model makes Node.js very fast, and makes scaling real-time applications very easy.
threads wait till some I/O operation finish: Every OS thread takes some memory, so regular servers can't handle many simultaneous connections without penalizing the system performance. var result = query("select * from users"); for(user in result){ //You get the idea } In this case the OS thread just sits and waits the I/O operation returns to resume the flow.
engine (Chromium and Google Chrome engine). • Programs are written in plain old javascript, we use the same language for client and server (Die Ruby Die!) • Does I/O better: query("select * from users", function(data, status){ //Do something really cool with users }); • Files I/O and db queries are non-blocking • Great performance even handling a big number of users • It gets better every time google improves V8 • It has his own package manager called npm (node package manager)
safe way to build high performance and scalable network applications in JavaScript. Those goals are achieved thanks it's architecture: Single Threaded : Node use a single thread to run instead of other server like Apache HTTP who spawn a thread per request, this approach result in avoiding CPU context switching and massive execution stacks in memory. This is also the method used by nginx and other servers developed to counter the C10K problem. Event Loop : Written in C++ using the Marc Lehman’s libev library, the event loop use epoll or kqueue for scalable event notification mechanism. Non blocking I/O : Node avoid CPU time loss usually made by waiting for an input or an output response (database, file system, web service, ...) thanks to the full-featured asynchronous I/O provided by Marc Lehmann’s libeio library.
protocols like TCP, DNS, and HTTP (the one that we will focus on). The design goal of a Node application is that any function performing an I/O must use a callback. That’s why there is no blocking methods provided in Node’s API. The HTTP implementation offered by Node is very complete and natively support chunked request and response (very useful since we are going to use the twitter streaming api) and hanging request for comet applications. The Node’s footprint for each http stream is only 36 bytes (source).
If we relate event-driven programming to standing in the line at a doctor’s office to see the receptionist. Inevitably, at least in the USA, there are additional forms to fill out with insurance info, privacy releases, etc.
thread-based system, when you get to the receptionist you stand at the counter for as long as it takes you to complete your transaction. If you have to fill out 3 forms, you would do so right there at the counter while the receptionist just sits there waiting for you. You are blocking her or him from servicing any other customers. The only real way to scale a thread-based system is to add more receptionists. This, however, has financial implications in that you have to pay more people and physical implications in that you have to make the room for the additional receptionist windows.
event-based system, when you get to the window and find out you had to complete additional forms, the receptionist gives you the forms, a clipboard and a pen and tells you to come back when you have completed the forms. You go sit down in the waiting and the receptionist helps the next person in line. You are not blocking her from servicing others. When you are done with your forms, you get back in line and wait to speak with the receptionist again. If you have done something incorrectly or need to fill out another form, he or she will give you the new form or tell you the correction and you’ll repeat the process of going off, doing your work, and then waiting in line again. This system is already highly scalable (and is in fact used in most doctor’s offices I visit). If the waiting line starts getting too long, you can certainly add an additional receptionist, but you don’t need to do so at quite the rate of a thread-based system.
always been one of the thread-based model. You launch Apache or any other web server and it starts receiving connections. When it receives a connection, it holds that connection open until it has performed the request for the page or whatever other transaction was sent. If it make take a few microseconds to retrieve a page from disk or write results to a database, the web server is blocking on that input/output operation. (This is referred to as “blocking I/O“.) To scale this type of web server, you need to launch additional copies of the server (referred to as “thread-based” because each copy typically requires another operating system thread). In contrast, Node.js uses an event-driven model where the web server accepts the request, spins it off to be handled, and then goes on to service the next web request. When the original request is completed, it gets back in the processing queue and when it reaches the front of the queue the results are sent back (or whatever the next action is). This model is highly efficient and scalable because the web server is basically always accepting requests because it’s not waiting for any read or write operations. (This is referred to as “non-blocking I/O” or “event-driven I/O“.) To put it a bit more concretely, consider this process:
a request for “/about.html” on a Node.js web server. The Node server accepts your request and calls a function to retrieve that file from disk. While the Node server is waiting for the file to be retrieved, it services the next web request. When the file is retrieved, there is a callback function that is inserted in the Node servers queue. The Node server executes that function which in this case would render the “/about.html” page and send it back to your web browser. Now, sure, in this case, it may only take microseconds for the server to retrieve the file, but.. microseconds matter! Particularly when you are talking about highly-scalable web servers! This is what makes Node.js different and of such interest right now. Add in the fact that it also uses the very common language of JavaScript, and it is a very easy way for developers to create very fast and very scalable servers.
is that there is no single right language or framework that should and must be used for all web apps. But based on what we heard from these startups, Node is increasingly being seen as a “best solution” for a certain type of application. According to Tom Hughes-Croucher, a recent Joyent hire who is writing the first O’Reilly book on Node, “Node has popularized event-driven programming.” With event-driven programming, Hughes-Croucher explains, “The actual amount of resources you use is much smaller, and you can get a lot more out of fewer servers.” Node is all about making event-driven, low-latency, concurrent apps. Erlang, the language that powers Facebook’s chat server, uses the same model. Tornado, a concurrent server for Python that powers FriendFeed, was an attempt at this, too. But Node has one advantage over technologies like Erlang and Tornado: “None of that was too accessible,” says Hughes-Croucher. “Node takes a language people know very well — Javascript — and makes it available to do server programming, as well.” In traditional languages and frameworks, the communication inside the app between the web server and the database is the most time-intensive part of the transaction. Node makes a much smaller footprint on your web server. It allocates web server resources on an as-needed basis, not pre-allocating a large chunk of resources for each user. For example, Apache might assign 8MB to a user, while Node assigns 8KB.
efficient on servers is by not allocating resources to things while it waits,” says Hughes-Croucher. “Say you have to talk to the database, and that’s going to take 50ms to respond. Instead of assigning all of the processing resources for that 50ms wait, it just uses a placeholder. When the database responds, then it allocates the resources needed to process. That means it’s totally possible to do a lot more requests at once, because you only allocate the server resources when you need to use them, not while you are waiting on databases.”
echo "world!"; ?> //helloworld.js setTimeout(function(){ console.log("world!"); }, 2000); console.log("hello"); There is no waisted time on the node program, the thread is idle not waiting
var server = http.createServer(function(req, res){ res.writeHead(200, {"content-type":"text/plain"}); res.end("Hello World!\n"); }).listen(8000); Headers of the request are: HTTP/1.1 200 OK content-type: text/plain Connection: keep-alive Transfer-Encoding: chunked
living on top of the V8. What is not node.js? A super framework that would change your life. Assuming that your life will change for a crappy piece of software
and realtime possible in all browsers. It also enhances WebSockets by providing built-in multiplexing, horizontal scalability, automatic JSON encoding/decoding, and more.
able to send static files such as HTML files, images and other files. The following code does just that: var sys = require("sys"), http = require("http"), url = require("url"), path = require("path"), fs = require("fs"); http.createServer(function(request, response) { var uri = url.parse(request.url).pathname; var filename = path.join(process.cwd(), uri); path.exists(filename, function(exists) { if(!exists) { response.sendHeader(404, {"Content-Type": "text/plain"}); response.write("404 Not Found\n"); response.close(); return; }
able to send static files such as HTML files, images and other files. The following code does just that: fs.readFile(filename, "binary", function(err, file) { if(err) { response.sendHeader(500, {"Content-Type": "text/plain"}); response.write(err + "\n"); response.close(); return; } response.sendHeader(200); response.write(file, "binary"); response.close(); }); }); }).listen(8080); sys.puts("Server running at http://localhost:8080/");
of the modules that we will need in our code. This includes the sys, http, url, path, and fs or filesystem modules. Next we create an HTTP server like we did before. This time, we will use the url module to parse the incoming URL of the request and find the pathname of the file being accessed. We find the actual filename on the server’s hard drive by using path.join, which joins process.cwd(), or the current working directory, with the path to the file being requested. Next, we check if the file exists, which is an asynchronous operation and thus requires a callback. If the file does not exist, a 404 Not Found message is sent to the user and the function returns. Otherwise, we read the file using the fs module using the “binary” encoding, and send the file to the user. If there is an error reading the file, we present the error message to the user, and close the connection. Because all of this is asynchronous, the server is able to serve other requests while reading the file from the disk no matter how large it is. If you run this example, and navigate to http://localhost:8080/path/to/file, that file will be shown in your browser.