Future-proofing Your Apps: Cloud Foundry and Node.js

June 28, 2012 Raja Rao DV

featured-cf-genericMost real-world applications we ship to consumers or enterprises are multi-year projects. In the cloud era, newer technologies (programming languages, runtimes, frameworks) are created faster than ever. While most of them fail to get any traction, once in a while a technology becomes popular because it solves a problem or set of problems extremely well.

Now in such an era, if you make a large investment for a multi-year project on a PaaS that only supports one technology and some other technology comes along that happens to solve your problem better, then you are stuck. You have unintentionally become a victim of vendor lock-in. The heart of your problem is that your PaaS, and hence your app, was not future-proofed to begin with.

PaaS With 1 set of Technologies

To future-proof your long term project, you should:

  • 1. Use a polyglot PaaS like Cloud Foundry that supports a great mix of both mature technologies and upcoming technologies.Polyglot PaaS
  • 2. Learn about newer and popular technologies like Node.js to:
    • See if they can replace part of your current app (i.e., convert it to a polyglot app).
    • Write future apps for your company in newer technologies using the same PaaS that you are already familiar with.

The remainder of this blog is about the latter option–learning newer and popular technologies, in this case Node.js, to help future-proof your app.

Things to note before you read:

  • While this blog refers to JavaScript frequently, it’s all happening on the server (not in the browser). Think of yourself as a server-side engineer throughout this blog.
  • We will also discuss when not to use Node.js and other similar languages towards the end of the blog.

What is Node.js?

Official definition: “Node.js is a platform built on Chrome’s JavaScript runtime for easily building fast, scalable network applications. Node.js uses an event-driven, non-blocking I/O model that makes it lightweight and efficient, perfect for data-intensive real-time applications that run across distributed devices.” – Nodejs.org

Simple (my) definition: A platform that makes writing powerful C/C++ server-side apps easy by essentially wrapping them in JavaScript.

Let’s understand the definition by looking under the hood:

While at a first glance, perhaps because of the name Node.js, it might feel like it is built using JavaScript, but it is not. It simply runs JavaScript on the server. It is about 80 percent C/C++ code and about 20 percent JavaScript code. The C/C++ libraries are responsible for running JavaScript (via Google Chrome V8 JS engine) and providing support for HTTP, DNS, and TCP, etc.,–important server-side functionalities. The proportionally smaller JavaScript code mostly consists of libraries or modules to help make server-side developers’ lives a lot simpler.

Some useful definitions:

  • Chrome V8 Engine: Chrome V8 Engine is Google’s open source, C++ based JavaScript engine that actually runs JavaScript. The Node.js team took this C++ code and added other important libraries like TCP, HTTP and DNS to create Node.js. This is the same engine that is also embedded in the Google Chrome browser that runs JavaScript in the browser as well. This is not yet-another-JavaScript-engine but one that uses innovative techniques like “Hidden Class Transitions,” “JS to Machine Code compilation” and “Automatic GC” to make it one of the fastest JavaScript engines.

    We encourage you to go through Google’s Chrome comic book to learn more about this. Three relevant pages from that book are shown below.

  • Asynchronous I/O and Evented Support (C/C++): In order to write a fast and scalable server application, we typically end up writing it in a multi-threaded fashion. While you can build great multi-threaded apps in many languages, it usually requires a lot of expertise to build them correctly. On the other hand, these libraries (along with Chrome’s V8 engine) provide a different architecture that hides the complexities of multi-threaded apps while getting the same or better benefits.
  • Let’s compare classic multi-threaded server with an evented, non-blocking I/O server:
  • An example multi-threaded HTTP server using blocking I/O
  • The above diagram depicts a simplified multi-threaded server. There are four users logging into the multi-threaded server. A couple of the users are hitting refresh buttons causing it to use lot of threads. When a request comes in, one of the threads in the thread pool performs that operation, say, a blocking I/O operation. This triggers the OS to perform context switching and run other threads in the thread pool. And after some time, when the I/O is finished, the OS context switches back to the earlier thread to return the result.
  • Architecture Summary: Multi-threaded servers supporting a synchronous, blocking I/O model provide a simpler way of performing I/O. But to handle a heavy load, multi-threaded servers end up using more threads because of the direct association to connections. Supporting more threads causes more memory and higher CPU usage due to more context switching among threads.
  • For more details, we recommend going through Benjamin Erb’s thesis paper here: http://berb.github.com/diploma-thesis/.
  • Event-driven, non-blocking I/O (Node.js server):The above diagram depicts how Node.js server works. At a high level, Node.js server has two parts to it:
  • At the front, you have Chrome V8 engine (single threaded), event loop and other C/C++ libraries that run your JS code and listen to HTTP/TCP requests.
  • And at the back of the server, you have libuv (includes libio) and other C/C++ libraries that provide asynchronous I/O.
  • Whenever a request is made from a browser, mobile device, etc., the main thread running in the V8 engine checks if it is an I/O. if it is an I/O then it immediately delegates that to the backside (kernel level) of the server where one of the threads in the POSIX thread pool actually makes async I/O. Because the main thread is now free, it starts accepting new requests/events.
  • And at some point when the response comes back from a database or file system, the backend piece generates an event indicating that we have a result from I/O. And when V8 becomes free from what it is currently doing (remember it is single-threaded), it takes the result and returns it to the client.
  • Architecture Summary: This architecture utilizes an event loop (main thread) at the front and performs asynchronous I/O at the kernel level. By not directly associating connections and threads, this model needs only a main event loop thread and many fewer (kernel) threads to perform I/O. Because there are fewer threads and consequently less context-switching, it uses less memory and also less CPU.

