How to implement horizontall scalability using NodeJs - javascript

So, I've web application which structure is based on this file structure: https://scotch.io/tutorials/setting-up-a-mean-stack-single-page-application .
My app also has a connection to mongoDB on Mlab.
what my app does:
allows users to login/signup;
retrieves data from mlab;
retrieved data can be rated by users;
retrieved data can be deleted by admin;
users can add data to db (data is training plans);
Now I need to make my app horizontally scalable, but I am a bit lost here:
•Sine I assume there i no real-time activities I shoudn't need something like socket.io?
•Should I add some sort of MQ (rabbitMQ, ZMQ, etc.): If so, perhaps any pointers on how to, because most of the examples just use simple text messages.
•I am quite sure I would need some load balancer. Nginx, HaProxy... I probably should change my express server setup to listen to multiple ports first, is that right?
Or am I completely wrong about this?
P.S.: Hope this isn't too broad question.

Different needs require different approaches :)
These can vary according to your needs. Not every scalable application has to have them.If you want the application to be asynchronous, you can take all the requests in a queue and return to the client instantly.You may then need a push mechanism to notify the client that the operation is over. (Socket.io, RabbitMQ etc)
Of course you will need a reverse proxy to distribute requests to different servers load balanced or workload basis (HAProxy etc.)
The first thing you need to pay attention to when you want to scale the application is to have a stateless structure.Or get them out of the process.(For example session, cache, file server)The second thing you need to be aware of is the authentication phase.A client that logged in from ServerA may encounter "unauthorized" on ServerB on subsequent requests.You should also think about the resources used by the application.While these resources serve a single server, they will begin to respond to millions of requests from five to ten servers simultaneously.There are things like monitoring instances.And a lot of things like that.
These are the things you should really think about :)

Related

Socket.io Performance optimisation 15'000 users

