A practical and educational Go project that demonstrates core distributed systems concepts, including load balancing, health monitoring, sticky sessions, caching, and asynchronous message processing.
BalancerLab provides a hands-on environment for exploring how modern backend systems handle traffic distribution, server failures, state management, and background workloads.
The project runs as an HTTP API on localhost:8080 and can be tested using Postman, a web browser, or PowerShell.
- Round Robin
- Least Connections
- Power of Two Choices (P2C)
- Weighted Round Robin
- Consistent Hashing
- Adaptive Load Balancing
- Join Idle Queue (JIQ)
-
Health Checker for monitoring server availability
-
Cache Store with Cache Stampede protection
-
Sticky Sessions using Cookies
-
Asynchronous Message Queue using Go channels
-
Distributed Systems Demonstrations:
- Latency
- Partial Failure
- Concurrency
-
Unit Tests for core packages
BalancerLab is organized into independent packages, each responsible for a specific distributed systems concern:
| Package | Responsibility |
|---|---|
api |
HTTP API endpoints |
lb |
Load balancing algorithms |
health |
Server health monitoring |
cache |
In-memory cache implementation |
session |
Sticky session management |
messaging |
Asynchronous message processing |
demo |
Distributed systems demonstrations |
.
├── go.mod
├── main.go
└── internal
├── api
│ └── server.go
├── cache
│ ├── store.go
│ └── store_test.go
├── demo
│ └── four_horsemen.go
├── health
│ ├── checker.go
│ └── checker_test.go
├── lb
│ ├── adaptive.go
│ ├── consistent_hash.go
│ ├── jiq.go
│ ├── least_connections.go
│ ├── p2c.go
│ ├── round_robin.go
│ ├── server.go
│ ├── weighted_round_robin.go
│ └── lb_test.go
├── messaging
│ ├── queue.go
│ └── queue_test.go
└── session
├── manager.go
└── manager_test.go
- Go 1.24 or later
- Postman (optional)
Verify your Go installation:
go versionClone the repository:
git clone <repository-url>
cd BalancerLabInstall dependencies:
go mod tidyStart the API server:
go run .If the application starts successfully, you should see:
API server is running on http://localhost:8080
The API is now ready to accept requests.
| Strategy | Description |
|---|---|
| Round Robin | Cycles through healthy servers sequentially |
| Least Connections | Selects the server with the fewest active connections |
| Power of Two Choices | Compares two random servers and picks the better one |
| Weighted Round Robin | Distributes requests according to server weights |
| Consistent Hashing | Routes the same user to the same server whenever possible |
| Adaptive | Considers server health and performance metrics |
| Join Idle Queue | Assigns requests to servers that advertise themselves as idle |
GET http://localhost:8080/healthResponse:
{
"status": "ok"
}GET http://localhost:8080/serversReturns all servers with their current state and metrics.
GET http://localhost:8080/lb/select?strategy=round_robin
GET http://localhost:8080/lb/select?strategy=least_connections
GET http://localhost:8080/lb/select?strategy=p2c
GET http://localhost:8080/lb/select?strategy=weighted_round_robin
GET http://localhost:8080/lb/select?strategy=adaptive
GET http://localhost:8080/lb/select?strategy=consistent_hash&user_id=user-42POST http://localhost:8080/servers/health?name=server-3&healthy=true
POST http://localhost:8080/servers/health?name=server-2&healthy=falsePOST http://localhost:8080/servers/metrics?name=server-2&cpu=97&memory=70&errors=20Servers are automatically marked unhealthy when:
- CPU usage exceeds 95%
- Error count exceeds 15
Register an idle server:
POST http://localhost:8080/jiq/register?name=server-1Select an idle server:
GET http://localhost:8080/jiq/selectRetrieve a cached value:
GET http://localhost:8080/cache?key=configDelete a cached value:
DELETE http://localhost:8080/cache?key=configPublish a message:
POST http://localhost:8080/queueRequest body:
{
"body": "order-created"
}View processed messages:
GET http://localhost:8080/queueView pending messages:
GET http://localhost:8080/queue/pendingCreate a sticky session:
GET http://localhost:8080/session/set?server=server-1Retrieve the assigned server:
GET http://localhost:8080/session/getNote: Postman usually stores cookies automatically. Ensure Cookie Jar is enabled if session persistence does not work as expected.
Run all tests:
go test ./...Run static analysis:
go vet ./...Run the race detector:
go test -race ./...On Windows, the race detector requires CGO to be enabled and a compiler such as GCC to be available in the system PATH.
Invoke-RestMethod http://localhost:8080/health
Invoke-RestMethod http://localhost:8080/servers
Invoke-RestMethod "http://localhost:8080/lb/select?strategy=round_robin"
Invoke-RestMethod "http://localhost:8080/cache?key=config"BalancerLab helps demonstrate and experiment with questions such as:
- What happens when a server becomes unavailable?
- How can requests be distributed efficiently?
- How do sticky sessions maintain user affinity?
- How can cache stampedes be prevented?
- How can background processing improve responsiveness?
- How do modern distributed systems balance reliability and performance?
These concepts form the foundation of scalable and resilient backend architectures.
Licensed under the MIT License.