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

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).

Related

Google App Engine with Python 3: Mix Standard and Flexible for Websockets

I've started to port a web app backend to Google App Engine for scaling. But I'm completely new to GAE and just reading into the concepts. Steep learning curve.
I'm 95% certain that at some point many millions or at another point at least hundreds of thousands of users will start using the web app through a GUI app that I'm writing. And they will be globals users, so at some point in the future I'm expecting a relatively stable flow of connection requests.
The GAE Standard Environment comes to mind for scaling.
But I also want the GUI app to react when user related data changes in the backend. Which suggests web sockets, which aren't supported in the Standard Environment, but in the Flexible Environment.
Here's my idea: The main backend happens in a Standard app, but the GUI listens to update notifications from a Flexible app through web sockets. The Standard app calls the Flexible app after noteworthy data changes have occurred, and the Flexible app notifies the GUI.
But is that even possible? Because sibling Flexible instances aren't aware of each other (or are they?), how can I trigger the persistent connections held by the Flexible instance with an incoming call from the Standard app to send out a notification?
(The same question goes for the case where I have only one Flexible app and no Standard app, because the situation is kind of the same.)
I'm assuming that the Flexible app can access the same datastore that the Standard app can. Didn't look this one up.
Please also comment on whether the Standard app is even a good idea at all in this case and I should just go with Flexible. These are really new concepts to me.
Also: Are there limits to number of persistent connections held by a Flexible app? Or will it simply start another instance if a limit is reached?
Which of the two environments end up cheaper in the long run?
Many thanks.
You can only have one App engine instance per project however you can have multiple flex services or standard services inside of an instance.
Whether if standard is a good idea it depends up to your arquitecture, I'm pretty sure you've looked at the comparison chart, from experience is that if your app can work okay with all the restrictions (code runtimes, no availability to do background process, no SSH debugging, among others) I will definitely go for standard since it has a very good performance when working with spikes of traffic deploys new services in just seconds, keep in mind that automatic scaling is needed for the best performance result.
There are multiple ways to connect between flex or standard services one would be to just send an HTTP request from one service to another, but some other options with GCP services like Pub/Sub.
In the standard environment, you can also pass requests between
services and from services to external endpoints using the URL Fetch
API.
Additionally, services in the standard environment that reside within
the same GCP project can also use one of the App Engine APIs for the
following tasks:
Share a single memcache instance.
Collaborate by assigning work
between services through Task Queues.
Regarding Data Store you can access the same datastore from different services here is a quickstart for flex and the quickstart for standard
Which of the two environments end up cheaper in the long run?
Standard pricing is based on instance hours
Flexible pricing is based on usage of vCPU, memory, and persistent disks
If your service run very hight performance process on short periods of time probably standard will be chepear, however if you run low performance process on long periods of time, flex will be chepear, but again it depends on each use case.

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.

Splitting load of an API between multiple servers

I'm planning to build an API for one of my projects. But I'm looking for a good way to manage it, and manage server load.
Would I be better off just creating everything on one server, or should I create multiple?
Thoughts:
If I create one server and that server crashes, the whole system would go down. But if I create multiple servers to handle this, and one of them crashes, only that part would go down.
How I was thinking to accomplish this:
1) Create one API ENDPOINT
2) When a user sends a REQUEST to that API ENDPOINT, the ENDPOINT would send another request to the correct server containing the special task, when the task is done it would return the data back to the user.
AKA:
User => ENDPOINT => ENDPOINT 1, ENDPOINT 2, ENDPOINT 3, => ENDPOINT => User
Is this how I should do it?
P.S. I don't know if this the right terminology but I'm trying to learn how to scale my ENDPOINTS/API/code.
About the load balancer, you should use specific web server applications to do that, like nginxor apache. This kind of web server tools already have implemented load balance mechanisms, you just need to configure it.
Also, I recommend you to pack your server in docker images. This way you could use Docker Swarm or Kubernetes to deploy and scale up/down your application. It's easier to manage your services, check applications states and deploy new versions.
You could use docker with nginx, where each docker container has an instance of your application and nginx will take care of redirect/distribute your requests between your instances.
What you are basically looking for is a comparison between microservices based architecture (or SOA) and a monolith.
In microservices, there are multiple services performing specific tasks. They all in-turn are used to perform complex tasks. Monoliths on the other hand consist of a big server which does everything and is also the single point of failure like your pointed.
Should you move to microservices?
It is widely agreed that a project should be built in monolithic architecture and then moved to microservices as the complexity grows. Martin Fowler's article explains this concept well.
This is because there are certain disadvantages and tradeoffs associated with this architecture -- inconsistency and latency, for instance.
TLDR; Stick to one server if starting, break into services when it becomes complex.

