Nowadays, everybody talks about orchestration, microservices, containers and how Kubernetes is changing the orchestration world. What does this mean to deploy your Node.js application in production? Why should you care anyways?
This blog post will touch this subject and give you the first steps to join the conversation and apply this learning straight in production. First, let talk more about the whole Microservice oriented architecture and how it applies to Node.js.
Demystify Node.js Microservices
Instead of writing an in-depth essay about the demystification of Microservices, I give you a quick summary before we jump into the sweet stuff.
To understand why everybody wants to talk about the cool guy in town (Microservices) we need to understand the precursor in application development. The monolith.
The monolith
If you have a monolithic application than all of the code for a system is in a single codebase that runs together and produces one point of entry.
Bringing up the application is just a simple npm start
. It keeps everything tidily together. It's still a great option for application development and being agile. The downside of this is when you want to release often, you'll have to redeploy the whole monolith, not just the changed parts.
Microservices
Another approach of developing an application is to break-up your codebase is smaller chunks. Each chunk is a service. All those services together will provide the end-user with the same functionality as the monolith.
Bringing up the application is NOT just a simple npm start
. You need to start each service independently using its own npm start
.
There is no definition how Micro your Microservice should be. When you break up your Monolith in smaller chunks or your application is composed of different services you are doing Microservices.
The upside of microservices allows you to release often and to redeploy only the parts of the system that you made the changes to. The downside is how we are going to orchestrate this.
I wrote an essay about orchestration in general and quote: Everything is orchestration. What this means that things applied to microservices, addressed in this blog post, also applies for monoliths.
The orchestration problem of a non-monolith approach
If your Node.js application is using a non-monolith approach; multiple services composed into a single application you need a way to orchestrate this. Containers for the win here! With containers, you can isolate each process (= service = npm start
) and give each process his own event loop. Let talk a bit out the Node's event loop.
Under the hood of the Node’s event loop
All the magic Node give us is happening in the Node’s event loop. Node is using the event-driven paradigm to perform all the magic in the event loop.
In computer programming, event-driven programming is a programming paradigm in which the flow of the program is determined by events such as user actions (mouse clicks, key presses), sensor outputs, or messages from other programs/threads. Event-driven programming is the dominant paradigm used in graphical user interfaces and other applications (like Node) that are centered on performing certain actions in response to the (user) input.
The general implementation is to have a central mechanism that listens for events and calls a callback function once an event has been detected. That’s the basic principle behind Node’s event loop.
Here’s some pseudo-code how Node’s event loop looks like:
while (queue.waitForMessage()) { queue.processNextMessage(); }
Node’s event loop is single threaded event loop, this can cause performance issues. For example, when you are under load or have a workload which does a lot of CPU intensive processing. How are we making our Node application more performant? Microservices and containers to the rescue!
Containerize each service
The first step to run your Microservices in production is to containerize is each service. We already wrote a bunch of articles about this.
Take this Express.JS as an example:
To run this in an isolated process, we need a Dockerfile to containerize this puppy:
Now you can build a container image: $ docker build -t my_micro_service .
and run it as an isolated process: $ docker run -p 8080:8080 my_micro_service
. You can now hit http://localhost:8080
What I really like about containers is the way you can scale your service and you Node’s event loop just by starting more containers and orchestrate them around your cluster. If for example parts of your API are under heavy load you can scale up that piece and utilize the resource for efficiently. If the pressure is normal, your can just scale down and maybe another part of your services need more capacity.
Cool! But how? You may ask. Let’s talk about a developer-centric solution using Cloud 66 for Containers backed by Kubernetes.
The solution
As we talked before, the nice thing when you break away from a monolith (= single thread) into a (micro) service oriented architecture you can have an isolated event loop for each service. Because every Node process is running isolated in a container!
When you want to succeed with Node.js in this new chapter in IT, you need to streamline the following four phases:
- coding your service and commit changes (obvious)
- building (= container images) and testing your service
- provisioning your infrastructure (= your cluster)
- deploying, running and maintaining your service in production
What does Kubernetes bring to the table
Kubernetes is an orchestrator, it takes all the pain away to run your workload on top of your cluster of your servers. Kubernetes make sure your services are always up and running, scaling and do fail-recovery when a server catch fire for example.
How can Cloud 66 help
Kubernetes is just a part of the bigger picture!
You still need a trigger from your code to (re)deploy your service in production. Have your code build, tested and push to your cluster. But also you need to provision your set of servers. Kubernetes will not help with this. This is the space where we step in. Cloud 66 provides a service to build, deploy & manage your apps on your own servers!
We provide the Complete Container Toolchain. The moment you push your changes after coding your service and we take care of it.
Sign up and start deploying Node.js services in a production backed by Kubernetes.
Originally published at blog.cloud66.com on July 12, 2017.