(二)深入Openflowplugin源码 Switch生命周期对象

本文深入分析Openflowplugin(0.6.2)源码,重点探讨Switch生命周期对象的创建,包括DeviceContext、RpcContext、StatisticsContext和RoleContext的详细创建过程,以及ContextChain的注册和服务选举的关键步骤。
摘要由CSDN通过智能技术生成

(二)深入Openflowplugin源码 Switch生命周期对象

2019-06-11 陈卓文

可直接点击上方蓝字

(网易游戏运维平台)

关注我们,获一手游戏运维方案

陈卓文

 

陈卓文,网易游戏高级开发工程师,负责网易游戏私有云平台底层SDN/NFV网络的开发工作。

 

本文为 Openflowplugin(0.6.2) 源码分析第二篇,也是 Openflowplugin 为上层北向应用提供服务的关键逻辑的开篇!

回顾第一篇笔记,

在 Switch 连上控制器 Handshake 完成后,

最终调用ContextChainHolderImpl.deviceConnected方法,会为 Switch 创建其对应的ContextChain对象。

createContextChain(connectionContext);

先给出总结:在 Openflowplugin 中,每个 Switch 都有唯一的ContextChain对象,管理其在 Openflowplugin 的生命周期。

1. 创建生命周期管理对象 ContextChain

通过调用

ContextChainHolderImpl.createContextChain方法为连上的 switch 创建contextChain对象,

在创建 ContextChain 前,会先为 Switch 创建四个对象 DeviceContext、RpcContext、StatisticsContext、RoleContext;

四个对象封装了 Switch 的四种类型操作:

Device 基本信息、Rpc 请求、Statistics 数据收集、Master/Slava 角色调用。

最后,将四个 Context 对象都传入 ContextChain 中管理。在下面会详细展开,每个步骤。

ContextChainHolderImpl.createContextChain方法是 Switch 连上控制器 Handshake 完成后的核心调用,这个方法主要逻辑:

1.1 创建 DeviceContext

创建 deviceContext,且传入自身对象 (ContextChainHolderImpl) 引用

final DeviceContext deviceContext = deviceManager.createContext(connectionContext);
deviceContext.registerMastershipWatcher(this);

创建deviceContext处理:

  • 设置ConnectionAdapterImpl对象中设置 packetIn filter 为 true,目的是为了过滤后续过程中收到底层 switch 的 packetIn message;

  • 注:可以看到在ContextChainHolderImpl.createContextChain方法后面会将 packetIn filter 恢复为 false

  • 创建OutboundQueueHandler对象并传入对象引用到connectionAdapterImplconnectionContext

  • OutboundQueueHandler对象用于 Packet output 先到 Queue,再到ConnectionAdapterImpl对象。

  • 创建DeviceContextImpl对象

  • 创建OpenflowProtocolListenerFullImpl对象,并传入引用到connectionAdapterImpl对象(setMessageListenersetAlienMessageListener),用于处理底层 switch 传递给控制器的所有 message。

  • 注意:当 switch 连上控制器时

    调用ConnectionManagerImpl.onSwitchConnected()方法,

    会同样会传入一个 MessageListener 对象OpenflowProtocolListenerInitialImpl

    此对象仅能出来 Hello message,在 Handshake 阶段使用。

    而此时 Handshake 已经结束,重新传入OpenflowProtocolListenerFullImpl用于处理所有 message。

1.2 创建 RpcContext

创建 rpcContext,且传入自身对象 (ContextChainHolderImpl) 引用

final RpcContext rpcContext = rpcManager.createContext(deviceContext);
rpcContext.registerMastershipWatcher(this);

创建 rpcContext 处理:创建RpcContextImpl对象

1.3 创建 StatisticsContext

创建 statisticsContext,

且传入自身对象 (ContextChainHolderImpl) 引用

final StatisticsContext statisticsContext = statisticsManager.createContext(deviceContext, ownershipChangeListener.isReconciliationFrameworkRegistered());
statisticsContext.registerMastershipWatcher(this);