Node.js scalability in typical web applications

As Node.js beginner coming from Enterprise IT, I am unable to comprehend one aspect of node.js usage. I am framing my question in two parts.
Question-1) Strictly from scalability standpoint, how can an I/O heavy web application scale using node.js unless we scale back-end I/O resources that it is consuming?
A database server can serve only "X" number of concurrent users. Even if node based HTTP server is able to handle more incoming requests, overall throughput is going to be dictated by number of concurrent connections DB can handle.
Same applies for other enterprise resources like content retrieval from file servers or invocation of legacy APIs etc. I understand that we would be less worried about cloud resources which can elastically scale and are not in our direct purview.
Question-2) If answer to above question is "Node is not one-size-fit-all solution", how are companies like PayPal, Walmart, LinkedIn et al able to gain scale using node? They too would integrate within their existing system landscape, and are not totally network based applications (or are they?).
Node.js is typically used as an orchestration layer in SOA.It is mainly used as front-end for the backend services.It is true that
the throughput is going to be dictated by number of concurrent connections DB can handle but there is also the time involved
for the presentation layer to present the content.
Web technologies like JSP,Ruby on rails are designed to get the content on the server and serve as a single page to the client and are not suited for orchestration layer.Today we need services that handle mobile clients(where there are lot of API calls to retrieve small amount of data)Thus node.js reduces the response time and increases the user expierence.
Look at http://nodejs.org/video/ video by Eric Hammer to understand how Node.js is being used in Walmart.

NodeJS horizontal scaling

I've been a ruby/php web application developer for quite some time and I'm used to the idea of horizontal scaling of server instances to handle more requests. Horizontal scaling - meaning separate instances of an application sitting behind a load-balancer that share nothing and are unaware of each other.
The main question I have is, since Node.js and it's emphasis on evented-io allows for a single box running a node.js server to handle 'thousands' of simultaneous requests - is load-balancing/horizontal scaling used to scale nodejs applications? Is scaling a node app limited to vertical scaling (throwing more RAM/Processing power at the problem)?
My second question has to do with node.js horizontal scaling and websockets. I've seen quite a few Node.js 'chat' tutorials out there that make use of websockets.
(favorite: http://martinsikora.com/nodejs-and-websocket-simple-chat-tutorial)
Since websockets effectively keep an open line of communication open between a browser and a server, would a horizontally scaled architecture typical of the PHP/Ruby world cause a chat application like the one explained in the link to break - as new websocket connection requests would be assigned to different processes/servers and there would be no one central resource tracking all connected clients?
Node.js supports horizontal scaling in much the way you describe via the built-in cluster module.
Regarding your second question about the use of websockets/socket.io in this environment, you have to use something like Redis to store shared state across multiple instances of your application as described here.
Node.js's cluster functionality is limited to single server with multiple processor. Mainly it leverages number of processors in server. I think the question if more about the scenario when we want to scale horizontally with multiple servers with a Load balancer facade.
If you have node.js instances spread across multi servers(horizontal scaling), it will serve the same purpose, you need to program it properly to support this type of setup.

Resources