Skip to content

Commit ebcdab8

Browse files
feat: first commit
0 parents  commit ebcdab8

22 files changed

Lines changed: 1506 additions & 0 deletions

.gitignore

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# If you prefer the allow list template instead of the deny list, see community template:
2+
# https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore
3+
#
4+
# Binaries for programs and plugins
5+
*.exe
6+
*.exe~
7+
*.dll
8+
*.so
9+
*.dylib
10+
11+
# Test binary, built with `go test -c`
12+
*.test
13+
14+
# Code coverage profiles and other test artifacts
15+
*.out
16+
coverage.*
17+
*.coverprofile
18+
profile.cov
19+
20+
# Dependency directories (remove the comment below to include it)
21+
# vendor/
22+
23+
# Go workspace file
24+
go.work
25+
go.work.sum
26+
27+
# env file
28+
.env
29+
30+
# Editor/IDE
31+
.idea/
32+
.vscode/
33+
34+
config.yaml
35+
36+
**/.DS_Store

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2025 Francisco De La Hoz
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 299 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,299 @@
1+
# Load Balancer in GO
2+
3+
<div align="center">
4+
5+
[Features](#features)[Quick Start](#quick-start)[Usage](#usage)[Configuration](#yaml-configuration-parameters)[Strategies](#load-balancing-strategies)[Health Checking](#health-checking)
6+
7+
</div>
8+
9+
---
10+
11+
## Overview
12+
13+
A **load balancer** built with Go that provides intelligent traffic distribution, automatic health checking, and multiple load balancing strategies.
14+
15+
## Features
16+
17+
- **Multiple Load Balancing Strategies:** Round Robin, Weighted, Smooth Weighted, Least Connections, Random
18+
- **Intelligent Health Checking:** Concurrent checks, recovery, configurable intervals
19+
- **Safe Architecture:** Thread-safe, graceful shutdown and logging
20+
- **Flexible Configuration:** YAML, environment defaults, minimal setup
21+
22+
## Quick Start
23+
24+
```bash
25+
git clone https://github.com/franciscodelahoz/load-balancer.git
26+
cd load-balancer
27+
go mod tidy
28+
go build -o load-balancer ./cmd/server
29+
./load-balancer
30+
```
31+
32+
## Usage
33+
34+
```bash
35+
go run ./cmd/server/main.go
36+
go run ./cmd/server/main.go -config=production.yaml
37+
curl http://localhost:8080/
38+
```
39+
40+
### Example Test Backends
41+
42+
```bash
43+
# Terminal 1
44+
python3 -m http.server 3001
45+
# Terminal 2
46+
python3 -m http.server 3002
47+
```
48+
49+
---
50+
51+
## YAML Configuration Parameters
52+
53+
All configuration is done via a YAML file. Below, each parameter is explained in detail, including its purpose and default value if omitted.
54+
55+
---
56+
57+
### **server**
58+
59+
- **port**
60+
*(default: `8080`)*
61+
Port on which the load balancer HTTP server listens.
62+
63+
### **load_balancer**
64+
65+
- **strategy**
66+
*(default: `"round-robin"`)*
67+
Load balancing algorithm. Options: `"round-robin"`, `"weighted-round-robin"`, `"smooth-weighted-round-robin"`, `"least-connections"`, `"random"`.
68+
69+
### **backends**
70+
71+
- **url**
72+
*(required)*
73+
The URL of the backend service.
74+
75+
- **weight**
76+
*(default: `1`)*
77+
Relative weight for distributing traffic. Higher values mean more requests sent to this backend.
78+
79+
### **health_check**
80+
81+
- **enabled**
82+
*(default: `true`)*
83+
Enables or disables health checking.
84+
85+
- **interval**
86+
*(default: `10s`)*
87+
How often to perform health checks (Go duration format, e.g., `10s`, `1m`).
88+
89+
- **timeout**
90+
*(default: `5s`)*
91+
Timeout for each health check request.
92+
93+
- **path**
94+
*(default: `"/health"`)*
95+
Path to request on each backend for health checking.
96+
97+
- **method**
98+
*(default: `"GET"`)*
99+
HTTP method to use for health checks.
100+
101+
- **success_threshold**
102+
*(default: `3`)*
103+
Number of consecutive successful health checks required before a backend is marked healthy.
104+
105+
- **failure_threshold**
106+
*(default: `3`)*
107+
Number of consecutive failed health checks required before a backend is marked unhealthy.
108+
109+
---
110+
111+
### **Examples**
112+
113+
**Minimal Configuration:**
114+
115+
```yaml
116+
backends:
117+
- url: "http://service-1:8080"
118+
```
119+
120+
**Full Configuration:**
121+
122+
```yaml
123+
server:
124+
port: 8080
125+
126+
load_balancer:
127+
strategy: "least-connections"
128+
129+
backends:
130+
- url: "http://service-1:8080"
131+
weight: 2
132+
133+
health_check:
134+
enabled: true
135+
interval: 30s
136+
timeout: 5s
137+
path: "/health"
138+
method: "GET"
139+
success_threshold: 5
140+
failure_threshold: 2
141+
```
142+
143+
---
144+
145+
## Health Endpoint Guidance
146+
147+
The load balancer marks a backend as *healthy* when the configured health endpoint returns an HTTP 2xx status. If your application responds with 200 OK for unknown or invalid routes, the health check will always succeed and give a false positive.
148+
149+
### Recommendations:
150+
- Expose a dedicated, lightweight health endpoint (e.g. /health) that returns 200 only when the service is actually healthy.
151+
- Return 404/4xx for unknown or invalid paths.
152+
- Keep health checks fast — avoid expensive operations.
153+
154+
### Quick test:
155+
156+
```bash
157+
curl -i http://your-backend/health # must return 200
158+
curl -i http://your-backend/invalid-path # must NOT return 200
159+
```
160+
161+
**Go Example:**
162+
```go
163+
http.HandleFunc("/health", func(w http.ResponseWriter, r *http.Request) {
164+
w.Header().Set("Content-Type", "application/json")
165+
w.WriteHeader(http.StatusOK)
166+
w.Write([]byte(`{"status":"ok"}`))
167+
})
168+
169+
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
170+
http.NotFound(w, r)
171+
})
172+
```
173+
174+
---
175+
176+
## Load Balancing Strategies
177+
178+
- `round-robin`
179+
- `weighted-round-robin`
180+
- `smooth-weighted-round-robin`
181+
- `least-connections`
182+
- `random`
183+
184+
Set the strategy in your YAML config:
185+
186+
```yaml
187+
load_balancer:
188+
strategy: "smooth-weighted-round-robin"
189+
```
190+
191+
---
192+
193+
## Health Checking
194+
195+
**Config:**
196+
```yaml
197+
health_check:
198+
enabled: true
199+
interval: 10s
200+
timeout: 5s
201+
path: "/health"
202+
method: "GET"
203+
```
204+
205+
**Best Practices:**
206+
- Enable health checking for auto-recovery
207+
- Use a dedicated health endpoint
208+
- Set proper intervals and timeouts
209+
210+
---
211+
212+
## Monitoring & Metrics
213+
214+
- **Logging:**
215+
Logs show strategy, backend states, health results, routing decisions.
216+
217+
```
218+
2025/09/10 10:50:24 [SYSTEM] Starting Load Balancer...
219+
2025/09/10 10:50:24 [SYSTEM] Added backend: http://localhost:3002 (weight: 1)
220+
2025/09/10 10:50:24 [HEALTH] Registered backend for health checking: http://localhost:3002
221+
2025/09/10 10:50:24 [HEALTH] Health checker started with 1 backends
222+
2025/09/10 10:50:24 [HEALTH] Health checking enabled (interval: 10s)
223+
2025/09/10 10:50:24 [SYSTEM] Load Balancer running on ::8080
224+
2025/09/10 10:50:24 [SYSTEM] Strategy: Smooth Weighted Round Robin
225+
2025/09/10 10:50:24 [SYSTEM] Admin API: http://localhost::8080/admin/health
226+
2025/09/10 10:50:29 [HEALTH] Backend http://localhost:3002 health check passed (latency: 5.055478666s)
227+
2025/09/10 10:51:39 [HEALTH] Backend http://localhost:3002 health check failed: unexpected HTTP status from backend: 404
228+
```
229+
230+
---
231+
232+
## Architecture
233+
234+
The diagram below shows the overall structure and flow:
235+
236+
```
237+
Load Balancer
238+
239+
┌────────────────┼────────────────┐
240+
│ │ │
241+
Strategies Health Server
242+
Manager Checker Pool
243+
│ │ │
244+
└────────────────┼────────────────┘
245+
246+
ProxyHandler
247+
248+
┌───────┼───────┐
249+
│ │ │
250+
Backend1 Backend2 Backend3
251+
```
252+
253+
- **Load Balancer:** Orchestrates incoming traffic and applies load balancing logic.
254+
- **Strategies Manager:** Chooses the backend based on selected algorithm.
255+
- **Health Checker:** Continuously checks backend health and availability.
256+
- **Server Pool:** Maintains list and state of backend servers.
257+
- **Proxy Handler:** Handles request forwarding and error responses.
258+
- **Backends:** The actual application servers receiving requests.
259+
260+
---
261+
262+
## Development
263+
264+
**Project Structure:**
265+
266+
```
267+
load-balancer/
268+
├── cmd/
269+
│ └── server/
270+
│ └── main.go # Application entry point
271+
├── internal/
272+
│ ├── backend/ # Backend management
273+
│ ├── config/ # Configuration handling
274+
│ ├── handlers/ # HTTP handlers
275+
│ ├── health/ # Health checking
276+
│ ├── loadbalancer/ # Core load balancer
277+
│ └── strategies/ # Load balancing algorithms
278+
├── config.yaml # Default configuration
279+
└── README.md
280+
```
281+
282+
**Build & Run:**
283+
```bash
284+
go run ./cmd/server/main.go
285+
go build -o load-balancer ./cmd/server
286+
./load-balancer
287+
```
288+
289+
**Production Build:**
290+
```bash
291+
go build -ldflags="-w -s" -o load-balancer ./cmd/server
292+
GOOS=linux GOARCH=amd64 go build -o load-balancer-linux ./cmd/server
293+
```
294+
295+
**Roadmap:**
296+
- [ ] Unit tests implementation
297+
- [ ] Metrics endpoint (`/metrics`)
298+
- [ ] Docker Compose setup and examples
299+
- [ ] Performance benchmarks

0 commit comments

Comments
 (0)