How to build a high load architecture for your web project?
Tags: webdev, architecture, discuss
Published: 2019-07-24 14:45:43

Choosing the right architecture for your web product is a crucial issue that you need to solve when thinking through its development. First and foremost, it should be scalable and be able to handle high loads. Especially if you’re making a functional website, online booking service, or an e-commerce solution. 

Remember Black Fridays which are so loved by people? Do you know that sometimes websites and web apps don’t manage to withstand such huge influxes of users and lose a lot of money? 

Perhaps, you also became annoyed when you had to wait for long seconds for the web page to load or when your transaction would be finally approved. And stopped doing business with the company that had provided you with poor customer experience. 

Slow page and partial content loading, crashes, random errors, disconnection with the Internet are the possible consequences of the lack of a high load architecture. That’s why the creation of a software system that can handle high loads matters. Even if your web project is rather small, at some point there may be an influx of users or you may need to elastically scale. 

<b>Take a look at some facts about high load:</b>

- A high load begins when one physical server becomes unable to effectively carry out data processing
- If one instance simultaneously serves 10,000 connections – it is high load
Highload is about a simultaneous service of thousands and millions of users
- If you <a href="https://smartym.pro/blog/software-project-development-how-to-scale-your-application-with-amazon-web-services/">deploy a web solution on AWS</a> (Amazon Web Services), <a href="https://en.wikipedia.org/wiki/Microsoft_Azure">Microsoft Azure</a>, or Google Cloud Platform, you’re maintaining a high load architecture


<b>You can face the following problems if your web solution doesn’t withstand high loads:</b>

- Slow or endless page loading
- Random errors
- Disconnected connections from the web server
- Partial content loading 
- Reduced user audience activity 
- Customer losses


As you can see, project architecture affects its success. No happy customers - no success and profit. To implement scalable web applications, you need to understand the principles of developing high-performance software solutions.

 
<h2>Principles of building high-performance solutions</h2>

 
<h3>Dynamics and Flexibility</h3>

You never know what exactly will happen with your project tomorrow. Or some minor product features will start gaining popularity when no one expects. 

Or you may need to add various features. Or you will decide to promote your application and attract customers. Therefore, you must be able to elastically scale and handle high loads.

When developing large-scale web solutions, focus on flexibility as it will enable you to easily make changes and extensions. Flexibility, no preliminary planning of all aspects, is the most important characteristic of any fast-growing software system.
 

<h3>Gradual project growth</h3>

It’s difficult to predict the audience size for the years to come, so it’s better to make focus on scalability. The same goes for the app architecture. Gradual solutions are the basis for successful software engineering.

If you are running a new product, there is no sense to instantly provide an infrastructure that can withstand millions of users and simultaneously process their multiple requests. 

Use the cloud to host new projects, as it allows them to reduce the cost of the server, facilitate their management, and easily deploy applications.

In addition, many cloud hosting services offer private network services, enabling software developers to safely use servers in the cloud and make the system scaling.


<b>Scaling of a web solution is a gradual process that has 4 main steps:</b>

- Load analysis
- Determination of the areas which are mostly affected by the loads
- The transfer of these areas to individual nodes and their optimization
- Load analysis


<h2>The development of a scalable web project architecture</h2>

In most cases, a new software solution is run on a single server, running a web server, database, and the solution itself. You don’t build a large complex project from the very beginning. Instead, focus on the product scalability and choose a powerful server that will be able to handle high loads if necessary. 

This approach will help you save time and reduce development costs. Below, you can see some ways that will help you make high-performance scalable web applications.
 

<h3>Database separation</h3>

Most often, it’s the first node which is under load is the database. Each request from the user to the application is generally 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, <a href="https://github.com/nginx/nginx">Nginx</a>, etc.).

 
<h3>Database migration</h3>

In some cases, moving the database to the other server can be a problem for the working web solution. You should make the following things to effectively migrate it:

- Use a simple solution – place an announcement about the 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.


<h3>Separation of a web server</h3>

Hereafter, separate the web server, which allocation to a separate node will allow to leave more resources for the application. In speaking of the example with PHP, you should configure the product deployment to both the Nginx server and the PHP server, 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:

<i>server {
server_name ruhighload.com;</i>

<i>root /var/www/ruhighload;
index index.php;</i>

<i>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;</i>
<i>   }
}</i>


Keep in mind that if you use file loading, you will need to allocate the file storage to a separate node.
 

<h3>Use several backends</h3>

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. To this end, you should define the list of backends in upstream and use it in the configuration:


<i>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;
   }
}</i>


When you start using several backends, requests from the same user will be sent to a different server. This will require a single repository for all sessions. 

You can choose, for instance, Memcache. Also, you should connect cache servers. Memcache will independently distribute the load between all the servers by using a constant hashing algorithm.
 

<h3>Task queues and DNS balancing</h3>

Task queues enable to asynchronously perform heavy operations, without slowing down the main application. While the queue server will be receiving tasks from the web solution, other servers will be handling them. If the average number of tasks in the queue will grow, increase the number of servers to balance the load.

DNS supports balancing based on Round Robin, allowing 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 will ensure balancing between the frontends.
 

<h3>File storages</h3>

File uploading and processing usually occurs on the backend side. Having several backends is totally inconvenient and inefficient, as software engineers have to remember on which backend they upload each file. 

Moreover, they can reduce backend performance. To avoid such difficulties, you should use separate servers for loading, storing, and processing files. 


<b>You can make it in the following way:</b>

- Define a separate subdomain for the file server
- Deploy Nginx on the server and a small application that can store files and process them 
- Scale by adding new servers and subdomains (for example, 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, a reliable content delivery network, and so on – and you have a high load architecture.

However, cost-effectiveness is the key. Say, you have 100 thousands of users and one server. So, to obtain 130 thousand of them, you need to place another server. It seems to be quite difficult, doesn’t it?

Therefore, you should take one step behind and think – which part of the system causes a problem? If it’s a database, choose a high-scalable database before beginning the project development. Or you can use several databases, for instance, one for writes and one for reads (CQRS).

Defining and solving such performance issues in advance and without a dramatic increase in infrastructure costs is an effective practice of ensuring high load.