RU EN

Grafana k6 and ASP.NET Core: A practical guide to Load & Stress Testing

Автор:
Источник:
Просмотров:
352
Grafana k6 and ASP.NET Core: A practical guide to Load & Stress Testing favorites 0

Performance testing is a critical aspect of the development process, it helps ensure that our applications can handle varying levels of traffic and deliver a smooth user experience under heavy loads.

In this article, we will explore how to perform load and stress testing on ASP.NET Core 6.0 applications using Grafana k6, an open-source performance testing tool.

Grafana k6 and ASP.NET Core

Understanding load and stress testing

Load and stress testing are both types of performance testing, but they focus on evaluating the performance of a system under different levels of load and stress conditions. Let’s understand each of them.

Load testing

Load testing involves assessing the performance of a system under expected and anticipated user loads. The main goal is to determine how well the system performs when multiple users access it simultaneously.

Key aspects

  • Scenarios: Test scenarios are designed to simulate real-world user behavior and usage patterns, including different types of user actions (e.g., browsing, searching, purchasing).
  • Load Levels: Gradually increase the number of virtual users (simulated users) to apply load on the system and observe how it responds. The load can be constant or vary over time (ramp-up or ramp-down scenarios).
  • Metrics: Common metrics in load testing include response time, throughput (transactions per second), error rates, and resource utilization (CPU, memory, etc.).
  • Objective: The primary objective is to ensure that the system meets performance requirements, maintains acceptable response times, and handles the expected number of users without crashing or degrading significantly.

Stress testing

Stress testing, on the other hand, assesses the system’s behavior under extreme conditions beyond its normal operating capacity. The goal is to identify the system’s breaking point, where it starts to exhibit performance degradation or fails altogether.

Key aspects

  • High Load Levels: Apply a load that exceeds the system’s designed capacity, testing its resilience and ability to recover from such conditions.
  • Breaking Point: Aims to find the point at which the system starts to exhibit issues, such as increased response times, errors, or crashes.
  • Recovery Testing: After reaching the breaking point, stress tests may evaluate how well the system recovers once the load is reduced to normal levels.
  • Objective: The primary objective is to identify the system’s weaknesses, bottlenecks, and failure points, allowing developers and administrators to make necessary improvements and enhance the system’s robustness.

Why Grafana k6?

k6 is a powerful and user-friendly load-testing tool that has gained significant popularity in the developer community. It offers a simple yet expressive JavaScript scripting language, making it easy to write and maintain test scripts. With its support for modern protocols and ability to scale to thousands of virtual users, k6 is an excellent choice for load and stress testing in .NET applications.

Setting up the environment

Let's install Grafana k6 by following the official installation guide.

Writing load test scripts

Using k6, we can create test scripts that simulate user behavior and generate realistic loads on our application. It allows us to define scenarios, set up HTTP requests, and perform assertions to validate the responses.

Let's create a JS file called load_test.js:

import http from 'k6/http';
import { check, sleep } from 'k6';

export let options = {
    stages: [
        { duration: '1m', target: 100 }, // Ramp-up to 100 virtual users over 1 minute
        { duration: '3m', target: 100 }, // Stay at 100 virtual users for 3 minutes
        { duration: '1m', target: 0 },   // Ramp-down to 0 virtual users over 1 minute
    ],
    thresholds: {
        http_req_duration: ['p(95)<300'], // 95% of requests must complete within 300ms
    },
};

export default function () {

    var response = http.get('https://localhost:7071/api/books'); // HTTP Get all books

    check(response, {
        'is status 200': (x) => x.status === 200 // An assertion
    });

    sleep(1); // Wait for 1 second between each request
}

For more info about stages and configuration.

Writing stress test scripts

Creates a JS file called stress_test.js:

import http from 'k6/http';
import { check, sleep } from 'k6';

