借鉴自http://blog.csdn.net/xjtuse2014/article/details/53968726
1.MoniterBandwidth模块:
1 package net.floodlightcontroller.qos_test; 2 3 import java.util.ArrayList; 4 import java.util.Collection; 5 import java.util.HashMap; 6 import java.util.Iterator; 7 import java.util.Map; 8 import java.util.Map.Entry; 9 import java.util.concurrent.ScheduledFuture; 10 import java.util.concurrent.TimeUnit; 11 12 import org.slf4j.Logger; 13 import org.slf4j.LoggerFactory; 14 15 import net.floodlightcontroller.core.IFloodlightProviderService; 16 import net.floodlightcontroller.core.internal.IOFSwitchService; 17 import net.floodlightcontroller.core.module.FloodlightModuleContext; 18 import net.floodlightcontroller.core.module.FloodlightModuleException; 19 import net.floodlightcontroller.core.module.IFloodlightModule; 20 import net.floodlightcontroller.core.module.IFloodlightService; 21 import net.floodlightcontroller.core.types.NodePortTuple; 22 import net.floodlightcontroller.statistics.IStatisticsService; 23 import net.floodlightcontroller.statistics.StatisticsCollector; 24 import net.floodlightcontroller.statistics.SwitchPortBandwidth; 25 import net.floodlightcontroller.threadpool.IThreadPoolService; 26 27 /** 28 * 带宽获取模块 29 * @author cq 30 * 31 */ 32 public class MonitorBandwidth implements IFloodlightModule, IMonitorBandwidthService { 33 34 //日志工具 35 private static final Logger log = LoggerFactory.getLogger(StatisticsCollector.class); 36 37 //Floodlight最核心的service类,其他service类需要该类提供 38 protected static IFloodlightProviderService floodlightProvider; 39 40 //链路数据分析模块,已经由Floodlight实现了,我们只需要调用一下就可以,然后对结果稍做加工,便于我们自己使用 41 protected static IStatisticsService statisticsService; 42 43 //Floodllight实现的线程池,当然我们也可以使用Java自带的,但推荐使用这个 44 private static IThreadPoolService threadPoolService; 45 46 //Future类,不明白的可以百度 Java现成future,其实C++11也有这个玩意了 47 private static ScheduledFuture<?> portBandwidthCollector; 48 49 //交换机相关的service,通过这个服务,我们可以获取所有的交换机,即DataPath 50 private static IOFSwitchService switchService; 51 52 //存放每条俩路的带宽使用情况 53 private static Map<NodePortTuple,SwitchPortBandwidth> bandwidth; 54 55 //搜集数据的周期 56 private static final int portBandwidthInterval = 4; 57 58 /** 59 * 获取带宽使用情况,计算带宽: 60 * switchPortBand.getBitsPerSecondRx().getValue()/(8*1024) + switchPortBand.getBitsPerSecondTx().getValue()/(8*1024) 61 */ 62 @Override 63 public Map<NodePortTuple, SwitchPortBandwidth> getBandwidthMap() { 64 bandwidth = statisticsService.getBandwidthConsumption(); 65 Iterator<Entry<NodePortTuple, SwitchPortBandwidth>> iter = bandwidth.entrySet().iterator(); 66 while(iter.hasNext()) { 67 Entry<NodePortTuple,SwitchPortBandwidth> entry = iter.next(); 68 NodePortTuple tuple = entry.getKey(); 69 SwitchPortBandwidth switchPortBand = entry.getValue(); 70 System.out.print("节点id以及端口号:" + tuple.getNodeId()+","+tuple.getPortId().getPortNumber()+","); 71 System.out.println("端口带宽:" + switchPortBand.getBitsPerSecondRx().getValue()/(8*1024) + switchPortBand.getBitsPerSecondTx().getValue()/(8*1024)); 72 } 73 return bandwidth; 74 } 75 76 /** 77 * 告诉FL,我们添加了一个模块,提供了IMonitorBandwidthService 78 */ 79 @Override 80 public Collection<Class<? extends IFloodlightService>> getModuleServices() { 81 Collection<Class<? extends IFloodlightService>> l = new ArrayList<Class<? extends IFloodlightService>>(); 82 l.add(IMonitorBandwidthService.class); 83 return l; 84 } 85 86 /** 87 * 我们前面声明了几个需要使用的service,在这里说明一下实现类 88 */ 89 @Override 90 public Map<Class<? extends IFloodlightService>, IFloodlightService> getServiceImpls() { 91 Map<Class<? extends IFloodlightService>, IFloodlightService> m = new HashMap<Class<? extends IFloodlightService>, IFloodlightService>(); 92 m.put(IMonitorBandwidthService.class, this); 93 return m; 94 } 95 96 /** 97 * 告诉FL我们依赖哪些服务,以便于加载 98 */ 99 @Override 100 public Collection<Class<? extends IFloodlightService>> getModuleDependencies() { 101 Collection<Class<? extends IFloodlightService>> l = new ArrayList<Class<? extends IFloodlightService>>(); 102 l.add(IFloodlightProviderService.class); 103 l.add(IStatisticsService.class); 104 l.add(IOFSwitchService.class); 105 l.add(IThreadPoolService.class); 106 return l; 107 } 108 109 /** 110 * 初始化这些service 111 */ 112 @Override 113 public void init(FloodlightModuleContext context) throws FloodlightModuleException { 114 floodlightProvider = context.getServiceImpl(IFloodlightProviderService.class); 115 statisticsService = context.getServiceImpl(IStatisticsService.class); 116 switchService = context.getServiceImpl(IOFSwitchService.class); 117 threadPoolService = context.getServiceImpl(IThreadPoolService.class); 118 } 119 120 /** 121 * 启动 122 */ 123 @Override 124 public void startUp(FloodlightModuleContext context) throws FloodlightModuleException { 125 startCollectBandwidth(); 126 } 127 //自定义的开始收集数据的方法,使用了线程池,定周期的执行 128 private synchronized void startCollectBandwidth(){ 129 portBandwidthCollector = threadPoolService.getScheduledExecutor().scheduleAtFixedRate(new GetBandwidthThread(), portBandwidthInterval, portBandwidthInterval, TimeUnit.SECONDS); 130 log.warn("Statistics collection thread(s) started"); 131 } 132 //自定义的线程类,在上面的方法中实例化,并被调用 133 private class GetBandwidthThread extends Thread implements Runnable { 134 private Map<NodePortTuple,SwitchPortBandwidth> bandwidth; 135 136 public Map<NodePortTuple, SwitchPortBandwidth> getBandwidth() { 137 return bandwidth; 138 } 139 140 @Override 141 public void run() { 142 System.out.println("GetBandwidthThread run()...."); 143 bandwidth =getBandwidthMap(); 144 System.out.println("bandwidth.size():"+bandwidth.size()); 145 } 146 } 147 }
2.IMonitorBandwidthService类:
1 package net.floodlightcontroller.qos_test; 2 3 import java.util.Map; 4 5 import net.floodlightcontroller.core.module.IFloodlightService; 6 import net.floodlightcontroller.core.types.NodePortTuple; 7 import net.floodlightcontroller.statistics.SwitchPortBandwidth; 8 9 public interface IMonitorBandwidthService extends IFloodlightService{ 10 11 //带宽使用情况 12 public Map<NodePortTuple, SwitchPortBandwidth> getBandwidthMap(); 13 }
在ubuntu命令行,需执行
curl -X POST http://192.168.161.1:8080//wm/statistics/config/enable/json
才能获取到带宽,结果如下所示:
前提是执行了iperf h1 h2命令后才能看到,否则带宽一直显示是0