Suppose we're building an SPA (Single Page Application) which depends on a couple of independent back-end systems. Basically a Microservices-esque implementation of SignalR-hubs.
Each of these back-end systems expose a separate SignalR endpoint with a separate set of hubs;
The separation of these hubs across different back-end systems is intentional in design and cannot be unified into a single one;
Basically, a single browser session to the app will have to maintain a separate SignalR-connection for each endpoint on which we depend.
From what we have gathered, this approach will not scale due to the fact - at this time of writing - most browsers seem to implement an arbitrary limit of concurrent websocket connections.
This leads us to the following questions:
Are we correct in our assumption that this will not scale in the browser?
If our assumption is correct, what are our options? Will we need to implement a single encompassing SignalR-endpoint?
Related
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.
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).
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.
I have a Node application which persists data to a MongoDB database. Most of this data is in hand, such as data for the User collection. However, the application also has the concept of Website collection, and for this collection, data must first be downloaded from somewhere before it is saved.
I am wondering how I should separate the above concerns in my application. At the service layer, I have things like User and Website. They provide basic CRUD operations. At completely the opposite end of the spectrum, there is a user interface whereby uses can input a website URL. Somewhere between this UI and the application persisting the data to MongoDB (the service layer), the application must make a request to this URL to gather some data. Once the data has been fetched, the Website service will persist it.
Potentially, there could be thousands of these URLs entered at once, and I do not want to bring down the Node process that handles the web server due to load issues. Therefore I think it would be a good idea to abstract the work out to a different process and use some sort of messaging bus to tie the application together.
It seems that you've decomposed system correctly -and have created that separation at the persistence "service" layer-, but I'd take this separation a bit further by moving toward a distributed system architecture (i.e. SOA / micro-services).
The initial step of building a distributed system is identifying each of the functions necessary to meet the overall business goal of the application and mapping these to service endpoints. Each loosely coupled service endpoint will then serve a small isolated job/function and it will act as an abstraction for that business goal.
By continuing the separation of responsibilities all the way to the service endpoint you create small independent boundaries for scalability, throughput, fault tolerance, security, deployment, etc.
For example -RESTfully speaking-, this might mean service endpoints for both Users (e.g. /users/{userid}) and Websites (e.g. /websites/{websiteid|url})... and perhaps an additional Resource to maintain the relationship/link between the two (e.g. /users/{userid}/userwebsites : {websiteid:1234,url:blah.com).
This separation would mean you can handle the website processing responsibility independently, which would have a number of benefits -beyond just handling the different load characteristics-.
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.