export let options = {
    stages: [
        { duration: '5s', target: 5 },    // Stage 1(5 seconds): Ramp - up to 5 virtual users over 5 seconds.
        { duration: '30s', target: 5 },   // Stage 2 (30 seconds): Stay at 5 virtual users for 30 seconds.
        { duration: '5s', target: 50 },   // Stage 3 (5 seconds): Ramp-up to 50 virtual users over 5 seconds.
        { duration: '30s', target: 50 },  // Stage 4 (30 seconds): Stay at 50 virtual users for 30 seconds.
        { duration: '5s', target: 100 },  // Stage 5 (5 seconds): Ramp-up to 100 virtual users over 5 seconds.
        { duration: '30s', target: 100 }, // Stage 6 (30 seconds): Stay at 100 virtual users for 30 seconds.
        { duration: '5s', target: 300 },  // Stage 7 (5 seconds): Ramp-up to 300 virtual users over 5 seconds.
        { duration: '30s', target: 300 }, // Stage 8 (30 seconds): Stay at 300 virtual users for 30 seconds.
        { duration: '5s', target: 0 },    // Stage 9 (5 seconds): Ramp-down to 0 virtual users over 5 seconds.
    ],
    thresholds: {
        http_req_duration: ['p(95)<1000'], // 95% of requests must complete within 1000ms
        http_req_failed: ['rate<0.1'],     // Request failure rate should be less than 0.1%
    },
};

export default function () {
    var response = http.get('https://localhost:7071/api/books'); // HTTP Get all books

    check(response, {
        'is status 200': (x) => x.status === 200 // An assertion
    });

    sleep(0.1); // Wait for 0.1 second between each request (adjust as needed for higher stress)
}

ASP.NET Core API folder structure

ASP.NET Core API folder structure

How to run the tests

The first thing we need to do is to start our API, let’s run dotnet run -c release

dotnet run

Let’s proceed with the test. To begin, open a new console window and navigate to the API folder. Next, execute the following k6 command in the console:

k6 run load_test.js

k6 run

During the test execution, k6 will collect various performance metrics, including response times, throughput, and error rates. These metrics will help us assess the application’s behavior under load and identify any performance bottlenecks.

The process above it is only for the load tests, If you want to run the stress tests, just run k6 run stress_test.js

Analyzing test results

After the load and stress tests are complete, it’s time to analyze the results. Grafana k6 provides detailed reports and visualizations that help us understand the application’s performance characteristics. We can inspect metrics like response time distributions, error rates, and trends to pinpoint areas that need improvement.

Test results

http_req_duration, the end-to-end time of all requests (that is, the total latency).

http_req_failed, the total number of failed requests.

iterations, the total number of iterations.

Based on the insights gained from the test results, we can fine-tune our application, optimize its performance, and make it more resilient to handle higher user loads.

Final thoughts

Grafana k6 is a powerful tool that helps us to ensure our applications can handle the expected user loads without compromising performance. We can simulate realistic scenarios, analyze performance metrics, and identify and address potential issues before they impact the final users.

For more info: https://k6.io/docs/

Похожее
24 марта 2024 г.
Автор: Иван Якимов
Недавно я натолкнулся в нашем коде на использование пакета MediatR. Это заинтересовало меня. Почему я должен использовать MediatR? Какие преимущества он мне предоставляет? Здесь я собираюсь рассмотреть эти вопросы. Как пользоваться MediatR На базовом уровне использование MediatR очень просто. Сначала...
Aug 15, 2021
.NET has a large number of built in exceptions. However, there maybe times when none of the built exceptions seem adequate for your particular scenario and you will need to create your own custom (AKA “user defined”) exception. This post...
Feb 19, 2024
Author: Anji Keesari
Introduction Website downtime can be a critical issue for companies in industries such as Insurance, Healthcare, Finance, and Banking, especially for applications that are mission critical. It can lead to inconvenience for users and potentially result in significant financial losses....
Apr 16, 2022
Author: Matthew MacDonald
Sometimes it’s the little things that count. When .NET 6 dropped this November, a few top-line items grabbed all the attention. I’m talking about C# 10, hot reload, Blazor’s AOT compilation, and some serious inner loop performance improvements. All of...
Написать сообщение
Тип
Почта
Имя
*Сообщение
RSS
Если вам понравился этот сайт и вы хотите меня поддержать, вы можете
Почему сеньоры ненавидят собеседования с кодингом, и что компании должны использовать вместо них
Почему программисты не стареют: эффект кодера после 40
Soft skills: 18 самых важных навыков, которыми должен владеть каждый работник
Using a сustom PagedList class for Generic Pagination in .NET Core
Семь итераций наивности или как я полтора года свою дебютную игру писал
Вопросы с собеседований, которые означают не то, что вы думаете
Как сделать полезный дашборд: советы и идеи
Жестокая правда будней программиста: 8 наблюдений
Задача по языку C#: Игра «Крестики Нолики» в консоли
Как мы столкнулись с версионированием и осознали, что вариант «просто проставить цифры» не работает
Boosty
Donate to support the project
GitHub account
GitHub profile