一、什么是Nightingale

GitHub 地址:https://github.com/didi/nightingale

在 Open-Falcon 基础上,结合滴滴内部的最佳实践,其在性能、可维护性、易用性方面做了大量的改进。作为集团统一的监控解决方案,支撑了滴滴内部数十亿监控指标,覆盖了从系统、容器、到应用等各层面的监控需求。

官网描述:
https://n9e.didiyun.com/docs/community/

Nightingale是一套衍生自Open-Falcon的互联网监控解决方案,融入了滴滴的最佳实践,由于改动太大,优化太多,产品上已经无法与Open-Falcon平滑兼容,故而单开一个项目。

编写Open-Falcon第一行代码是在2014年,几年下来,有超过200家商业公司在生产环境使用,我们也在逐步优化,夜莺可以说是一个颠覆级版本,性能、易用性、可用性都做了大幅改进,在滴滴抗住了7.7亿(包括物理机、虚机、容器、网络、业务模块的)监控指标,这是一个新的征程,期待与诸君携手,把监控这个领域,做到极致!

二、Nightingale与Open-Falcon对比

[推荐阅读]关于open falcon 与nightingale 的一些调研
参考URL: https://www.cnblogs.com/xiaobaiskill/p/13045313.html

  1. 功能不同点对比
  • 告警引擎重构:
    Open-Falcon 的告警策略,在监控数据推送上来的同时会触发策略判断,这种「推」的模式优势是策略的判断时效性非常高,但是不利于更高级的告警策略的支持和扩展,比如多条件的组合报警就很难支持。Nightingale 转为推拉结合模式,通过推模式保证大部分策略判断的效率,通过拉模式支持了与条件告警和nodata告警;

  • 引入了导航对象树:
    将 Open-Falcon 采用的扁平 HostGroup,转为 Nightingale 的导航对象树,对象树本质上是一种对监控对象的分组管理机制,方便查找和查看监控对象,以及对监控对象设置监控策略等管理动作。同时在 Nightingale 中,去除了告警模板的概念,告警策略直接与树节点绑定,简化设计,大幅提升灵活度和易用性;

  • 索引模块升级换代:
    Open-Falcon 使用 MySQL 存储 metrics 的索引数据,在扩展性和灵活性上存在瓶颈。Nightingale 根据监控需求,设计开发了全新的内存索引模块 index,查询方式更多样,查询效率更高,避免了原来 MySQL 索引数据达到亿级别时面临的维护优化工作;

  • 时序数据库优化:
    在 Open-Falcon 存储模块 Graph 的基础上,引入 Facebook 的 Gorilla 压缩方案,近期几个小时的数据采用内存存储,大幅提升数据查询效率,长期数据仍然使用 rrdtool 数据格式存储在硬盘上。同时进一步完善了时序数据库的性能和稳定性;

  • 告警引擎高可用改进:
    告警引擎 judge 模块通过心跳机制做到了故障自动摘除,再也不用担心单个 judge 宕机导致部分策略失效,需要人工介入的问题,index 模块也是采用类似方式保证可用性;

  • 原生内置日志监控功能:
    Nightingale 客户端原生内置了日志匹配和指标抽取能力,在 web 控制台页面上支持了日志匹配规则的配置,同时也支持读取目标机器特定目录下的配置文件的方式,让业务指标监控更为易用;

  • 可运维性增强:
    将 portal(falcon-plus中的api)、uic、dashboard、hbs、alarm 合并为一个模块:monapi,简化了系统整体部署难度,原来的部分模块间调用变成进程内方法调用,性能更高;

  • 配置文件中心化:
    配置文件做了易用性改造,抽取数据库通用配置到 mysql.yml,抽取端口实例地址等关联配置到 address.yml,大批配置在代码里给了默认值,使得配置文件更清晰,易于维护。

三、Nightingale架构

