Skip to content

Latest commit

 

History

12 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

HTTP Балансировщик Нагрузки

Представляет собой HTTP-сервер, который принимает входящие запросы
и перенаправляет их на свободный и доступный Backend-сервер.
Адреса серверов должны быть заданы в Config-файле.

  • Использует стандартный HTTP-пакет net/http
  • Реализует ReverseProxy с использованием пакета net/http/httputil
  • Использует Redis для хранения Rate Limits пользователей

Архитектура приложения

  • Проект использует чистую архитектуру (API, service и repository слои)
  • В проекте реализован DI-контейнер (service_provider.go)
  • Для взаимодействия с сервисами используются интерфейсы, что позволяет легко заменять их реализацию
    а также упрощает процесс тестирования благодаря возможности генерации Mock-ов на основе интерфейсов

Фичи приложения

  • Реализован алгоритм балансировки Round Robin - доступ к Backend-серверам осуществляется по круговой очереди
  • Реализован Health Check - механизм, периодически проверяющий состояние каждого Backend-сервера
    (интервал настраивается в Config-файле)
  • Rate limiting на основе алгоритма Token Bucket (дефолтная настройка происходит в Config-файле)
  • Возможность установить кастомные Rate Limits конкретному пользователю через RestAPI
  • Асинхронная обработка запросов с помощью использования паттерна Worker Pool (Хоть и сервер на net/http по дефолту асинхронный, для примера был реализован WorkerPool и применен в api/loadBalancer/check.go)
  • Синхронизация работы в условиях конкурентных вызовов с помощью Mutex и Channels
  • Graceful Shutdown реализованный с помощью кастомного модуля Closer
  • REST API для получения добавления/удаления/изменения и получения информации состоянии Rate Limits пользователей
  • Redis для хранения данных о Rate Limits пользователей
  • Логирование информации о запросах и ошибках с использованием пакета slog

Rate Limiter

  • Использует IP в качестве уникального идентификатора каждого пользователя
  • Выделяет на каждый IP отдельный Bucket токенов
  • Настройка Bucket - происходит через Config-файл
  • Имеется возможность установить кастомный Config-файл конкретному клиенту (на уровне запуска приложения)
  • Логирование информации о состоянии каждого клиента по IP (каждый тик)
  • Атомарность операций с токенами
  • Использование RWMutex для минимизирования блокировок, обеспечивающих атомарность

Backend-сервер

  • Простая реализация сервера с двумя endpoints: "/" и "/health"
  • Возможность запускать на разных портах благодаря указанию флага -port

Redis | Плюсы в рамках приложения

  • Много операций чтения и мало операций записи - Redis отлично подходит
  • Приложение требует низкой задержки - Redis используется как кэш
  • Данные не являются особо важными, в случае чего их легко восстановить
  • В дальнейшем можно использовать TTL для автоматизированного и гибкого управления и хранения Rate Limits

RestAPI

  • Method=GET /clients - Получить список всех пользователей и их RateLimits
  • Method=POST /clients - Добавить пользователю кастомные RateLimits
  • Method=GET /clients/{id} - Получить информацию о RateLimits конкретного пользователя
  • Method=PUT /clients - Обновить данные RateLimits у пользователя
  • Method=DELETE /clients/{id} - Удалить RateLimits пользователя (установятся дефолтные из Config-файла)

Пример JSON-body запросов

  • Для Add и Update
{
    "id": "127.0.0.1",
    "capacity": 20,
    "refill_rate": 2,
    "interval": 2
}

Установка и запуск

Можно запустить двумя способами:

  • Запустить локально
  • Запустить через Docker

Предварительно нужно настроить config-файл

Пример настроенного Config-файла

loadBalancer:
    host: "localhost"
    port: "8080"

backends:
    addresses:
        - "http://localhost:9000"
        - "http://localhost:9001"
        - "http://localhost:9002"

healthChecker:
    interval: 2

rateLimiter:
    capacity: 10
    refill_rate: 1
    refill_interval: 5

workerPool:
    pool_size: 5
    queue_size: 5

Запуск локально

Для запуска локально потребуется запустить отдельно Backend-сервера, Балансировщик нагрузки и redis базу данных

Запуск Backend-сервера

Для запуска нескольких серверов на разных портах, нужно установить значение флага -port на любой открытый порт

    cd ./BackendServer
    go mod tidy
    go run cmd/main.go -port=9000

Запуск Redis

Предлагается запустить Redis внутри Docker

  docker-compose build redis
  docker-compose up redis

Запуск Балансировщика нагрузки

    cd ./loadBalancer
    go mod tidy
    go run cmd/main.go

Запуск через докер

Запуск через докер требует установленного и запущенного docker в системе, а также docker-compose

    docker-compose build
    docker-compose up

Пример нагрузки

При capacity = 100: пример 100% Complete Requests и быстрой скорости ответа

    ab -n 100 -c 50 http://127.0.0.1:8080/

При capacity = 100: пример 10% Complete Requests и быстрой скорости ответа

  ab -n 1000 -c 100 http://127.0.0.1:8080/

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages