2025-12-18 18:52:28 -05:00
2025-12-18 18:52:28 -05:00
2025-12-10 23:54:54 -05:00
2025-12-10 16:28:51 -05:00
2025-12-18 18:52:28 -05:00
2025-11-06 13:03:00 -05:00
2025-12-18 18:52:28 -05:00
2025-12-18 18:52:28 -05:00

nginy

EngineWhy, also known as nginy, is a simple but flexible TCP load balancer.

Contents

Features

  • Multiple different load balancing algorithms
    • Round Robin
    • IP Hashing
    • Adaptive algorithm (based on this paper)
  • Cluster based backend grouping, and CIDR based client matching for fine-grained control.
  • YAML based config for readability and simplicity.
  • Automatic hot-reload of configuration without interruptions to service.

Getting started

Running as a standalone binary

You must have the latest stable Rust release (1.91 at the time of writing), and a valid configuration file (see Configuration for details).

  1. Clone the repository:
git clone https://github.com/psun256/enginewhy.git
cd enginewhy
  1. Build the application:
cargo build --release
  1. Run the application:
./target/release/l4lb -c path/to/config.yaml

Running as a dockerized application

You may also consider running the load balancer as a dockerized application.

  1. Clone the repository:
git clone https://github.com/psun256/enginewhy.git
cd enginewhy
  1. Build the application:
docker build -t enginewhy .
  1. Run the application:
docker run -v "path/to/config.yaml:/enginewhy/config.yaml" enginewhy

Configuration

Configuration file is written in YAML. By default, the program will look for a file named config.yaml in the working directory. You can change this by specifying the path with -c or --config when running the program.

The file consists of:

  • Defining the health response and iperf port (IP + port).
  • A set of backends (IP + Port for each).
  • A set of clusters, which act as group aliases for a set of backends.
  • A list of rules, which consist of:
    • Clients: One or more CIDR + port number, used to match incoming client connection
    • Targets: One or more clusters / backend names.
    • Strategy: A load balancing algorithm to use.
      • Some algorithms have additional configuration, like the Adaptive algorithm.

Sample configuration:

healthcheck_addr: "10.0.1.10:9000"

iperf_addr: "10.0.1.10:5201"

backends:
  - id: "srv-1"
    ip: "10.0.1.11:8081"
  - id: "srv-2"
    ip: "10.0.1.12:8082"
  - id: "srv-3"
    ip: "10.0.1.13:8083"
  - id: "srv-4"
    ip: "10.0.1.14:8084"

clusters:
  main-api:
    - "srv-1"
    - "srv-2"
  priority-api:
    - "srv-3"
    - "srv-4"

rules:
  - clients:
      - "0.0.0.0/0:8080"
    targets:
      - "main-api"
    strategy:
      type: "RoundRobin"

  - clients:
      - "10.0.0.0/24:8080"
      - "10.0.0.0/24:25565"
    targets:
      - "main-api"
      - "priority-api"
    strategy:
      type: "RoundRobin"

An incoming client will be matched with whatever rule has the longest matching prefix on the correct port.

Examples

You can find some examples in the examples directory of the project.

To run these, just run docker compose up.

Description
University of Toronto - Computer Networks -CSCD58 Final Project nginx-like load balancer in rust
Readme 1.9 MiB
Languages
Rust 97.1%
Dockerfile 2.9%