SDN之QoS--3:网络基础信息的测量(Floodlight)

模块该部分承接上文,添加三个模块,来实现网络带宽使用、丢包率、链路时延等的测量。当然,读者也可以把他们三个木块合并,只是那样的话,每一个service就不单一了。

一、说在前面

一般来讲,我们在Floodlight中添加自定义的模块,最基础的需要实现以下两个步骤:

  1. 自定义一个interface,里面写上自定义的方法,当然,需要extends IFloodlightServcice.
  2. 自定义一个class,实现我们的那个interface,还需要实现IFloodlightModule。如果还需要处理OpenFlow消息还需要实现IOFMessageListener,其他类似;如果需要使用FL提供的线程池,那就需要添加改依赖。
在getModuleDependencies()中添加

接下来,我主要记录我们是如何采集到链路带宽使用情况,以及需要依赖那些service,另外两个模块与这个答题类似,就只贴上代码了。

二、链路带宽使用情况
定义的interface : IMonitorBandwidthService

public interface IMonitorBandwidthService extends IFloodlightService {
   
    //带宽使用情况
    public Map<NodePortTuple,SwitchPortBandwidth> getBandwidthMap();
}

然后是定义的MonitorBandwidth

package aaa.net.floodlightcontroller.test;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import net.floodlightcontroller.core.IFloodlightProviderService;
import net.floodlightcontroller.core.internal.IOFSwitchService;
import net.floodlightcontroller.core.module.FloodlightModuleContext;
import net.floodlightcontroller.core.module.FloodlightModuleException;
import net.floodlightcontroller.core.module.IFloodlightModule;
import net.floodlightcontroller.core.module.IFloodlightService;
import net.floodlightcontroller.statistics.IStatisticsService;
import net.floodlightcontroller.statistics.StatisticsCollector;
import net.floodlightcontroller.statistics.SwitchPortBandwidth;
import net.floodlightcontroller.threadpool.IThreadPoolService;
import net.floodlightcontroller.topology.NodePortTuple;

/**
 * 带宽获取模块
 * @author xjtu
 *
 */
public class MonitorBandwidth implements IFloodlightModule,IMonitorBandwidthService{
   

    //日志工具
    private static final Logger log = LoggerFactory.getLogger(StatisticsCollector.class);
    //Floodlight最核心的service类,其他service类需要该类提供
    protected static IFloodlightProviderService floodlightProvider;
    //链路数据分析模块,已经由Floodlight实现了,我们只需要调用一下就可以,然后对结果稍做加工,便于我们自己使用
    protected static IStatisticsService statisticsService;
    //Floodllight实现的线程池,当然我们也可以使用Java自带的,但推荐使用这个
    private static IThreadPoolService threadPoolService;
    //Future类,不明白的可以百度 Java现成future,其实C++11也有这个玩意了
    private static ScheduledFuture<?> portBandwidthCollector;
    //交换机相关的service,通过这个服务,我们可以获取所有的交换机,即DataPath
    private static IOFSwitchService switchService;
    //存放每条俩路的带宽使用情况 
    private static Map<NodePortTuple,SwitchPortBandwidth> bandwidth;
    //搜集数据的周期
    private static final int portBandwidthInterval = 4;

    //告诉FL,我们添加了一个模块,提供了IMonitorBandwidthService
    @Override
    public Collection<Class<? extends IFloodlightService>> getModuleServices() {
        Collection<Class<? extends IFloodlightService>> l = new ArrayList<Class<? extends IFloodlightService>>();
        l.add(IMonitorBandwidthService.class);
        return l;
    }
    //我们前面声明了几个需要使用的service,在这里说明一下实现类
    @Override
    public Map<Class<? extends IFloodlightService>, IFloodlightService> getServiceImpls() {
        Map<Class<? extends IFloodlightService>, IFloodlightService> m = new HashMap<Class<? extends IFloodlightService>, IFloodlightService>();
        m.put(IMonitorBandwidthService.class, this);
        return m;
    }

