作者简介:鸿哥,硕士研究生,国内某通信设备公司软件研发工程师,主要从事云计算、SDN技术开发
一、EntityOwnershipService服务简介
EntityOwnershipService是一个通用的服务,是odl中集群控制的核心服务,APP如果想支持集群,则app必须自己注册一个全集群唯一的entity,在YANG MODEL中引入EntityOwnershipService服务,注册registerCandidate以及registerListener,从而实现多集群实例下的选主操作,并在集群当中的主(master)出现故障时,处理新主实例的升主操做,提高app的可用性。
注:odl应用编写的前提:集群下开发的app均采用md-sal模式,而非AD-SAL模式。
二、使用EntityOwnershipService及编程应用
1、Yang model引入EntityOwnershipService
在mutiple-impl中的yang引入EntityOwnershipService,增加对entityownerservice的引用。
2、拿到EntityOwnershipServiceDependency
在mutiple-impl的MutipleModule.java中获取EntityOwnershipServiceDependency,并将该实体复制到MutipleProvider
3、实现EntityOwnershipListener接口
EntityOwnershipListener接口中有ownershipChanged方法,一旦有主从切换事件,就会调用该方法。
4、registerListener的注册
将MutipleProvider注册为entityOwnershipService的监听器。
5、实现主从角色的业务逻辑
监听entityOwnershipService服务之后,需要针对不同的角色(Master和Slave)实现不同的逻辑,比如希望在主(Master)当中注册rpc,在从(Slave)取消注册rpc
6、注册RPC与取消RPC的实现
注意在close当中需要将entityOwnershipListenerRegistration与entityOwnershipCandidateRegistration关闭。
三、测试验证
1、基本环境准备
编译mutiple模块,在mutiple根目录执行mvn clean install –DskipTests编译成功。
找到编译后的mutiple目录。
将该mutiple模块安装到distribution-karaf-0.3.3-Lithium-SR3控制器当中。
2、搭建集群
关闭控制器,开始部署集群。
在106上执行
1 |
./configure_cluster.sh 1 192.168.7.106 192.168.7.107 192.168.7.108 |
在107上执行
1 |
./configure_cluster.sh 2 192.168.7.106 192.168.7.107 192.168.7.108 |
在108上执行
1 |
./configure_cluster.sh 3 192.168.7.106 192.168.7.107 192.168.7.108 |
分别启动控制器并执行:
1 2 3 4 |
feature:install odl-restconf-all feature:install odl-mdsal-clustering bundle:install mvn:org.jolokia/jolokia-osgi/1.1.5 bundle:start org.jolokia.osgi |
3、观察log
在106上观察log,可以得知106上的角色为Slave。
在107上观察log,可以得知107上的角色为Master
在108上观察log,可以得知108上的角色为Slave
4、关闭Master控制器107,继续观察剩下两台控制器的log
在106上的log显示,表明106升级为Master
在108上的log显示,表明108没有升级为Master
5、重启控制器107,继续观察3台控制器的log
目前Master在106上,启动之后的107上的log显示:
说明重启之后的107变为Slave。继续尝试,挂掉106,再看107 上的log
可以看到107又变成主了,同时log打印了将Routed rpc注册上来。
四、RPC问题
在odl集群当中,按照上述方法监听到了主从变化,如果在主从变化事件当中采用普通RPC的注册与注销会存在问题,例如IP分别为106、107、108的3台控制器组成集群,假设106被选举成为了主(Master),在106上的APP(假设称为APP1)成功注册了RPC,而107、108两台从(Slave)因为是从因此没有注册RPC,此时如果有一个模块(消费者)需要调用APP1的RPC,在控制器106上不存在问题,然后在107、108上就存在问题,因为107、108并注册该RPC,同时107、108上的消费者又不能夸控制器去调用106上的APP1的RPC。
又比如web前端往控制器发送请求,假设在107上的web前端发送请求至odl控制器,由于在107是从(Slave)并没有注册RPC,所以odl控制器并不能响应前端的请求。
因此,在集群当中注册RPC时不应该使用普通的RPC,而应该注册使用RoutedRPC,RoutedRPC能够将RPC进行路由,实现夸控制器调用。
比如在107web前端发送一个请求,但是107控制器不是主,并未注册RPC,不能响应该请求,但是能够将该请求路由至106(master),由106控制器处理之后返回给前端。
同理请求由108web发送也是一样的,将该请求路由给Master,由Master返回处理结果。
五、普通RPC转为RoutedRpc修改点
1、修改yang model,在rpc的input当中添加标记信息
同时添加context-instance
2、建立InstanceIdentifier
3、修改实现类,由注册rpc实现类改为注册RoutedRpc,同时注册rpc标记路径
六、RoutedRPC功能验证
在编译好模块并安装在3台控制器上之后。通过yangui来测试验证下。打开106的yangui:
添加账户操作,执行成功:
打开107上的yangui再执行添加一个账户操作:
Down 掉107控制器,访问106控制器,还是可以正常工作: