3.2 KiB
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).
- Clone the repository:
git clone https://github.com/psun256/enginewhy.git
cd enginewhy
- Build the application:
cargo build --release
- 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.
- Clone the repository:
git clone https://github.com/psun256/enginewhy.git
cd enginewhy
- Build the application:
docker build -t enginewhy .
- 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.