在这里插入图片描述因为要应对海量的监控数据,所以图中的所有模块都支持横向水平扩展,绿色部分负责了采集、传输和存储功能,红色部分负责了告警功能,紫色部分负责和用户交互,用户可以通过监控数据上报API将数据上报给Collector或者Transfer,之后Transfer会将数据转发给TSDB,TSDB接收到数据之后会生成索引数据推给index,用户在看图的时候会先从index查询索引,然后再从TSDB查询监控指标。另一份会将配置了监控策略的监控数据发给Judge,Judge收到数据之后,会和内存中的告警策略做匹配,匹配成功之后,会进行告警判别,然后产生告警事件,将告警事件写的Redis中。

  • nginx
    nginx作为反向代理,根据不同location代理了monapi、transfer、index的前端请求,同时,pub目录下的前端资源也是由nginx来serve,nginx的配置文件参看etc/nginx.conf。
    安装后静态文件路径为/usr/local/n9e/pub,同时提供一个 nginx 配置文件/usr/local/n9e/etc/nginx.conf,建议安装好 nginx 之后直接替换即可,如组件为分布式部署,建议根据实际配置修改 nginx 配置文件里对应的 upstream 服务器地址。

  • monapi
    主要承接web端的请求,无状态,可以水平扩展部署多台,依赖mysql和redis
    ,请提前把密码准备好。monapi要run起来依赖的配置文件有3个,除了address.yml,另外就是mysql.yml和monapi.yml,mysql.yml里是数据库连接配置

四、Nightingale安装

滴滴夜莺Nightingale安装教程
参考URL: https://blog.csdn.net/mz_418/article/details/105065509

1. 准备工作

  1. 安装nginx
  2. 安装mysql和redis
  3. 安装golang
  4. linux系统创建 n9e

2. 源码编译安装

# clone代码并编译打包,pack时会自动build,打包成一个tar.gz
git clone https://github.com/didi/nightingale.git
cd nightingale && ./control build && ./control pack

3. 通过rpm包安装(推荐)

官网下载:https://n9e.didiyun.com/docs/install/rpm/

经过测试,可以直接参考官网步骤。

All in one 安装

tar zxvf n9e-2.7.2-dbd81ee.el7.x86_64.rpm-bundle.tar.gz
yum install n9e-* -y

安装之后,需要安装 nginx,mysql 组件。 mysql 导入表结构

mysql -uroot -p </usr/local/n9e/sql/n9e_hbs.sql
mysql -uroot -p </usr/local/n9e/sql/n9e_mon.sql
mysql -uroot -p </usr/local/n9e/sql/n9e_uic.sql

安全考虑,建议为 n9e 独立建立 mysql 用户,在 mysql 里创建 n9e 用户并授权

mysql>create user n9e@localhost identified by 'n9epwd123';
mysql>grant all on n9e_hbs.* to n9e@localhost;
mysql>grant all on n9e_mon.* to n9e@localhost;
mysql>grant all on n9e_uic.* to n9e@localhost;

flush privileges;

已建立 n9e 用户,密码为 n9epwd123 替换默认 nginx 配置文件,并重启 nginx 服务

cp /usr/local/n9e/etc/nginx.conf /etc/nginx/
systemctl restart nginx

systemctl enable --now n9e-index n9e-tsdb n9e-transfer n9e-monapi n9e-judge n9e-collector

使用浏览器打开http://ip 即可访问,默认账号 root 密码 root

3.1 修改配置文件

配置文件在etc目录,着重看一下mysql.yml,修改mysql访问的用户名和密码,另外redis密码默认为空,如果您配置了redis的访问密码,需要对应的修改monapi和judge的配置文件,将redis密码配置好。另外在etc/address.yml下可以看到各个模块监听的端口,如果与本地其他服务端口冲突了,就需要手工修改一下啦。

修改mysql端口或账号密码

cd /usr/local/n9e/etc
vi mysql.yml

修改redis 密码或端口:
需要对应的修改monapi和judge的配置文件

vi monapi.yml
vi judge.yml 

4. 安装过程问题定位

安装好之后不符合预期,先到 logs 目录下,把所有日志检查一遍,看有没有报错
cd /usr/local/n9e/logs

正常启动应该有如下几个进程:

[root@localhost etc]# ps axf |grep n9e
30321 pts/1    S+     0:00      |   \_ grep --color=auto n9e
31062 ?        Ss     0:00 nginx: master process /usr/local/openresty/nginx/sbin/nginx -c /usr/local/n9e/etc/nginx.conf
  883 ?        Ssl    0:02 /usr/local/n9e/n9e-index
  884 ?        Ssl    0:03 /usr/local/n9e/n9e-tsdb
  885 ?        Ssl    0:11 /usr/local/n9e/n9e-transfer
  887 ?        Ssl    0:02 /usr/local/n9e/n9e-judge
  888 ?        Ssl    0:05 /usr/local/n9e/n9e-collector
