heartbeat模型涉及

主机找到主机所在组 根据组查找组的模板  根据模板(有继承关系)找到策略  并且合并策略

模本跟组绑定,不直接和主机绑定

//rpc接口  这个接口用来获取主机对应的所有策略

func (t *Hbs) GetStrategies(req model.NullRpcRequest, reply *model.StrategiesResponse) error {
	reply.HostStrategies = []*model.HostStrategy{}
	// 一个机器ID对应多个模板ID
	hidTids := cache.HostTemplateIds.GetMap()
	sz := len(hidTids)
	if sz == 0 {
		return nil
	}

	// Judge需要的是hostname,此处要把HostId转换为hostname
	// 查出的hosts,是不处于维护时间内的
	hosts := cache.MonitoredHosts.Get()
	if len(hosts) == 0 {
		// 所有机器都处于维护状态,汗
		return nil
	}

	tpls := cache.TemplateCache.GetMap()
	if len(tpls) == 0 {
		return nil
	}

	strategies := cache.Strategies.GetMap()
	if len(strategies) == 0 {
		return nil
	}

	// 做个索引,给一个tplId,可以很方便的找到对应了哪些Strategy
	tpl2Strategies := Tpl2Strategies(strategies)

	hostStrategies := make([]*model.HostStrategy, 0, sz)
	for hostId, tplIds := range hidTids {

		h, exists := hosts[hostId]
		if !exists {
			continue
		}

		// 计算当前host配置了哪些监控策略
		ss := CalcInheritStrategies(tpls, tplIds, tpl2Strategies)
		if len(ss) <= 0 {
			continue
		}

		hs := model.HostStrategy{
			Hostname:   h.Name,
			Strategies: ss,
		}

		hostStrategies = append(hostStrategies, &hs)

	}

	reply.HostStrategies = hostStrategies
	return nil
}

计算每个主机的模板,由于模板有继承关系,需要做合并

(最早建的模板)                               (最新建的模板) 

A               B                   C             D

(SA,SE)  (SC(metric+tag和SA相同),SH)

A的SA和SC要合并

E                      F

func CalcInheritStrategies(allTpls map[int]*model.Template, tids []int, tpl2Strategies map[int][]*model.Strategy) []model.Strategy {
	// 根据模板的继承关系,找到每个机器对应的模板全量
	/**
	 * host_id =>
	 * |a |d |a |a |a |
	 * |  |  |b |b |f |
	 * |  |  |  |c |  |
	 * |  |  |  |  |  |
	 */
	tpl_buckets := [][]int{}
	for _, tid := range tids {
		ids := cache.ParentIds(allTpls, tid)
		if len(ids) <= 0 {
			continue
		}
		tpl_buckets = append(tpl_buckets, ids)
	}

	// 每个host 关联的模板,有继承关系的放到同一个bucket中,其他的放在各自单独的bucket中
	/**
	 * host_id =>
	 * |a |d |a |
	 * |b |  |f |
	 * |c |  |  |
	 * |  |  |  |
	 */
	count := len(tpl_buckets)
	uniq_tpl_buckets := [][]int{}
	for i := 0; i < count; i++ {
		var valid bool = true
		for j := 0; j < count; j++ {
			if i == j {
				continue
			}
			if slice_int_eq(tpl_buckets[i], tpl_buckets[j]) {
				break
			}
			if slice_int_lt(tpl_buckets[i], tpl_buckets[j]) {
				valid = false
				break
			}
		}
		if valid {
			uniq_tpl_buckets = append(uniq_tpl_buckets, tpl_buckets[i])
		}
	}

	// 继承覆盖父模板策略,得到每个模板聚合后的策略列表
	strategies := []model.Strategy{}

	exists_by_id := make(map[int]struct{})
	for _, bucket := range uniq_tpl_buckets {

		// 开始计算一个桶,先计算老的tid,再计算新的,所以可以覆盖
		// 该桶最终结果
		bucket_stras_map := make(map[string][]*model.Strategy)
		for _, tid := range bucket {

			// 一个tid对应的策略列表
			the_tid_stras := make(map[string][]*model.Strategy)

			if stras, ok := tpl2Strategies[tid]; ok {
				for _, s := range stras {
					uuid := fmt.Sprintf("metric:%s/tags:%v", s.Metric, utils.SortedTags(s.Tags))
					if _, ok2 := the_tid_stras[uuid]; ok2 {
						the_tid_stras[uuid] = append(the_tid_stras[uuid], s)
					} else {
						the_tid_stras[uuid] = []*model.Strategy{s}
					}
				}
			}

			// 覆盖父模板
			for uuid, ss := range the_tid_stras {
				bucket_stras_map[uuid] = ss
			}
		}

		last_tid := bucket[len(bucket)-1]

		// 替换所有策略的模板为最年轻的模板
		for _, ss := range bucket_stras_map {
			for _, s := range ss {
				valStrategy := *s
				// exists_by_id[s.Id] 是根据策略ID去重,不太确定是否真的需要,不过加上肯定没问题
				if _, exist := exists_by_id[valStrategy.Id]; !exist {
					if valStrategy.Tpl.Id != last_tid {
						valStrategy.Tpl = allTpls[last_tid]
					}
					strategies = append(strategies, valStrategy)
					exists_by_id[valStrategy.Id] = struct{}{}
				}
			}
		}
	}

	return strategies
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

weixin_36013896

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值