创建 statisticsContext 处理:

  • 创建MultipartWriterProvider对象

  • 注意这里传入了 deviceContext,是为了 write 到 device 的 operational yang。

    deviceContextImpl中有写入 device 对应 yang 需要的 TransactionChain

  • 创建StatisticsContextImpl对象

  • 传入了MultipartWriterProvider对象,目的是StatisticsContextImpl收集的数据可以写入 device operational yang 节点

1.4 创建 RoleContext

创建 roleContext,且传入自身对象 (ContextChainHolderImpl) 引用

final RoleContext roleContext = roleManager.createContext(deviceContext);
roleContext.registerMastershipWatcher(this);

创建 roleContext 处理:

  • 创建RoleContextImpl对象;

  • 创建SalRoleServiceImpl对象,

    传入RoleContextImpl

    用于后续步骤,设置 Switch 的 Master/Slave role。

1.5 创建 ContextChain

在创建 4 个 context 后,创建ContextChainImpl对象。然后向ContextChainImpl对象注册/加入各个对象:

  1. ContextChainImpl对象注册 registerDeviceRemovedHandler,用于后续 Switch 下线过程清除 Manger 中各个 Context 的索引。

  2. ContextChainImpl对象添加 context(addContext)。

  3. 最后将ContextChainImpl对象保存到ContextChainHolderImpl.contextChainMap中,相当于一个索引。ContextChainHolderImpl维护了各个 Switch 的 ContextChain 对象。

注意addContext是把传入的 deviceContext/rpcContext/statisticsContext/roleContext 封装到GuardedContextImpl对象。

GuardedContextImpl对象仅做多一层封装,会记录具体 Context 的状态等。

    @Override
    public <T extends OFPContext> void addContext(@Nonnull final T context) {
        contexts.add(new GuardedContextImpl(context));
    }

最后,完成创建ContextChainImpl对象后,将设备从connectingDevices索引中删除,表示已经在控制器 connected。

1.6 开始选举 Master/Slave

上文基本展开了

ContextChainHolderImpl.createContextChain方法详细讲解,

唯独缺少最后一行代码,这也是最关键一行!

调用 ContextChain 的 registerServices 方法:

contextChain.registerServices(singletonServiceProvider);

在展开这一行代码的逻辑之前,我们先回顾一下全文!

可以看到,在 Switch 完成 Handshake 后,Openflowplugin 会为 switch 创建 ContextChain 对象(包括各个 Context)。

考虑到多个控制器情况下,当 Switch 设置多个控制器(比如 ovs:set-controller),那么哪个控制器能够对 Switch 操作,比如下发流表。

因为在每个控制器,Openflowplugin 都会为 switch 创建 ContextChain 对象。

Openflow 协议,支持多个控制器,且控制器有角色有三类 master、slave、equal。为了控制层高可用使用 master/slave 模式;为了控制器负载均衡使用 equal 模式;

在此,我们不讨论 equal 模式,我们讨论 Master/slave 模型。

Openflowplugin 默认是以集群模型实现的,假设存在三个控制器节点,那么就会选举出一个节点作为某一个 Switch 的 Master( 不同 Switch,Master 不一定相同);

如果 Openflowplugin 作为单点控制器运行,那么它就是所有连上的 Switch 的 Master。

假设在三节点的集群情况下,Switch 连上所有控制节点,此时每个控制节点都有 Switch 的 ContextChain 对象,那么哪个节点是该 Switch 的 Master?

关键就是上面的这一行代码!由于篇幅问题,我们在下篇展开!

2. 总结

在 Switch 完成 Handshake 后,Openflowplugin 会为 Switch 创建各个 Context 对象(Device/Rpc/Statistics/Role),以及 ContextChain 对象。

 

敬请期待下期

(三)深入Openflowplugin源码 Master选举及Context服务实例化

 

往期精彩

 

(一)深入Openflowplugin源码分析Openflow握手过程

 

人工智障入门

 

网易游戏《荒野行动》《阴阳师》等出海实践-AWS技术峰会演讲实录

 

MySQL Flashback拯救手抖党

 

函数式编程在JavaScript下应用实践

 

感谢阅读,如果好看请点击右下角「在看」,点亮小星星,变亮的星星是小编的动力哦!

原始链接

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值