29393 ?        Ssl    0:01 /usr/local/n9e/n9e-monapi

五、Nightingale使用

推荐直接看官网说明:
https://n9e.didiyun.com/docs/usage/

1. 端口监控

端口监控在夜莺中通过配置具体的采集策略来指定采集哪些端口,也支持读取目标机器标识文件

支持两种配置方式,一个是在目标机器的指定目录创建元信息文件,一个是在页面上配置采集策略。

  • 目标机器元信息文件方式
    可以查看collector的配置文件,里边有个portPath配置项,可以把要监听的端口touch一个文件放到portPath指定的路径下,collector组件会自动探测,自动采集。

    比如要采集n9e这个服务的monapi组件的端口5800的存活性,可以到portPath指定的路径(没有的话手工创建出对应目录)下,创建一个10_5800的文件,里边的内容是n9e-monapi。

    文件名命名规范KaTeX parse error: Expected group after '_' at position 7: {采集频率}_̲{采集的端口}
    文件内容是这个模块的名称,比如n9e-monapi,这样报警的时候我们看到n9e-monapi就知道是哪个服务出问题了,不允许有空格,引号等特殊字符
    对于业务服务来说,我们在部署服务的时候,可以将这个端口文件创建出来,这样平台就可以帮我们监控这个服务了,当我们下线服务的时候,把这个端口文件顺便删除,这样平台就不再监控这个端口了。

    端口采集完了,我们可以在所负责的服务的公共父节点配置一条监控策略,就可以搞定我们手下的所有的服务的所有的模块的所有的端口的监控:

    采集周期假设为20秒,策略统计周期可以配置为60秒,每个值都=0则报警,端口监控的metric是:proc.port.listen无需每个端口分别配置

  • 页面上配置采集策略
    这个方式比较简单,不过多赘述,采集策略配置的时候有个service字段,需要填写模块的名称,相当于目标机器元信息文件的内容部分。

注意:在界面采集配置时,配置界面会显示,当前这个配置的采集指标,请留意!
比如:

端口监控指标
proc.port.listen

2. 进程监控

