Become a JMeter and Continuous Testing Pro

Start Learning
Slack

Test Your Website Performance NOW!

arrow Please enter a URL with http(s)
Nov 02 2014

Overcoming Scale and Load Challenges: 5 Guidelines for Web-App Developers. Part 1

The once far-fetched notion of starting from nothing and making it big has become much more attainable over the past few years. Web-scale environments have given startups the ability to obtain millions of users in extremely short periods of time (just take a look at sites like Facebook and AirBnB).

 

However, Apple’s failure with the iPhone 6’s big launch, was proof that the system is in need of a better web-scale platform. This shows us the importance of implementing preventative measures to ensure web-scalability from the get-go. It’s vital that web-scale developers keep all of these considerations in mind to maintain a robust environment from the start - and support future growth of any size. That way they won’t have to constantly fix issues that could have been avoided in the first place. It’s no easy feat to develop an application for a considerable number of users and maintain it while allowing your IT team to respond to unexpected events.

 

If you want to succeed here, you need to understand the following:

 

 - All resources are limited. Always remember that any action you perform requires resources that cost money. (We’ll elaborate on the kinds of resources later on).

 

 - Set your resources free after use. If you have resources that aren’t necessary for a current request, but rather for a background process, it’s in your best interest to move them or perform manipulations that don’t require changing code.

 

The following 3 guidelines will help you enable and maintain efficient web-scalability:

 

 

1. Memory Allocation

Memory leaks are notorious for causing service performance degradation, and can eventually cause failure. So, proper memory allocation is crucial if you want to maintain efficiency as well as performance.

 

Let's say that a user asks for a list that, for whatever reason, needs to be filtered in an application itself, not in the database. You’ll need to first request the specified data from the database so you can start filtering it. Getting the list into memory entails requesting the required memory from the system. If your programming language calls for you to explicitly allocate the requested memory and doesn't garbage collect it by itself, it’s your responsibility to then free the disk memory when sending the data back to the user. If this isn’t done, all of the memory that was requested to perform the task won’t be available for other requests. If you used 100K of memory for the particular table at hand, you can kiss that memory goodbye unless you restart your application. Needless to say, this is a far from ideal situation. After a number of similar requests, your application will run out of memory, which can lead to application and even machine failure.

 

It is important to note that most modern programming languages already manage memory allocation and release. However, some applications require critical run-time responses and therefore need to be written in C or C++, unless another 3rd party code/app is used, risking the chance of a bug. For example: if it turns out that openSSL has a memory leak in certain scenarios, you’re going to experience the bug (even if it’s not your fault). Though you may not be able to fix it, you should at least be aware of the application's (SSL, C, C++) behavior.

 

2. Log Sprawl

Logs tend to use an unnecessarily large amount of disk space. They are very important in any application, documenting everything that happens - errors and all. Even if you can’t fix the documented errors in real time, being aware that an issue exists may help you prevent future errors from occurring. Unfortunately, logging this information requires a lot of disk space, which in turn poses the demand for lower storage costs or smarter lock utilization.

 

Another type of situation may entail inspecting certain messages, meaning every action performed on the system will need to be documented in log files. This is done in debug mode. Here, you can find out how data is managed, what a user requested, and the actual results that were sent. While it’s nice to have the debug mode as an option, it’s not a viable permanent solution due to its excessive use of disk resources. In order to allow your IT team and developers to deal with tricky logging issues, they need to be able to choose the proper system mode for each given situation.

 

Avoid the Sprawl:

 

Log Store Location: The most important thing you can do for this is allow configuration files to be updated in real-time and setup log files to automatically change location. Even if a minor problem starts occurring on a more frequent basis, your log files might grow rapidly and cause your application to fail, at random, due to insufficient disk space. Therefore, you should store your log files on a separate dedicated disk and not in the same file system as your application. Additionally, I’d recommend preparing to move your log files on the fly. That way if a serious problem arises that requires further research, you can simply allocate your log to a larger disk and continue capturing every little thing that happens in the system.

 

Systems should allow you to move between modes according to the current state of affairs. The error-only mode is used under normal circumstances, whereas the enhanced information and debug modes are used when detecting the source of an error, so you can easily and safely find the “firing gun”. On the other hand, contradictory systems endlessly write error logs and circulate bug information, causing you to write to one file and copy data, from time to time, to another archived file. In addition, when the first log file reaches its capacity, the system will completely clear the next file and start writing to it. This circulation creates a limited amount of space that can be useful if an important issue comes up that you want to inspect.

 

Priority: Certain incidents create logs, such as warnings, bugs, and even accidentally leaving a running debugging tool in production. The bottom line is that log files’ physical locations should be configurable. Additionally, every message sent to a log should be prioritized. This is important because in some cases, we only need specific information from logs, such as errors or warnings, and need to know where to find the respective messages.

 

3. Open User Sessions

Many applications store their user session information in memory and not in physical storage, depending on the required communication and performance.

 

For example, bank sessions are very short, as opposed to Facebook sessions that can last for weeks (the session key is not saved in memory but in the database). If there is no activity in a bank session for a few minutes, you’re automatically disconnected. As a result, many applications that require short sessions simply store the session information, along with your credentials and other important data, in their memory. If these resources aren’t released, a memory leak can occur, causing endless sessions that result in the server being unable to accept new sessions or requests. This, as mentioned above, will lead to unresponsiveness.

 

There are two ways to know when to close a connection. The first is when users explicitly request to disconnect by clicking the logout button and the other occurs on the application’s end when the server detects inactivity (no requests or keep-alive requests for a certain amount of minutes) and disengages the session key itself. For example, if a user closes the browser, without logging out of the application, no request will be sent to close the session. Therefore, the server should identify idle sessions, in line with the length of time stated in the company's policy, and automatically log off accordingly. Subsequently, the disconnected session's memory will be removed, meaning if the user wants to continue using the application, he/she will have to log in again.

 

The guidelines above can be used to better manage memory allocation, log sprawl, and open user sessions. In part two of this series, I’ll cover how to handle holding multiple database connections and http requests per minute. These final guidelines will lead us to an all encompassing solution to keep loads under control and applications scalable.

 

Want more infornation and training now? Check out our educational resource center for web-app developers.

 
     
arrow Please enter a URL with http(s)

You might also find these useful:

Interested in writing for our Blog?Send us a pitch!