I have a chat application with huge chatrooms (15'000 user connected to one single room).
Only few have the right to write, so theoretically there should not be a huge load.
I have noticed that there are performance issue: when only one message is send, the server CPU load spikes to 30%-50% and the message gets delivered slowly (maybe 1 second later or worse if you write multiple messages)
I have analysed the performance with clinic-flame. I see that this code is the problem:
socket.to("room1").emit(/* ... */); which will trigger send() in engine.io and clearBuffer in the ws library.
Does someone know if I am doing something wrong and how to optimize the performance?
You can load balance sokets.io servers.
I haven't do this yet, but you have informations about doing this here: https://socket.io/docs/v4/using-multiple-nodes
If you use node.js as http server : https://socket.io/docs/v4/using-multiple-nodes#using-nodejs-cluster
Alternatively, you can consider using redis for that. There is a package that allow to distribute trafic on a cluster of process or server:
https://github.com/socketio/socket.io-redis-adapter
You do not have to manage load balance if you have up to 15k to 20k Users, follow the below instructions.
In socket code do not use await async.
In socket code do not use any DB query.
Use a socket to take data from someone and provide those data to others, if you want to store those data do it using APIs before or after you send it to the socket.
It's all about how you use it. queries and await all this will slow your response and load, there is always a way to do things differently.
The above 3 suggestions boost my socket performance, I hope it does the same for you.

Should I use WebSocket for this use case

I kind of new for WebSocket and would like to ask you guys a question if WebSocket is really the best way I should go.
Use case. Clients need to submit different kinds of jobs, e.g. J1, J2, J3, ... to server API through web GUI and the server will do or distribute to other computational resources to accomplish the jobs, however the server needs to update each Client the progress of the jobs they submit. One very simple example is that, if Client A wants to upload a big file, and server needs to notify the progress of the uploading until it is fully uploaded. I do think this is a very common use case.
The way I am doing now is to use HTTP polling, i.e. query status from Client side every 1s to get status from the server and display. I do think there must be other more efficient way of doing this, and I come up with WebSocket way. However after doing some reading, WebSocket's best use is to real-time broadcast same data to all subscripters, e.g. updating a certain stock price in a given channel.
Do you guys think if WebSocket is the right way to go? if so, how should I build the channel for different Clients and different types of jobs, or any other suggestions?
thank you.
WebSocket may be a solution if you require real-time notification. You don't need different channels for each job, you just need messages that allow you to multiplex on server-side and demultiplex on client-side.
You should take into account that each opened WebSocket uses resources on the server, so you should consider the average workload.
On the other hand, if you don't require real-time notifications, loose polling may be a better solution.

What is the best way to update all clients when Flask database changes without polling?

Currently I have a Flask server that runs a small web frontend as well as a command line interface to that same server. The basic idea looks like this:
<Top section: allows file upload>
* list of files from database
<Second section: allows file manipulation/ upload>
* list of files from database
<Third section: Not files, but still allows for database changes>
* list of things made from database
Now this works well from the front end, but currently if the CLI or another client makes a change to the database, it doesn't update other clients. I have it somewhat working with JS polling and rewriting the list of files every 10s, but that seems both inefficient and also would look very messy if I had to do it for every section. I saw websockets mentioned in various forums, but I've never used them and am unsure if it would be a pain to add. I'm not trying to rewrite the whole thing for a single feature.
Final takeaway: How to update all clients better than polling/ how to do polling efficiently?
Yes you are correct. You need sockets. There are bunch of articles over the internet but I would like to give a summary and try to explain why sockets will be the best fit to your requirements.
Sockets are way of achieving two way communication between client and server without the need of polling.
There is a package called Flask-SocketIO
Flask-SocketIO gives Flask applications access to low latency
bi-directional communications between the clients and the server.
Then for the scenario where you would like to send changes to all the connected client when one client does some work to your database or something similar, you will need to use broadcasting. When a message is sent with the broadcast option enabled, all clients connected to the namespace receive it, including the sender. Here you can find details of the broadcasting using Flask-SocketIO.

Secure db queries in single page web app

I'm creating single page web app with ArangoDB for storage. Arango provides awesome ways for accessing and manipulating data. One of them is classic JS API. It would be easy to write straightforward DB queries in client side JS which would be direct queries for DB. So no server application in middle.
Of course, this is really unsecure pattern. So I should write some sort of REST-full API service that queries data from server via URL and later server queries the DB. But this is really inconvenient, since I'd need to write two or three times more code (first query for my server, second query for DB, and perhaps some translator between the two queries). Also, I think that API calls for my server would look almost same as API calls for DB.
I don't want to go for full abstraction since the app should be complex and there would be a lot of types of API request, which would only bring bugs and eat more time.
So what is the best way for requesting data in client app from DB in terms of, firstly, security and, secondly, ease of coding?
I'd really suggest to write REST API calls (or generally URL calls) to access your data. Anything what run on the client side or any traffic from the client can be accessed and manipulated. That comes with authentication and SQL calls themselves.
What you want to secure? DB client authentication? If you encrypt it, you need to decrypt it on the client side. SQL calls - if you build and transmit them, the client could manipulate them to get / update ANY data with ANY values. Really no easy way around..
So - to be safe - stick to the patterns here..
I found a GraphQL with Relay by Facebook which solves this problem best.

What's the best way to retrieve messages from the server for a chat application

I'm writing a chat application from scratch, and I'm trying to figure out the best way to retrieve messages from the server in real time. I've done a fair amount of research, and have come up with this: I could use web sockets, and I've seen it done before successfully. I could use long polling, but I'm wondering if that places greater stress on the server, or maybe is just not right for a chat application. I could poll the server every second, but that just seems like a waste of bandwidth. Suggestions? Thank you!
The websocket protocol is ideal for something like a chat application for several reasons.
As you've already identified, continous polling of the server is quite a waste of resources.
Using traditional HTTP requires the use of bulky headers which waste valuable bandwidth. Websockets allow for lean messaging.
Most importantly for your application, unlike HTTP, websockets are bi-directional, meaning that your server can independently send messages to your chat client. With HTTP, all communication must be initiated by the client, and you are restricted to a request-response type of communication. With websockets, if your client receives a message from another user on your chat service, the server can immediately and independently relay that information to the intended recipient.
So to answer your question. You should definitely go with web sockets. Since you lack traditional headers, you will have to do a bit of work when it comes to formatting the messages sent over the connection, but the efficiency is well worth the minimal effort it takes to set up your messaging model.
What? Do you need to and from a database on a dedicated server?
I would recommend Ajax with JavaScript or jQuery but i like to do my own coding so JavaScript.
If your showing data back and forth match i would probably use MySQL.
For example to query up the last known query if matches current then would not be updated.
If doesn't match loop up from last to rent match would be DESC if in Order by type. Anyways...
Hope this helps you decide on what you should use.
Although this is what is common on games, blogs, forums, chats with MySQL/SQL.

Categories

Resources