进程监控在夜莺中通过配置具体的采集策略来指定采集哪些进程,也支持读取目标机器标识文件
支持两种配置方式,一个是在目标机器的指定目录创建元信息文件,一个是在页面上配置采集策略。

  • 目标机器元信息文件方式
    进程监控和端口监控的处理逻辑类似,都是在本地touch一个文件,告诉collector去监控哪个进程,如果要监控多个进程,就需要touch多个文件。

    对于端口监控而言,端口号具备唯一性,但对进程而言,进程名(查看进程名可以cat /proc//status)不具备唯一性,比如python语言写的进程,进程名都是python,java语言写的进程,进程名都是java,那我们应该touch一个什么样的文件,来准确告诉collector我们要采集具体哪个进程呢?

    我们需要找一个能方便区分一个进程的东西,这里我们有两个办法,一个是使用进程的名字,一个是使用进程的cmdline(参看/proc//cmdline),比如touch一个10_name_n9e-monapi文件,就可以采集进程名为n9e-monapi的进程,因为n9e-monapi是go写的,进程名就是n9e-monapi,所以这么配置是OK的。如果进程name无法很好的区分,可以touch一个10_cmdline_xx的文件,假设要监控的进程pid是5648,xx就是/proc/5648/cmdline的一个子串即可,只要这个子串能与其他进程的cmdline区分开,就无需使用整个cmdline内容。举例:我们使用java -c uic.properties启动了一个java进程,其cmdline为:java-cuic.properties,我们要监控这个进程只需要touch一个10_cmdline_uic.properties的文件即可。

    对于文件内容,和端口监控一样,可以写进程的模块名,监控数据上报的时候,就会带上这个信息,作为一个tag上报

    总结: 建议使用cmdline形式, 无需使用整个cmdline内容,只要这个子串能与其他进程的cmdline区分开。

  • 页面上配置采集策略
    这个方式比较简单,不过多赘述,采集策略配置的时候有个service字段,需要填写模块的名称,相当于目标机器元信息文件的内容部分。

注意:在界面采集配置时,配置界面会显示,当前这个配置的采集指标,请留意!
比如,你配置进程方式,如下采集指标如下:

进程采集指标 proc.num

六、配置sender

官网: https://github.com/n9e/mail-sender

sender可以参看社区已有的Sender(https://github.com/n9e?q=sender&type=&language=),没有提供voice-sender和sms-sender,是因为各家通道商接口各异没有标准。

Nightingale的理念,是将告警事件扔到redis里就不管了,接下来由各种sender来读取redis里的事件并发送,毕竟发送报警的方式太多了,适配起来比较费劲,希望社区同仁能够共建。

1. mail-sender

官网: https://github.com/n9e/mail-sender
最常见的告警发送方式是邮件,所以这里我写了一个mail-sender,供参考

  1. github下载源码
  2. 编译安装
unzip mail-sender-master.zip
cd mail-sender-master/
./control build
编译完成后,打包
tar zcvf mail-sender.tar.gz mail-sender etc/mail.html etc/mail-sender.yml
cp mail-sender.tar.gz /usr/local/n9e/
tar -zxvf mail-sender.tar.gz 
  1. 编辑配置
    vi /usr/local/n9e/etc/mail-sender.yml
    读取告警事件,自然要给出redis的连接地址;发送邮件,自然要给出smtp配置;直接修改etc/mail-sender.yml即可

配置etc/mail-sender.yml,相关配置修改好,我们先来测试一下smtp是否好使, ./mail-sender -t you@example.com,程序会自动读取etc目录下的配置文件,发一封测试邮件给you@example.com

七、collector单独部署

官方参考视频: https://s3-gz01.didistatic.com/n9e-pub/video/n9e-install-collector.mp4

collector的部署依赖的文件是n9e-collector二进制、etc/collector.yml、etc/address.yml

把这三个文件扔到目标机器的/home/n9e目录下,然后修改etc/address.yml中的monapi和transfer的addresses字段,配置为真实的server的ip地址即可。因为collector要跟transfer和monapi通信,所以必须知道这俩组件的ip地址。

思路: 把collector 打个包,分发到目标机并启动。

  1. 把你之前安装的collector 打个包,分发到你要安装的新的目标机

    cd /usr/local/n9e
    mkdir tmp
    mkdir -p tmp/etc
    cp n9e-collector tmp/
    cp etc/address.yml tmp/etc/
    cp etc/collector.yml tmp/etc/
    
  2. 复制n9e-collector.service,让collector systemctrf管理,开机自启动

#确认文件存在
cat /usr/lib/systemd/system/n9e-collector.service
cp /usr/lib/systemd/system/n9e-collector.service  tmp/etc/

address.yml 中 修改 monapi、tranfer的ip 为collector要连接的服务的ip。
collector.yml 中修改 自己节点ip(或者使用shell脚本获取ip模式)

打包压缩文件

cd tmp/
tar zcvf collector.tar.gz *
  1. 分发到目标并安装

注意:根据你打包的 n9e-collector.service 文件中配置的路径,放置包,如下, /usr/local/n9e/

[root@localhost tmp]# cat etc/n9e-collector.service 
[Unit]
Description=Nightingale Collector
After=network-online.target
Wants=network-online.target

[Service]
# modify when deploy in prod env
User=root
Group=root

Type=simple
ExecStart=/usr/local/n9e/n9e-collector
WorkingDirectory=/usr/local/n9e

Restart=always
RestartSec=1
StartLimitInterval=0

[Install]
WantedBy=multi-user.target[

你需要mkdir对应的目录,把包放置相应的目录

mkdir -p  /usr/local/n9e/
cd /usr/local/n9e/
tar -zxvf collector.tar.gz 
cp etc/n9e-collector.service /usr/lib/systemd/system/
vi etc/n9e-collector.service /usr/lib/systemd/system/
systemctl enable  n9e-collector

八、使用过程问题整理

1. 节点有多个ip,上报的ip不是自己想要的

官网参考: https://s3-gz01.didistatic.com/n9e-pub/video/n9e-usage-identity.mp4

collector.yml 中的identity 可以写死,一般是ip,作用colletor用这个作为endpoint的内容。

修改collector.yml 中的identity中的specify 可以写死。

九、参考

Nightingale滴滴夜莺监控系统入门(五)–采集功能
参考URL: https://blog.csdn.net/weixin_43876361/article/details/114010444

Logo

一站式 AI 云服务平台

更多推荐