What are the benefits of Node.js?

  1. Savings in I/O cost (i.e., high performance): Because of the architecture, Node.js provides high performance like Nginx server as shown below. (As a side note: Nginx uses evented, non-blocking architecture, where as Apache uses multi-threaded architecture. Nginx doesn’t use Node.js, this is just an architecture comparison).
  2. Savings in Memory: Again, because of the architecture, Node.js uses relatively very little memory much like Nginx server as shown below.
  3. JavaScript: Node.js uses a familiar and very popular language–JavaScript–and allows engineers to use a single language for both client and server. (You can also use CoffeeScript (tenth on this list), which compiles to JavaScript.)https://github.com/languages
  4. Thousands of libraries: High performance and a familiar language is great, but you really need libraries to get started. Although Node.js is relatively new, it already has nearly 11,000 libraries.
  5. Second most popular watched project on Github: A large ecosystem of developers means better libraries and frameworks.

    2nd most popular on Github

    2nd most popular watched on Github

When to use Node.js:

Use Node.js to:

  1. Build a (soft) real-time social app like Twitter or a chat app.
  2. Build high-performance, high I/O, TCP apps like proxy servers, PaaS, databases, etc.
  3. Build backend logging and processing apps.
  4. Build great CLI apps similar to vmc-tool, and build tools such as ant or Make.
  5. Add a RESTful API-based web server in front of an application server.

When NOT to use Node.js:

Node.js is not suitable for every application:

  1. Mission-critical (hard) real-time apps like heart monitoring apps or those that are CPU-intensive.
  2. For simple CRUD apps that don’t have any real-time or high-performance needs, Node.js does not provide much of an advantage over other languages.
  3. Enterprise apps that might need some specific libraries for which there may not be a Node.js library yet. (However, you could build a polyglot app that uses Java in conjunction to Node.js to help with libraries.)

What are the drawbacks of Node.js:

Most of the drawbacks are because Node.js itself is relatively new:

  1. Node.js libraries are developed actively with a high rate of change. There are newer versions of libraries literally every month. This can cause version issues and instabilities. Npm shrinkwrap and package.json were introduced a while back to set up standards, but the issue still exists.
  2. Still many libraries, such as the SAML auth library which is required for enterprise apps, are not available yet.
  3. The whole callback, event-driven, functional programming aspects of Node.js can add a learning curve burden to server-side programmers of other object-oriented languages. (Note, there are several libraries to help overcome this. One example is async. In addition, developers can also use CoffeeScript which compiles to JavaScript to help with learning curve).
  4. Asynchronous and event-driven code inherently adds more complexity to the code versus a synchronous code.
  5. JavaScript has more than its share of “bad parts” and might throw off engineers and newcomers. (Side note: Read some good JavaScript books like: JavaScript: The Good Parts if you are a newcomer.)

What are other similar and newer languages I should be aware of:

  1. vertx.io: Write your application components in JavaScript, Ruby, Groovy or Java. Or mix and match several programming languages in a single application.
  2. Erlang: Erlang is a programming language used to build massively scalable soft real-time systems with requirements on high availability. Some of its uses are in telecoms, banking, e-commerce, computer telephony and instant messaging. Erlang’s runtime system has built-in support for concurrency, distribution and fault tolerance.
  3. Twisted: Twisted is an event-driven networking engine written in Python and licensed under the open source.
  4. EventMachine: EventMachine is an event-driven I/O and lightweight concurrency library for Ruby. It provides event-driven I/O using the Reactor pattern.
  5. Scala: Scala is a general purpose programming language designed to express common programming patterns in a concise, elegant and type-safe way.
  6. Dart: With the Dart platform, you can write code that runs on servers and in modern web browsers. Dart compiles to JavaScript, so your Dart web apps will work in multiple browsers.
  7. Go: Go is an open source programming environment that makes it easy to build simple, reliable and efficient software.
That’s it! Hopefully this blog gave you a good overview of polyglot PaaS and Node.js. We want to get you on track to future-proof your next multi-year project.
Also, please be sure to join me for a live webinar: “Node.js Basics: An Introductory Training” on July 18, 10:00 a.m. PDT.
Want to try Node.js on Cloud foundry?
Cloud Foundry provides a runtime environment for Node.js applications and the Cloud Foundry deployment tools automatically recognize Node.js applications. Simply follow the step-by-step instructions as described here: http://docs.cloudfoundry.com/frameworks/nodejs/nodejs.html and you will be on your way to running Node.js apps soon.
  • Raja Rao DV (@rajaraodv – Developer Advocate, Cloud Foundry, (Node.js))

About the Author

Biography

Previous
How to Setup Your Mac for Rails Development
How to Setup Your Mac for Rails Development

This guide will show you how to setup your Mac environment for optimal Ruby on Rails development. Step 1: P...

Next
VIGGLE: Loyalty With Rewards For Watching TV
VIGGLE: Loyalty With Rewards For Watching TV

Think back to your childhood. Remember when your parents would reward you for cleaning your room, or helpi...