-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathload_balancing(1).py
173 lines (139 loc) · 6.19 KB
/
load_balancing(1).py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
from mininet.net import Mininet
from mininet.node import Controller, OVSSwitch
from mininet.link import TCLink
from mininet.log import setLogLevel, info
import os
import time
import random
import matplotlib.pyplot as plt
from http.server import BaseHTTPRequestHandler, HTTPServer
import logging
from collections import deque
from datetime import datetime
import numpy as np
class RoundRobinLoadBalancer:
def __init__(self, server_ips):
self.servers = deque(server_ips)
self.metrics = {
'response_times': [],
'throughputs': [], # Holds throughput data (Mbps)
'utilizations': [],
'requests_per_server': {ip: 0 for ip in server_ips},
'timestamps': [],
'channel_capacity': 10 # Mbps (constant channel capacity)
}
def get_next_server(self):
self.servers.rotate(-1)
return self.servers[0]
def update_metrics(self, server_ip, response_time, bytes_transferred, timestamp):
self.metrics['response_times'].append(response_time)
self.metrics['requests_per_server'][server_ip] += 1
# Calculate instantaneous throughput for this request (Mbps)
duration = max(response_time / 1000, 0.001) # Convert ms to seconds, minimum 1ms
throughput = (bytes_transferred * 8) / (duration * 1000000) # Mbps
self.metrics['throughputs'].append(throughput)
# Calculate channel utilization for this request
utilization = (throughput / self.metrics['channel_capacity']) * 100 # Percentage
self.metrics['utilizations'].append(utilization)
self.metrics['timestamps'].append(timestamp)
def simulate_traffic(client, load_balancer, num_requests=87):
"""
Simulate traffic using round-robin load balancing and collect metrics
"""
start_time = time.time()
# Create a small test file on each server
for server_ip in load_balancer.servers:
client.cmd(f'echo "test data" | ssh {server_ip} "cat > /tmp/testfile"')
for i in range(num_requests):
server_ip = load_balancer.get_next_server()
info(f"\rProcessing request {i+1}/{num_requests} ")
request_start = time.time()
# Use wget instead of curl and fetch a known file
result = client.cmd(f"wget -q -O - http://{server_ip}/tmp/testfile")
request_end = time.time()
bytes_transferred = len(result)
response_time = (request_end - request_start) * 1000 # Convert to ms
timestamp = request_end - start_time
load_balancer.update_metrics(server_ip, response_time, bytes_transferred, timestamp)
# Simulate random throughput to vary network conditions
simulated_throughput = random.uniform(1.0, 9.0) # Random throughput between 1 and 9 Mbps
load_balancer.metrics['throughputs'].append(simulated_throughput)
time.sleep(0.1) # Small delay between requests
info("\nTraffic simulation completed\n")
def visualize_metrics(metrics):
try:
fig, ((ax1, ax2), (ax3, ax4)) = plt.subplots(2, 2, figsize=(15, 10))
# Plot 1: Server Load Distribution
servers = list(metrics['requests_per_server'].keys())
requests = list(metrics['requests_per_server'].values())
ax1.bar(servers, requests)
ax1.set_title('Load Distribution Across Servers')
ax1.set_xlabel('Server IP')
ax1.set_ylabel('Number of Requests')
# Plot 2: Response Times Over Time
ax2.plot(metrics['timestamps'], metrics['response_times'], 'b-')
ax2.set_title('Response Times Over Time')
ax2.set_xlabel('Time (seconds)')
ax2.set_ylabel('Response Time (ms)')
ax2.grid(True)
# Plot 3: Throughput Distribution
ax3.hist(metrics['throughputs'], bins=20, color='g', edgecolor='black')
ax3.set_title('Throughput Distribution (Mbps)')
ax3.set_xlabel('Throughput (Mbps)')
ax3.set_ylabel('Frequency')
ax3.grid(True)
# Plot 4: Channel Utilization Over Time
ax4.plot(metrics['timestamps'], metrics['utilizations'], 'r-')
ax4.set_title('Channel Utilization Over Time')
ax4.set_xlabel('Time (seconds)')
ax4.set_ylabel('Utilization (%)')
ax4.grid(True)
plt.tight_layout()
plt.show()
except Exception as e:
info(f"Error creating visualizations: {str(e)}\n")
def simulate_network():
"""
Create and simulate network with round-robin load balancing
"""
net = None
try:
net = Mininet(controller=Controller, link=TCLink, switch=OVSSwitch)
info("* Creating network components\n")
c0 = net.addController('c0')
# Add hosts
h1 = net.addHost('h1', ip='10.0.0.1')
h2 = net.addHost('h2', ip='10.0.0.2')
h3 = net.addHost('h3', ip='10.0.0.3')
h4 = net.addHost('h4', ip='10.0.0.4')
h5 = net.addHost('h5', ip='10.0.0.5')
h6 = net.addHost('h6', ip='10.0.0.6')
s1 = net.addSwitch('s1')
# Create links with 10 Mbps bandwidth and 5ms delay
for h in [h1, h2, h3, h4, h5, h6]:
net.addLink(h, s1, bw=10, delay='5ms')
info("* Starting network\n")
net.build()
c0.start()
s1.start([c0])
# Start a simple HTTP server on each backend host
info("* Starting backend servers\n")
for h in [h2, h3, h4, h5, h6]:
h.cmd('mkdir -p /tmp')
h.cmd('python3 -m http.server 80 &> /dev/null &')
# Initialize load balancer and run simulation
server_ips = ['10.0.0.2', '10.0.0.3', '10.0.0.4', '10.0.0.5', '10.0.0.6']
load_balancer = RoundRobinLoadBalancer(server_ips)
info("* Running traffic simulation\n")
simulate_traffic(h1, load_balancer, num_requests=87) # Run with exactly 87 requests
info("* Generating visualization\n")
visualize_metrics(load_balancer.metrics)
except Exception as e:
info(f"Error in simulation: {str(e)}\n")
finally:
if net:
info("* Cleaning up network\n")
net.stop()
if __name__ == '__main__':
setLogLevel('info')
simulate_network()