Python 交换机负载平衡动态主机拓扑
下面是在mininet中设置网络的代码,其中每个主机将运行一个客户端程序,即通过hx.cmd'python pyexample.py',每个服务器将运行一个客户端将连接到的服务器程序 首先,我已将所有主机连接到交换机,其中一些是服务器,一些是主机。当主机/客户端/服务器的数量不固定时,如何让此交换机充当负载平衡器 第二,在多个客户端向单个服务器发送请求的情况下,如何让客户端和服务器相互连接并将结果返回给单个客户端Python 交换机负载平衡动态主机拓扑,python,load-balancing,mininet,openflow,Python,Load Balancing,Mininet,Openflow,下面是在mininet中设置网络的代码,其中每个主机将运行一个客户端程序,即通过hx.cmd'python pyexample.py',每个服务器将运行一个客户端将连接到的服务器程序 首先,我已将所有主机连接到交换机,其中一些是服务器,一些是主机。当主机/客户端/服务器的数量不固定时,如何让此交换机充当负载平衡器 第二,在多个客户端向单个服务器发送请求的情况下,如何让客户端和服务器相互连接并将结果返回给单个客户端 #!/usr/bin/python from mininet.topo impo
#!/usr/bin/python
from mininet.topo import Topo
from mininet.net import Mininet
from mininet.util import dumpNodeConnections
from mininet.log import setLogLevel
import math
# num_hosts = number of servers + clients
# network with n hosts connected to one switch
class NetworkTopology(Topo, num_hosts, num_servers):
clients = []
servers = []
def build(self, n=num_hosts):
# Switch controlled to act as load balancer
# TODO: Write controller
switch = self.addSwitch('s1')
# Generate 0..n-1 hosts - n = num_hosts
for h in range(n):
s = 0
while s < num_servers:
# Add server to the topology
server = self.addHost('server%s' % (s+1))
self.addLink(server, switch)
servers.append(server)
else:
# Add client to the topology
client = self.addHost('client%s' % ((h-s)+1))
self.addLink(host, switch)
clients.append(client)
def runTest(num_hosts, num_servers, num_levels, num_base_reports):
topo = NetworkTopology(num_hosts, num_servers)
# Main function
if __name__ == '__main__':
setLogLevel('info')
num_base_reports = 100
num_levels = math.log(num_base_reports, 10) # log to base 10
num_hosts = round(4**(math.log(num_base_reports-1, 10)))
num_servers = round(2**(math.log(num_base_reports-1, 10)))
runTest(num_hosts, num_servers num_levels, num_base_reports)
客户端线程:
客户:
正如你所知,在SDN中发生了一些新的事情;对数据平面和控制平面分离!因此,您必须使用控制器在网络中构建负载平衡功能。SDN控制器和交换机使用OpenFlow或其他南向API相互连接。网络功能,如防火墙、本机、负载平衡和其他功能将在控制器软件上实现 控制器有很多选择,比如ONOS、OpenDaylight、泛光灯、RYU等等。如果用python编写代码很容易,那么您最好选择,因为前面提到的其他控制器都是基于java的 您可以在RYU controller的顶部找到实现简单循环负载平衡应用程序的示例代码: 您应该在第131行和该块中添加代码: 您必须将代码添加到第131行之后和以下elif块中:
elif ip.proto == 0x06: # Resolve TCP
例如,类似这样的事情:
elif ip.proto == 0x06: # Resolve TCP
if pkt_tcp.src_port == 3000: # Ignore packets from server when creating rule
return
ip_src = ip.src
# if ip of client has been learned (flow installed), no need to process
# helps with burst of traffic that creates duplicate flows
if ip_src in self.ip_to_mac:
return
out_port = self.net.servers[self.rr_counter].port
mac_dest = self.net.servers[self.rr_counter].mac
ip.dst = self.net.lb_ip
# Forward Received TCP Packet to the selected Server
p = packet.Packet()
p.add_protocol(ethernet.ethernet(dst=mac_dest, src=src, ethertype=ether_types.ETH_TYPE_IP))
p.add_protocol(ip)
p.add_protocol(pkt_tcp)
self.send_packet(p, msg, datapath, out_port)
# Add Flow Entry
match = datapath.ofproto_parser.OFPMatch(in_port=msg.in_port, dl_type=0x0800,
nw_proto=0x06, nw_src=ip_src, nw_dst=self.net.lb_ip)
actions = [parser.OFPActionSetDlDst(mac_dest), parser.OFPActionOutput(out_port)]
self.add_flow(match, actions)
# Insert reverse flow
match = datapath.ofproto_parser.OFPMatch(in_port=out_port, dl_type=0x0800,
nw_proto=0x06, nw_src=self.net.lb_ip, nw_dst=ip_src)
actions = [parser.OFPActionSetDlSrc(self.net.lb_mac), parser.OFPActionOutput(msg.in_port)]
self.add_flow(match, actions)
# Update ARP table
self.ip_to_mac.update({ip_src: src})
# Update RR counter
self.rr_counter = (self.rr_counter + 1) % self.net.servers_num
别忘了在课堂上添加lb服务器、Mac服务器和IP服务器
在这方面可以帮助您的其他资源:
你可以根据你的观点来匹配协议和端口吗?我将在各自的主机上执行一个Java客户端和服务器程序,以便使用套接字连接相互通信。请将代码发送给我好吗?我需要这些代码来传达我对您使用的套接字的想法。请参阅更新的OP-我添加了客户端和服务器代码,以及每个客户端连接到服务器时调用的客户端线程。它是一个基本的套接字连接您使用的库默认使用TCP协议,根据您的代码,它使用的是端口3000。因此,您的匹配将是:|从客户端到服务器->eth_类型:0x800 IPv4协议:TCP dst_端口:3000 |从服务器到客户端->eth_类型:0x800 IPv4协议:TCP src_端口:3000 |您还可以添加其他字段来完成匹配,例如,src_ip,dst_ip等等。我将把您在答案中提供的示例循环链接中的这些匹配放在哪里?另外,在我的Java应用程序中,我想我会连接到负载平衡器?如果是的话,我会怎么做?最后,如何将示例负载平衡器连接到我的mininet topo?你能为其他人更新答案吗?
public class Client
{
protected static final int PORT = 3000;
public Client() {
}
public static void main(String[] args) {
try {
Socket sock = new Socket("127.0.0.1", PORT);
// Output Stream (sending to server)
OutputStream os = sock.getOutputStream();
PrintWriter pw = new PrintWriter(os, true);
// Input Stream (receiving from server)
InputStream is = sock.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String request, response;
while(true) {
request = "MyRequest!";
pw.println(request);
if((response = br.readLine()) != null) {
System.out.println(response);
break;
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
elif ip.proto == 0x06: # Resolve TCP
elif ip.proto == 0x06: # Resolve TCP
if pkt_tcp.src_port == 3000: # Ignore packets from server when creating rule
return
ip_src = ip.src
# if ip of client has been learned (flow installed), no need to process
# helps with burst of traffic that creates duplicate flows
if ip_src in self.ip_to_mac:
return
out_port = self.net.servers[self.rr_counter].port
mac_dest = self.net.servers[self.rr_counter].mac
ip.dst = self.net.lb_ip
# Forward Received TCP Packet to the selected Server
p = packet.Packet()
p.add_protocol(ethernet.ethernet(dst=mac_dest, src=src, ethertype=ether_types.ETH_TYPE_IP))
p.add_protocol(ip)
p.add_protocol(pkt_tcp)
self.send_packet(p, msg, datapath, out_port)
# Add Flow Entry
match = datapath.ofproto_parser.OFPMatch(in_port=msg.in_port, dl_type=0x0800,
nw_proto=0x06, nw_src=ip_src, nw_dst=self.net.lb_ip)
actions = [parser.OFPActionSetDlDst(mac_dest), parser.OFPActionOutput(out_port)]
self.add_flow(match, actions)
# Insert reverse flow
match = datapath.ofproto_parser.OFPMatch(in_port=out_port, dl_type=0x0800,
nw_proto=0x06, nw_src=self.net.lb_ip, nw_dst=ip_src)
actions = [parser.OFPActionSetDlSrc(self.net.lb_mac), parser.OFPActionOutput(msg.in_port)]
self.add_flow(match, actions)
# Update ARP table
self.ip_to_mac.update({ip_src: src})
# Update RR counter
self.rr_counter = (self.rr_counter + 1) % self.net.servers_num