    //告诉FL我们以来那些服务,以便于加载
    @Override
    public Collection<Class<? extends IFloodlightService>> getModuleDependencies() {
        Collection<Class<? extends IFloodlightService>> l = new ArrayList<Class<? extends IFloodlightService>>();
        l.add(IFloodlightProviderService.class);
        l.add(IStatisticsService.class);
        l.add(IOFSwitchService.class);
        l.add(IThreadPoolService.class);
        return l;
    }

    //初始化这些service,个人理解这个要早于startUp()方法的执行,验证很简单,在两个方法里打印当前时间就可以。
    @Override
    public void init(FloodlightModuleContext context) throws FloodlightModuleException {
        floodlightProvider = context.getServiceImpl(IFloodlightProviderService.class);
        statisticsService = context.getServiceImpl(IStatisticsService.class);
        switchService = context.getServiceImpl(IOFSwitchService.class);
        threadPoolService = context.getServiceImpl(IThreadPoolService.class);
    }

    @Override
    public void startUp(FloodlightModuleContext context) throws FloodlightModuleException {
        startCollectBandwidth();
    }

    //自定义的开始收集数据的方法,使用了线程池,定周期的执行
    private synchronized void startCollectBandwidth(){
        portBandwidthCollector = threadPoolService.getScheduledExecutor().scheduleAtFixedRate(new GetBandwidthThread(), portBandwidthInterval, portBandwidthInterval, TimeUnit.SECONDS);
        log.warn("Statistics collection thread(s) started");
    }

    //自定义的线程类,在上面的方法中实例化,并被调用
    /**
     * Single thread for collecting switch statistics and
     * containing the reply.
     */
    private class GetBandwidthThread extends Thread implements Runnable  {
   
        private Map<NodePortTuple,SwitchPortBandwidth> bandwidth;

        public Map<NodePortTuple, SwitchPortBandwidth> getBandwidth() {
            return bandwidth;
        }

//      public void setBandwidth(Map<NodePortTuple, SwitchPortBandwidth> bandwidth) {
   
//          this.bandwidth = bandwidth;
//      }

        @Override
        public void run() {
            System.out.println("GetBandwidthThread run()....");
            bandwidth =getBandwidthMap(); 
            System.out.println("bandwidth.size():"+bandwidth.size());
        }
    }

    /**
     * 获取带宽使用情况
     * 需要简单的换算 
        根据 switchPortBand.getBitsPerSecondRx().getValue()/(8*1024) + switchPortBand.getBitsPerSecondTx().getValue()/(8*1024)
        计算带宽
     */
    public Map<NodePortTuple,SwitchPortBandwidth> getBandwidthMap(){
        bandwidth = statisticsService.getBandwidthConsumption();
//      
//      for(NodePortTuple tuple:bandwidth.keySet()){
   
//          System.out.println(tuple.getNodeId().toString()+","+tuple.getPortId().getPortNumber());
//          System.out.println();
//      }
        Iterator<Entry<NodePortTuple,SwitchPortBandwidth>> iter = bandwidth.entrySet().iterator();
        while (iter.hasNext()) {
            Entry<NodePortTuple,SwitchPortBandwidth> entry = iter.next();
            NodePortTuple tuple  = entry.getKey();
            SwitchPortBandwidth switchPortBand = entry.getValue();
            System.out.print(tuple.getNodeId()+","+tuple.getPortId().getPortNumber()+",");
            System.out.println(switchPortBand.getBitsPerSecondRx().getValue()/(8*1024) + switchPortBand.getBitsPerSecondTx().getValue()/(8*1024));

        }


        return bandwidth;
    }

}

三、链路丢包率统计

import net.floodlightcontroller.core.module.IFloodlightService;

public interface IMonitorPkLossService extends 
  • 5
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 35
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 35
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值