High load architecture: How to develop high-performance scalable applications
In custom web app development, focus on building a high-performance scalable architecture. Even if your project is rather small, at some point there may be an influx of users or you may need to scale. If your system doesn’t flexible and can’t support high loads, it has high chances for failure.
Some facts you should know about high load:
- Highload starts when one physical server becomes unable to effectively carry out data processing
- If one instance serves 10,000 connections at the same time – it’s high load
- Highload is about a simultaneous service of thousands and millions of users
- If you deploy your web application on Amazon Web Services (AWS), Microsoft Azure, or Google Cloud Platform, you’re maintaining a high load architecture
What generally happens, when the system doesn’t withstand high loads:
- Slow or endless page loading
- Random errors
- Disconnected connections from the web server
- Partial content loading (for example, there are no some images)
- Reduced user audience activity and client losses as a result
For these reasons, you’ll have to pay a lot of efforts for maintaining and scaling a web application, thus wasting time, costs, and energy and losing clients.
Keep in mind that the architecture of a web application defines 95% of the success of the entire work. That’s why it’s so important to build an easily scalable server architecture that will be able to handle high loads.
To develop successful large-scale web applications, you need to understand the principles of building high-performance software.
Principles of developing high-performance applications
Dynamics & Flexibility
You never know what will happen with your application tomorrow. Perhaps, the number of your users will increase 10 times. Or some minor product feature will start gaining popularity when no one expects. As a result, you will face problems associated with the necessity to expand the project.
When building large-scale web applications, the main focus should be made on flexibility which will allow you to easily implement changes and extensions. Flexibility, no preliminary planning of all aspects, is the most important characteristic of any fast-growing system.
Gradual project growth
It’s difficult to predict the audience size for the years to come, so it’s better to move focus to scalability. The same goes for the application architecture. Gradual solutions are the basis for successful custom web app development.
If you are running a new application, it makes no sense to immediately provide an infrastructure that can withstand millions of users. Use the cloud to host new projects, as it allows to reduce the cost of the server and simplify their management.
Also, many cloud hosting services provide private network services, enabling programmers to safely use multiple servers in the cloud and make the system scaling.
Scaling of any web application is a gradual process that includes 4 steps:
- Load analysis
- Determination of the areas most affected by the loads
- The transfer of these areas to individual nodes and their optimization
- Load analysis
Building a high-performance scalable architecture
Generally, a new application is run on a single server, running the web server, database, and the application itself. This approach for custom web app development is reasonable as it helps save time and reduce costs.
You don’t build a large project from the very beginning (if it doesn’t suppose having a lot of users), but focus on project scalability and choose a powerful server that will be able to handle high loads if required.
However, the goal of many projects is to attract thousands and millions of users, provide rich user experience and quality services, and earn money. E-commerce solutions, customer portals, AR gaming apps, online consulting services, social networking solutions, dating apps, – the list is long.
All of these examples suppose having a large audience and require using various optimizations allowing to withstand high loads. First of all, let’s consider ways that will help you build large-scale and high-performance web applications.
Database separation
Most often, it’s the first node which is under load is the database. Each request from the user to the application is usually from 10 to 100 database queries. Database branching on a separate server will increase its performance and reduce the negative impact on other components (PHP, Nginx, etc.).
Database migration
In some cases, moving the database to the other server can be a problem for the working application. For database migration, you can make the following things:
- Use a simple solution – place an announcement about planned work on the site and make a transfer. It’s better to do it at night when the user audience activity is minimal.
- Use replication to synchronize data from one server to another. After configuration, you should change the database IP address in the application to the new server. And then – turn off the old server.
Separation of the web server
Next, you should separate the web server, which allocation to a separate node will enable to leave more resources for the application.
Concerning the example with PHP, you should configure the application deployment to both the Nginx server and the server with PHP, representing backend.
Then Nginx itself will give the static files, and the PHP server will only be occupied with scripts processing. Nginx enables the connection to the backend by IP address:
server {
server_name ruhighload.com;
root /var/www/ruhighload;
index index.php;
location ~* \.(php)$ {
fastcgi_pass 10.10.10.1:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
}
Note, that if you use file loading, you will need to allocate the file storage to a separate node.
Using several PHP backends
When the load increases, a web application starts working more slowly. At some point, the reason will lie already in the implementation itself. To avoid such issues you should use several PHP backends.
When installing backends, make sure they have the same configuration. Use Nginx to balance the load between them. For this purpose, you should define the list of backends in upstream and use it in the configuration:
upstream backend {
server 10.10.10.1;
server 10.10.10.2;
server 10.10.10.3;
}
server {
server_name ruhighload.com;
root / var / www / ruhighload;
index index.php;
location ~ * \. (php) $ {
fastcgi_pass backend;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $ document_root $ fastcgi_script_name;
}
}
Once you start using several backends, requests from the same user will be sent to different servers. This will require a single repository for all sessions, for example, Memcache.
A simple, but important thing you should make is to connect cache servers. Memcache will independently distribute the load between the servers by using a constant hashing algorithm.
Task queues & DNS balancing
Task queues enable to perform heavy operations asynchronously, without slowing down the main application. While the queue server will receive tasks from the application, other servers handle tasks.
If the average number of tasks in the queue is increasing, you should increase the number of servers too. It will help you balance the load.
DNS supports balancing based on Round Robin, enabling to specify multiple IP addresses of receiving web servers, called frontends. Here you need to install several identical frontends so that DNS will give different IP addresses to different clients. This way, you ensure balancing between the frontends.
File storages
File uploading and processing generally occurs on the backend side. When there are several backends, it becomes inconvenient, as developers have to remember on which backend they upload each file.
Also, it can significantly reduce the backend performance. To avoid such difficulties, you should use separate servers for loading, storing, and processing files. You can make it in the following way:
- Define a separate subdomain for the file server
- Deploy Nginx on the server and a small application that can store files and process them is required
- Make scaling by adding new servers and subdomains (for instance, images1, images2, images3, etc.)
- Transfer the file load to the client side so that the form will send a request to a certain server
There is no big deal to create an application, that proportionally scales across servers as traffic flow grows. Stateless everything, load balancing, 90% cached, content delivery network, and so on – and you have a high load architecture.
However, cost-effectiveness is the key. Imagine that you have 100 thousands of users and one server. So, in order to obtain 120 thousands of users, you need to place another server. Quite complicated, isn’t it?
So, you should take one step behind and think – which part of the system causes a problem under load? If it’s a database, choose a high-scalable one before starting the project. Or take even several databases, for example, one for writes, one for reads (CQRS).
Defining and resolving performance issues in advance and without drastically increasing infrastructure costs – this is high load all about.
If you have some questions about the article, need recommendations, or have a project idea, apply to us and get a consultation for free! Having high expertise in delivering quality large-scale web applications, we are always ready to help you!