Skip to content

Commit 25e06e8

Browse files
author
SamSyntax
committed
adding flags for amount of servers and implementing weighted round robin balancing method
1 parent e127790 commit 25e06e8

File tree

6 files changed

+69
-14
lines changed

6 files changed

+69
-14
lines changed

Makefile

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,5 @@
1-
build:
1+
run:
22
go build -o ./lb *.go && ./lb
3+
build:
4+
go build -o ./lb *.go
5+

README.md

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,10 +72,10 @@ Run the code using:
7272
```bash
7373
go build *.go -o ./lb && ./lb
7474
```
75-
OR
75+
or
7676

7777
```bash
78-
make build
78+
make run
7979
```
8080
The load balancer will listen on port 7000. Open your browser or use curl to send a request to localhost:7000:
8181

@@ -84,6 +84,10 @@ curl http://localhost:7000
8484
```
8585
The request will be forwarded to one of the backend servers, and you will see a response indicating the server's port.
8686

87+
We can also specify amount of servers and balancing method (Round Robin and Weighted Round Robin) by building program and passing flags:
88+
```bash
89+
make build && ./lb -amount 5 -method rr
90+
```
8791
Example Output
8892
```bash Serving requests at localhost:7000
8993
Spawning server: Server 0 at localhost:8000
@@ -98,7 +102,7 @@ forwarding to "localhost:8004"
98102
forwarding to "localhost:8000"
99103
```
100104
Customization
101-
Number of Servers: You can modify the number of servers spawned by changing the argument passed to the Spawner function in main.go.
105+
Number of Servers: You can modify the number of servers spawned by changing the <b>-amount</b> flag value.
102106
Ports: The backend servers listen on ports 8000 and higher. You can modify the port range in the Spawner function.
103107
Dependencies
104108
This project does not require any third-party dependencies. It only uses the Go standard library.

loadbalancer

7.51 MB
Binary file not shown.

loadbalancer.go

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,11 @@ type ServerInterface interface {
1515
}
1616

1717
type LbServer struct {
18-
addr string
19-
proxy *httputil.ReverseProxy
20-
name string
18+
addr string
19+
proxy *httputil.ReverseProxy
20+
name string
21+
weight int
22+
current int
2123
}
2224

2325
func (s LbServer) Address() string {
@@ -32,7 +34,7 @@ func (s LbServer) Serve(w http.ResponseWriter, r *http.Request) {
3234
s.proxy.ServeHTTP(w, r)
3335
}
3436

35-
func NewLbServer(addr string) *LbServer {
37+
func NewLbServer(addr string, weight int) *LbServer {
3638
serverUrl, err := url.Parse(addr)
3739
if err != nil {
3840
fmt.Printf("Failed to parse url: %v\n", err)
@@ -41,24 +43,50 @@ func NewLbServer(addr string) *LbServer {
4143
return &LbServer{
4244
addr: addr,
4345
proxy: httputil.NewSingleHostReverseProxy(serverUrl),
46+
weight: weight,
47+
current: 0,
4448
}
4549
}
4650

4751
type LoadBalancer struct {
4852
port string
4953
roundRobinCount int
5054
servers []LbServer
55+
weidhted bool
5156
}
5257

53-
func NewLoadBalancer(port string, servers []LbServer) *LoadBalancer {
58+
func NewLoadBalancer(port string, servers []LbServer, weighted bool) *LoadBalancer {
5459
return &LoadBalancer{
5560
port: port,
5661
roundRobinCount: 0,
5762
servers: servers,
63+
weidhted: weighted,
5864
}
5965
}
6066

6167
func (lb *LoadBalancer) GetNextAvailableServer() LbServer {
68+
if lb.weidhted {
69+
return lb.getWeightedServer()
70+
}
71+
return lb.getRoundRobinServer()
72+
}
73+
func (lb *LoadBalancer) getWeightedServer() LbServer {
74+
75+
totalServers := len(lb.servers)
76+
for i := 0; i < totalServers; i++ {
77+
server := &lb.servers[lb.roundRobinCount%totalServers]
78+
if server.current < server.weight {
79+
server.current++
80+
return *server
81+
}
82+
server.current = 0
83+
lb.roundRobinCount++
84+
}
85+
lb.roundRobinCount++
86+
return lb.servers[lb.roundRobinCount%totalServers]
87+
}
88+
func (lb *LoadBalancer) getRoundRobinServer() LbServer {
89+
6290
server := lb.servers[lb.roundRobinCount%len(lb.servers)]
6391
for !server.IsAlive() {
6492
lb.roundRobinCount++

main.go

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,27 @@
11
package main
22

33
import (
4+
"flag"
45
"fmt"
56
"net/http"
7+
"os"
68
)
79

810
func main() {
9-
servers := Spawner(5)
10-
lb := NewLoadBalancer("7000", servers)
11+
nFlag := flag.Int("amount", 1234, "Enter amount of local servers to be spawned")
12+
method := flag.String("method", "rr", "Load balancing method: 'rr - Round Robin | wrr - Weighted Round Robin")
13+
flag.Parse()
14+
servers := Spawner(*nFlag)
15+
var lb *LoadBalancer
16+
switch *method {
17+
case "wrr":
18+
lb = NewLoadBalancer("7000", servers, true)
19+
case "rr":
20+
lb = NewLoadBalancer("7000", servers, false)
21+
default:
22+
fmt.Println("Invalid method. Use 'rr' or 'wrr'.")
23+
os.Exit(1)
24+
}
1125
handleRedirect := func(w http.ResponseWriter, r *http.Request) {
1226
lb.ServeProxy(w, r)
1327
}

spawner.go

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ import (
77
"strconv"
88
)
99

10-
func Server(port, name string) LbServer {
11-
srv := NewLbServer("http://localhost" + port)
10+
func Server(port, name string, weight int) LbServer {
11+
srv := NewLbServer("http://localhost"+port, weight)
1212
srv.name = name
1313

1414
mux := http.NewServeMux()
@@ -34,10 +34,16 @@ func Server(port, name string) LbServer {
3434
}
3535
func Spawner(amt int) []LbServer {
3636
servers := make([]LbServer, 0, amt)
37+
weights := []int{5, 2, 3}
3738
for i := 0; i < amt; i++ {
39+
k := 0
40+
if i > len(weights) {
41+
k = 0
42+
}
43+
k++
3844
name := fmt.Sprintf("Server %v", i)
3945
port := ":" + strconv.Itoa(8000+i)
40-
srv := Server(port, name)
46+
srv := Server(port, name, weights[k])
4147
servers = append(servers, srv)
4248
}
4349
return servers

0 commit comments

Comments
 (0)