Scalability of server-side application, best approach - node.js

I'm programming a server-side application which will manage requests from:
Game client
Website (HTTP requests)
API
As of now I'm using only one (NodeJS) application for every type of requests, the problem is that with a growing user base, this approach will generate a bottle-neck.
I would like some advices on how to develop the server-side architetture so that it'll be scalable.
The only solution that I know of is to use multiple servers with the same application running which will share the same memory (Redis server).
Is it possible in nodeJS to split the management of these types of request into multiple servers? Maybe one or more servers for each type of request?
Currently I'm using:
NodeJS
Redis
MySQL
Express
Socket.io
Thanks in advance, can you recommend some books on this matter?

On one machine to handle the power of multicore architecture you can use node.js Cluster module (https://nodejs.org/api/cluster.html).
I think it is a good idea to split API and Website on different applications. If you decide to run multiple node.js applications on one machine try to use pm2 (http://pm2.keymetrics.io/). You could probably split your API on a bunch of small applications - which called microservice architecture. I personally don't like microservice approach you can check the web for pros and cons.
Also if you deploy your application (or bunch of applications) on different virtual/phisycal machines (which is usual in production) you can use haproxy for balancing and
fault tolerance (http://www.haproxy.org/).

Related

Architecture question - The need for a separate backend running Mongo, Express & Node in MERN or MEVN project

Are my assumptions correct here, is there a different need for a separate backend, or can a monolithic (hopefully simpler) solution accomplish the same functionality perhaps at the cost of not scaling as well?
Looking at existing MERN or MEVN solutions, they always seem to involve two node processes where the front end process is running the client framework and backend processes DB requests using Node, Express & Mongo. This seems like a good solution performance wise when balancing across at least two servers. For my solution, where performance is not the issue, I've wondered what is the need for a separate backend. Why not just use try/catch with async/await in the front end to get to the DB data instead of an api call to a separate backend. Then once I started trying to design my more monolithic solution, I realized there is a problem that the separate backend actually solves. Trying to avoid DB concurrency issues, I realized the separate backend solution actually lowers the need for logical transactions since node is single threaded and only processes one request/response at a time.
So if I understand correctly, you're asking why do you need a backend that talks to the DB (and potential other backend services) instead of calling the DB from the front-end directly.
The answer is the following:
If you run this application on your local machine only (front-end and DB), then I can see why you wouldn't need a backend.
If this application is exposed in Internet, then your DB will hijacked in a matter of minutes maybe.
Security is the main concern here, everything that runs on client-side (JS stuff) can be seen pretty easily by the user -- this includes endpoints, passwords, etc. Not to mention that your business logic is fully exposed to the attackers.
For that reason, the backend plays a very important role in protecting the access to the DB, rate-limiting and resource usage capping, and many others.

Node Backend Setup (Multiple Node App or just One Universal Node App?

I am trying to create back-end with nodes and it will have three clients.
- Mobile App
- Web App
- Admin Panel
I heard that the node is a single thread app. To have maximum performance is it better to have three node servers or just one that connects all? I am using MERN stack.
The question doesn't have a single answer and could possibly be considered opinion based.
However, the ultimate choice of your architecture - wheter you will have a single app that serves the backend for multiple frontends or multiple separate apps for each frontend - doesn't really depend on performace considerations and is completely independent on the fact that node is single threaded or not.
It's because, regarding scalability and performance, you will possibly use the cluster module to scale your app to multiple processor cores and then, you will have a farm of servers processing incoming requests. This holds regardless of your architecture.
If I were you, I'd have a single application supporting multiple frontends from the single backend then. Assuming you can correctly control the access to the backend (so that for example, web users are not able to forge requests and interfere with the mobile app), a single app could possibly be easier to deploy.

Sails.js (Node.js) server architecture, scaling and performance

I want to create Sails.js (Node.js) server app, which will provide API for single-page-app. This server will consist of multiple modules:
user management
forum
chat
admin GUI
content management
payment gateway
...
All these modules will share one database. The server must be able to handle as many requests and web sockets as possible. Clean architecture and performance are my primary goals.
My questions:
Should I create multiple servers running on multiple ports? I mean, one server for content management module. Another server for forum management module.
Or is it better to create only one big universal server, which will consists of multiple separate modules (hooks in Sails.js) and runs on one port? Will performance of the server decrease in this case ?
I was thinking about vertical scaling one big universal server, running on single port with pm2. Or is it better to scale Node.js horizontaly and split server to multiple smaller servers ?
Im new to Node.js so I appreciate any advice.
I think it really boils down to the scale of the project.
For very simple things there's no real reason to scale past a single but reliable server is there?
However for broader projects that have a back-end that is resource intensive and a lot of users and traffic, you may a want to split the back / front end aspects depending on the requirements.
In which case you might have a single server (or more) dealing with the specific administrative requests or routines then have the client / user API running through a load balancer and spread across multiple servers in multiple regions or break it down further into an auto scaling group so as to accommodate for fluctuations in traffic.
It would be worthwhile to note too that this is really suited for higher volumes of traffic or resource usage as you're dedicating the server infrastructure for this purpose, for smaller applications where there is infrequent usage then breaking things down into micro services from the start and getting billed for the runtime rather than dedicated infrastructure utilization might make more sense to me. You could take a look at AWS API Gateway and Lambda services for some more information on that (I am not affiliated to AWS in any way, I just appreciate what they have managed to put together there).

Methods for calling APIs in one Nodejs app from another Nodejs app

Our application will have a website and a mobile app both communicating to the same API backend. I have one Nodejs application for serving only APIs and a second Nodejs app serving html pages for the website. I am using Expressjs web framework for both of these apps.
What are different methods to call APIs in one Nodejs from another Nodejs app? Additional information on when to use each method would be great.
EDIT:
Example,
I have the following applications
NodejsAPI (node & express)
NodejsWebsite (node & express)
MobileApp
NodejsAPI will provide access to APIs for the MobileApp and the NodejsWebsite. MobileApp will access APIs over http. But I want to know what are the options for NodejsWebsite to call APIs in NodejsAPI app. From what I understand this will be inter process communication between the two processes. For .net applications such communications could be done using .net pipes, tcp communication etc. What are the equivalent methods for Nodejs applications on unix and linux platforms?
Thinking from IPC perspective I found the following to be useful,
What's the most efficient node.js inter-process communication library/method?
https://www.npmjs.org/package/node-ipc
There's node's vanilla http client, http client swiss army knife, request, then there's superagent, similar to jQuery.ajax. To make your life easier there's armrest and fementa, both different flavors of the same thing.
Now if you want to reach for more performance and have another interface of your application, you can use one of these RPC solutions:
dnode: One of the most popular solutions. It's makes things very easy. It's makes using remote interfaces seamless. phantomjs-node uses dnode. Doesn't perform well with huge objects compared to others. For small stuff, it's perfect. There's other ports for other languages too.
zerorpc: Uses zeromq as it's socket library which is famous for being reliable. It supports connecting to a python client too.
smith: RPC systems used in cloud9 editor backend. Basically almost as nice as dnode, but faster. Both smith and zerorpc uses msgpack instead of JSON, so they will save bytes on the wire.
axon-rpc: A lightweight solution. As nice to use as zerorpc. You can configure it to use msgpack with axon-msgpack.
All of above work on both TCP(To be used on different machines) or Unix Domain Sockets(faster than TCP, but only on the same machine).
If you want more performance, you can embed your NodejsAPI in your NodejsWebsite, by just simply requiring it's interface module.
If you want answers better than this, write a more specific question. The question as it is, is too broad.

What are my options when it comes to node.js lifecycle?

Are there any examples or conventions out there of how to use node.js to host multiple web apps?
I'm already aware that node itself can be used to build a server, but I'm curious as to whether there have been implementations where you aren't necessarily running it all the time. Strictly for the reason that perhaps there are multiple sites being hosted, each with their own copy of a framework, static files and custom functionality.
Or maybe you do run one instance of node and code a multiple site architecture to ensure one bad site doesn't take the server downin some way?
Virtual hosts, ensuring that one site can't crash others...these are all things that have been considered with other platforms, but I have had some difficulties finding for node! :)
I am already aware of connect, express and other middleware, however it doesn't cover what I'm asking here.
If you're worried about runtime isolation, each "site" should run it's own node process. Then use a proxy like node-http-proxy that will do host header based routing. Another great node based option is bouncy, but you don't necessarily need to use node to do the host based routing. You could just as well use haproxy, nginx, etc.
The baseline RAM overhead of each node process is very small (~10mb - 15mb). Also, if you do HTTP based routing you can spread your sites easily across machines, user home directories, etc.
If you want to handle the site/host registration programmatically, I would use seaport and then communicate the hostname and host + port details back to the proxy so that the routing table can by dynamic. This would also make it fairly easy to scale a site across multiple node processes.
Good luck!

Resources