您的位置:首页 > 其它

Ceilometer项目源码分析----ceilometer分布式报警系统的具体实现(2)

2014-11-30 23:48 639 查看
感谢朋友支持本博客,欢迎共同探讨交流,由于能力和时间有限,错误之处在所难免,欢迎指正!如果转载,请保留作者信息。
博客地址:http://blog.csdn.net/gaoxingnengjisuan
邮箱地址:dong.liu@siat.ac.cn
PS:最近没有登录博客,很多朋友的留言没有看见,这里道歉!还有就是本人较少上QQ,可以邮件交流。
[b]ceilometer分布式报警系统的具体实现(2)[/b] 接续上篇博客来对分布式报警系统的具体实现进行分析。5 def check_mastership(self, eval_interval, api_client)
def check_mastership(self, eval_interval, api_client):
    """
    实现定期检测主控权角色;
    确定当前的partition是否是主控角色;
    如果为拥有主控权的partition,则根据不同的情况实现不同形式的报警器分配操作;
    """
    LOG.debug(_('%s checking mastership status') % self.this)
    try:
        assuming = not self.is_master
            
        """
        _is_master:确定当前的partition是否是主控角色;
        _master_role:作为拥有主控权的partition,根据不同的情况实现不同形式的报警器分配操作;
        """
        self.is_master = (self._is_master(eval_interval) and
                          self._master_role(assuming, api_client))
        self.presence_changed = False
    except Exception:
        LOG.exception(_('mastership check failed'))

方法小结:实现定期检测主控权角色;
确定当前的partition是否是主控角色;
如果为拥有主控权的partition,则根据不同的情况实现不同形式的报警器分配操作;
6 def presence(self, uuid, priority)
def presence(self, uuid, priority):
    """
    实现接收某一个Partition广播的其存在性信息;
    """
    report = PartitionIdentity(uuid, priority)
    if report != self.this:
        if report not in self.reports:
            self.presence_changed = True
        self._record_oldest(report)
        self.reports[report] = timeutils.utcnow()
        LOG.debug(_('%(this)s knows about %(reports)s') %
                  dict(this=self.this, reports=self.reports))

7 def report_presence(self)
def report_presence(self):
    """
    通过方法fanout_cast实现广播当前partition的存在性
    (包括uuid和优先级信息)通知给所有的Partition;
    """
    LOG.debug(_('%s reporting presence') % self.this)
        
    """
    广播当前partition的存在性(包括uuid和优先级信息)通知给所有的Partition;
    """
    try:
        self.coordination_rpc.presence(self.this.uuid, self.this.priority)
    except Exception:
        LOG.exception(_('presence reporting failed'))


8 def assigned_alarms(self, api_client)
def assigned_alarms(self, api_client):
    """
    通过指定客户端获取分配给当前partition的报警器;
    """
    if not self.assignment:
        LOG.debug(_('%s has no assigned alarms to evaluate') % self.this)
        return []

    try:
        LOG.debug(_('%(this)s alarms for evaluation: %(alarms)s') %
                  dict(this=self.this, alarms=self.assignment))
        return [a for a in api_client.alarms.list(q=[{'field': 'enabled',
                                                      'value': True}])
                if a.alarm_id in self.assignment]
    except Exception:
        LOG.exception(_('assignment retrieval failed'))
        return []

好了,分布式报警系统的源码具体实现解析完成,下面对分布式报警系统做总体的小结: 注:关于分布式报警系统遵循的协议在官方文档中进行了描述,具体协议的源码实现也在上述的方法中进行了比较详细的解析,这里直接引用一片博客中的内容对分布式报警系统协议进行简单的总结,博客地址http://blog.csdn.net/hackerain/article/details/38172941,感谢作者。
对于PartitionedAlarmService,它通过rpc实现了一套多个evaluator进程之间的协作协议(PartitionCoordinator),使得可以通过水平扩展来不断增大alarm service的处理能力,这样不仅实现了一个简单的负载均衡,还实现了高可用。下面我们就重点来说一下PartitionCoordinator这个协议。
PartitionCoordinator允许启动多个ceilometer-alarm-evaluator进程,这多个进程之间的关系是互相协作的关系,他们中最早启动的进程会被选为master进程,master进程主要做的事情就是给其他进程分配alarm,每个进程都在周期性的执行三个任务:
1.通过rpc,向其它进程广播自己的状态,来告知其他进程,我是活着的,每个进程中都保存有其他进程的最后活跃时间;
2.争抢master,每个进程都会不断的更新自己所维护的其它进程的状态列表,根据这个状态列表,来判断是否应该由自己来当master,判断一个进程是否是master的条件只有一个,那就是看谁启动的早;
3.检查本进程负责的alarm,会去调用ceilometer的api,来获取该alarm的监控指标对应的监控数据,然后进行判断,发送报警等;

当一个进程被确定为master之后,如果它不挂掉,那么它的master是不会被抢走的,该进程就会一直在履行master的职责:
1.当有新的alarm被创建时,master会将这些新创建的alarm平均的分配给其它worker进程,如果不能平均分配的,剩下的零头就由master自己来负责;
2.当有新的evaluator进程添加进来,或者是现有的evaluator进程被kill掉,那么master就会重新洗牌一次,把所有的alarm再平均的分配给现有的evaluator进程;
3.当master挂掉咋办呢?那么就会由第二个最早启动的进程接替master的位置,然后重新洗牌
通过这个协议,就实现了一个简单的分布式alarm服务;

好了,到此为止,分布式报警系统的具体源码实现分析和总结工作到此为止~~~~谢谢~~~~
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