深入拆解Nightingale(一)

前言

了解了一段时间的开源项目夜莺,虽说看了一些官方提供了文档和还有视频,并且有幸参加快猫的黄埔营培训,算是新手入门水平。还是存在很多问题不懂,我想关键应该其中细节并没有很了解,另一方面也听大佬说‘阅读优秀的源代码是软件工程师提高自己编程能力和学习开源框架的最佳手段之一’,所有我打算写一系列关于夜莺监控在源码级别的分析,希望能做到深入拆解的地步并且深入浅出的表达出来,哈哈哈。

ps 夜莺是源于滴滴,目前被ccfos托管,用的开源协议是比较友好地Apache License 2.0

不过另一方面由于个人能力水平有限,Golang开发经验也停留在了解基础知识等级,其中必然存在一些理解或解释不到位的情况,甚至出错的可能,希望大家可以指出货给些建议,感激不尽:)

稍后文章中初步打算按照这样思路来开始,选取一个功能点作为研究对象:

  • 首先先了解一下整体架构,相应的组成部分,以及各模板的大概作用,如何组织;
  • 其次通过源码进行详细分析;
  • 最后针对特定问题解决办法深入学习:我的方式是什么?作者的方式是什么?有没有更好的解决办法?

概述

本篇作为第一篇打算先从整体结构上看看夜莺项目的目录结构,并有个初步认识。

架构介绍

架构方面文章介绍大家从README中就能看到我就不做过多的赘述了。简单的具有有这些特点,可接入多个时序库,专业告警能力,支持各种采集器,易用的 WebUI 和权限管控,统一的观测平台。适配多种业务架构,内置各类仪表盘和告警规则,开箱即用。

项目目录 

写文章时候夜莺已经是V6版本(main分支,Version: v6.0.0-da9f5fbb12ce2c291448e3d9a7c5282c911463f4),相较于V5有了很大变更,更加简化易用

./
├── LICENSE  //开源协议
├── Makefile  //构建脚本
├── README.md
├── README_en.md
├── alert/ //告警引擎相关##**
├── center/ //中心端(节点)管理相关##**
├── cli/ //版本升级相关**
├── cmd/ //项目的可执行文件
├── conf/ //解析配置文件相关
├── doc/ //文档相关
├── docker/ //容器相关
├── etc/  //配置文件目录
├── fe.sh*
├── go.mod  //项目版本依赖包
├── go.sum
├── integrations/ //内置模板,监控大盘和告警规则
├── memsto/ //猜测是memory storage,缓存相关
├── models/ //模型定义
├── pkg/ //公开的库代码,可被外部应用程序依赖使用
├── prom/ //对PromQL的支持相关
├── pushgw/ //转发网关(收采集器,发时序库)**
└── storage/  //存储模块,里面有redis##和关系库**

四大模块:

  • cli,升级用和主业务无关,先不了解
  • center,中心节点也就是n9e的完整版包含各种管理和配置,会调用alert和pushgw模块
  • alert,告警引擎,告警功能的各种代码
  • pushgw,转发网关,接收各种采集器的数据转发给时序库

剩余就是一些辅助模块

初步分析

首先,在storage就两个文件,通过ide很容易发现使用他们地方,可以了解到redis只在alert,center使用到,关系库在alert,center,cli,pushgw用到。

边缘机房,下沉部署时序库、告警引擎、转发网关的时候,要注意,告警引擎需要依赖数据库,因为要同步告警规则,转发网关也要依赖数据库,因为要注册对象到数据库里去,需要打通相关网络,告警引擎和转发网关都不用Redis,所以无需为Redis打通网络。

这里遇到第一个问题,边缘机房下沉部署场景,官网介绍是alert没有用到redis不用为他打通网络,但是我看初始化代码里面有storage.NewRedis报错会退出,没报错话是用在targetCache这个结构体,具体作用还不确认,也没准是个官方的小bug。

func Initialize(configDir string, cryptoKey string) (func(), error) {
    config, err := conf.InitConfig(configDir, cryptoKey)
    if err != nil {
        return nil, fmt.Errorf("failed to init config: %v", err)
    }

    logxClean, err := logx.Init(config.Log)
    if err != nil {
        return nil, err
    }

    db, err := storage.New(config.DB)
    if err != nil {
        return nil, err
    }
    ctx := ctx.NewContext(context.Background(), db)

    redis, err := storage.NewRedis(config.Redis)
    if err != nil {
        return nil, err
    }

    syncStats := memsto.NewSyncStats()
    alertStats := astats.NewSyncStats()

    targetCache := memsto.NewTargetCache(ctx, syncStats, redis)
    ...
}

其次,我经验项目目录结构没什么经验,不过好在夜莺项目的目录不复杂,比较清晰。参考网上一些关于GO项目布局的文章可以了解到虽然有个很流行的Standard Go Project Layout不过Go官方并没有给出书面标准,再这个里给了一些建议,也可以从CNCF的前两个项目kubernetesprometheus的目录可以看到这两个项目的实践。

总归来说,实际项目中,可以根据需要自定义目录结构和命名约定,只要团队和社区能够理解并遵循它们即可。重要的是保持一致性,这样可以更容易地理解和维护。

参考文章

阅读源代码的一些心得

CCF开源发展委员会介绍

开源协议ApacheLicense2.0介绍

怎么阅读学习源代码

golang 编程规范 - 项目目录结构

V6版本integrations目录作用

05|标准先行:Go项目的布局标准是什么?

夜莺V6.X架构介绍

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值