城的灯

基于Graphite的监控方案

需求

公司目前的监控粒度非常粗放,只做了些常规的监控,如:服务器的CPU/磁盘/网络,数据库,消息队列,以及一些核心业务的健康检查等。这种粒度的监控对发展初期的创业公司来说已经足够,但是对于接下来的发展便开始捉襟见肘了。个人认为监控不能浮于形式,不是采集一堆数据进行简单的罗列或者生成Dashboard,而是能够通过这些数据产生决策,告诉我们哪里出了问题,该如何解决,甚至自动解决。所以我们要能够自动采集系统中的各种metric,然后各种metric汇集到数据中心进行处理,最后便是展现、报警以及自动修复等逻辑。


分析

关于监控,业界成熟的方案数不胜数,如何从中选择适合自己的解决方案便是其中的难点。确定方案之前,我们首先需要对自己的系统架构进行梳理,确定我们所选方案兼容目前架构。由于我们的系统基本全部都构建在一系列的Java技术栈之上,Zabbix已经广泛应用在各个系统之中,所以我们做了如下的几点约定:

  1. Metric的获取只能用Java实现
  2. 服务器以及一些中间件的常规监控延续使用Zabbix
  3. 报警逻辑使用Zabbix实现
  4. 数据能够实现多个维度的自由组合叠加以及横向对比
  5. Metric获取的侵入性要非常小

方案

经过了前面两步,其实后面的方案选择就非常简单了,最终我们新版的监控架构图如下:

MonitorStructure

  • Metrics:获取JVM中的指标项(metric),并将指标项发布到Graphite。
  • Graphite:数据收集处理以及对外提供接口。
  • Grafana:通过Graphite-web接口获取数据进行图表展示。
  • Zabbix:通过Graphite-web接口获取数据,来进行报警以及服务器常规监控。

实施

方案确定之后,便可以开始实施了。首先需要将环境配置起来,然后才是代码层面的嵌入。Graphite的安装不是一件容易的事情,各个平台的安装都不相同,你可以把这当做是一种痛并快乐着的享受,下面便是我在Ubuntu上进行环境配置的步骤,仅供参考:

Graphite安装

  1. sudo apt-get install nginx uwsgi uwsgi-plugin-python
  2. sudo apt-get install graphite-web graphite-carbon

安装就上面两步,当然在安装的过程中,缺少什么安装下就行了,接下来便可以开始配置Graphite。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
1. sudo vim /etc/graphite/local_settings.py
#将时区修改为正确的时区
TIME_ZONE = 'Asia/Shanghai'
#配置数据库,当然你也可以使用默认的sqlite3
DATABASES = {
'default': {
'NAME': 'graphite',
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'USER': 'postgres',
'PASSWORD': 'postgres',
'HOST': 'localhost',
'PORT': ''
}
}

2. 当配置好了之后,并可以执行`sudo graphite-manage syncdb`,进行数据库信息同步。

3. sudo vim /etc/default/graphite-carbon
CARBON_CACHE_ENABLED=true

4. sudo vim /etc/carbon/carbon.conf
#开启Carbon的log rotation
ENABLE_LOGROTATION = True

5. sudo vim /etc/carbon/storage-schemas.conf
#配置storage schemas
#意思是匹配任何以test.开头的metrics,采用三种方式收集存储数据:
#1.10s:10m---每10秒创建一个数据点,保存10分钟内该类型的数据点。
#2.1m:1h---每1分钟创建一个数据点,保存1小时内该类型的数据点。
#3.10m:1d---每10分钟创建一个数据点,保存一天内的该类型的数据点。
[test]
pattern = ^test\.
retentions = 10s:10m,1m:1h,10m:1d

6. sudo cp /usr/share/doc/graphite-carbon/examples/storage-aggregation.conf.example /etc/carbon/storage-aggregation.conf
#/etc/carbon/storage-aggregation.conf中的aggregation method默认使用的是average,其中的xFileFactor的值代表Carbon做聚合的最小百分比值,根据你的具体情况修改。

7. sudo vim /etc/nginx/sites-available/graphite.conf
#nginx配置
upstream graphite {
server unix:///run/uwsgi/app/graphite/socket;

keepalive 600;
}

server {
listen 80;
server_name graphite.yangguo.info;

access_log /var/log/nginx/graphite.access.log;
error_log /var/log/nginx/graphite.error.log;


location / {
uwsgi_pass graphite;
include uwsgi_params;
}
}

8. sudo ln -s /etc/nginx/sites-available/graphite.conf /etc/nginx/sites-enabled

9. sudo vi /etc/uwsgi/apps-available/graphite.ini
[uwsgi]
processes = 8
uid = _graphite
gid = _graphite
master = True
chdir = /usr/share/graphite-web
wsgi-file = graphite.wsgi
chmod-socket = 666
enable-threads = true

10. sudo ln -s /etc/uwsgi/apps-available/graphite.ini /etc/uwsgi/apps-enabled

11. sudo service carbon-cache start
sudo service nginx start
sudo service uwsgi start

对于上面第五步metrics的配置,精度的具体配置得看自己的业务,并不是粒度越细越好。江南白衣有篇很好的文章:Graphite的百万Metrics实践之路,就直接引过来,希望对大家有帮助。Graphite的安装及配置并不是非常容易,如果碰见问题,查查资料便能够解决,特别注意各种版本的兼容问题。

Whisper存储模式和聚合

在开始的架构图中,你可能已经看见Graphite包含三个组件,CarbonGraphite-web你可以不了解。但是如果你对Whisper的内部运行原理不是很了解,你可能会碰见如下的困惑:

  • 为什么我的数据点被平均了?
  • 为什么我周期性的发布了数据点,却看不见任何数据?
  • 我发布了很多天的数据,却只能看见一天的数据?
  • 为什么看见的数据跟我发布的数据点好像对应不上?

要解决以上的问题,首先我们要明白Whisper是如何存储数据的,然后要了解它的聚合规则,最后还有数据点的移动。只要掌握了这些,我们才能配置合理的存储模式以及聚合规则,从而得到我们想要的结果。InfoQ上的DevOps实战:Graphite监控上手指南已经讲的非常透彻,此处本着不造轮子的原则,就不复述了。

Grafana安装

Grafana安装便非常简单,具体步骤如下:

  1. $ wget https://grafanarel.s3.amazonaws.com/builds/grafana_2.1.1_amd64.deb
  2. $ sudo apt-get install -y adduser libfontconfig
  3. $ sudo dpkg -i grafana_2.1.1_amd64.deb

安装完成之后,便可以启动grafana-server了:

$ sudo service grafana-server start

最后设置开机启动:

$ sudo update-rc.d grafana-server defaults 95 10

别的环境安装教程见此处

Grafana安装完成之后,便可以通过配置Data sources了,然后自定义需要展示的Dashboard,至此GraphiteGrafana的安装与集成便完成了。

Metrics使用

Metrics它不但提供了Gauge、Counter、Meter、Histogram、Timer等度量工具类以及Health Check功能,而且它还提供了很多模块为第三方库或者应用提供辅助统计信息,比如Jetty,Logback,Log4j,Apache HttpClient,Ehcache,JDBI,Jersey,最后它还可以将度量数据发送给Ganglia和Graphite以提供图形化的监控。作为一款监控指标的度量类库,从功能完善度已经易用性来说,它是表现的相当优秀。

具体的业务指标需要自己的定义,然后完成采集,如果你使用spring,你可以使用metrics-spring,这又可以减轻一部分你的工作量。具体代码如何与代码集成,阅读下相关文档就可以很快上手了。

效果

当完成上面三步,我们的数据采集,数据的汇总,数据展现都正常之后,我们就可以看看效果了,这是我简单的截了一个我的测试环境的图,供大家参考。
jvm监控
logic监控

监控

graphite之所以被大家广泛采用,我觉得graphite-web API功不可没,它可以根据你将你需要的数据通过PNG图片或者JSON返回给你。正式基于这点,我们可以非常方便的与自己的报警系统集成,我们可以细粒度的监控我们的每项指标,然后来指定报警规则,并可以通过图表+文字的形式发送出来。

请求1:http://graphite.travelzen.com/render?target=jvm.192_168_161_87.ibe-interface-server.memory.heap.usage得到了一个png图片

api图片

请求2:http://graphite.travelzen.com/render?target=jvm.192_168_161_87.ibe-interface-server.memory.heap.usage&format=json得到json数据

1
2

[{"target": "jvm.192_168_161_87.ibe-interface-server.memory.heap.usage", "datapoints": [[0.01583333333333333, 1440424200], [0.016166666666666666, 1440424800], [0.015999999999999997, 1440425400], [0.01583333333333333, 1440426000], [0.015999999999999997, 1440426600], [0.01583333333333333, 1440427200], [0.015999999999999997, 1440427800], [0.01583333333333333, 1440428400], [0.016166666666666666, 1440429000], [0.016166666666666666, 1440429600], [0.015999999999999997, 1440430200], [0.016000000000000004, 1440430800], [0.01633333333333333, 1440431400], [0.01633333333333333, 1440432000], [0.01616666666666667, 1440432600], [0.01616666666666667, 1440433200], [0.01583333333333333, 1440433800], [0.01616666666666667, 1440434400], [0.0165, 1440435000], [0.016000000000000004, 1440435600], [0.016, 1440436200], [0.016166666666666666, 1440436800], [0.01616666666666667, 1440437400], [0.01583333333333333, 1440438000], [0.01633333333333333, 1440438600], [0.01633333333333333, 1440439200], [0.015666666666666666, 1440439800], [0.01633333333333333, 1440440400], [0.016333333333333335, 1440441000], [0.01583333333333333, 1440441600], [0.01616666666666667, 1440442200], [0.015999999999999997, 1440442800], [0.01616666666666667, 1440443400], [0.015999999999999997, 1440444000], [0.015999999999999997, 1440444600], [0.016, 1440445200], [0.01616666666666667, 1440445800], [0.01583333333333333, 1440446400], [0.01616666666666667, 1440447000], [0.016000000000000004, 1440447600], [0.016000000000000004, 1440448200], [0.01616666666666667, 1440448800], [0.015999999999999997, 1440449400], [0.016, 1440450000], [0.01616666666666667, 1440450600], [0.01583333333333333, 1440451200], [0.01616666666666667, 1440451800], [0.016000000000000004, 1440452400], [0.016000000000000004, 1440453000], [0.016166666666666666, 1440453600], [0.01616666666666667, 1440454200], [0.016000000000000004, 1440454800], [0.016166666666666666, 1440455400], [0.01616666666666667, 1440456000], [0.01616666666666667, 1440456600], [0.01616666666666667, 1440457200], [0.015999999999999997, 1440457800], [0.016000000000000004, 1440458400], [0.01633333333333333, 1440459000], [0.015666666666666666, 1440459600], [0.01633333333333333, 1440460200], [0.01583333333333333, 1440460800], [0.01616666666666667, 1440461400], [0.016, 1440462000], [0.01616666666666667, 1440462600], [0.016166666666666666, 1440463200], [0.016, 1440463800], [0.01633333333333333, 1440464400], [0.01633333333333333, 1440465000], [0.0165, 1440465600], [0.01633333333333333, 1440466200], [0.017, 1440466800], [0.017, 1440467400], [0.017, 1440468000], [0.016666666666666663, 1440468600], [0.017, 1440469200], [0.016999999999999998, 1440469800], [0.016833333333333332, 1440470400], [0.017, 1440471000], [0.020500000000000004, 1440471600], [0.023, 1440472200], [0.02266666666666667, 1440472800], [0.023000000000000003, 1440473400], [0.02316666666666667, 1440474000], [0.022833333333333334, 1440474600], [0.023, 1440475200], [0.022500000000000003, 1440475800], [0.023, 1440476400], [0.022833333333333334, 1440477000], [0.022833333333333334, 1440477600], [0.022833333333333337, 1440478200], [0.022833333333333337, 1440478800], [0.022833333333333337, 1440479400], [0.023, 1440480000], [0.023, 1440480600], [0.022833333333333337, 1440481200], [0.023, 1440481800], [0.016166666666666666, 1440482400], [0.015000000000000003, 1440483000], [0.015000000000000003, 1440483600], [0.015000000000000003, 1440484200], [0.015000000000000003, 1440484800], [0.015333333333333332, 1440485400], [0.015333333333333334, 1440486000], [0.01633333333333333, 1440486600], [0.025, 1440487200], [0.024999999999999998, 1440487800], [0.025333333333333336, 1440488400], [0.025, 1440489000], [0.02533333333333333, 1440489600], [0.025333333333333336, 1440490200], [0.025, 1440490800], [0.024833333333333336, 1440491400], [0.02633333333333333, 1440492000], [0.026499999999999996, 1440492600], [0.02633333333333333, 1440493200], [0.027500000000000004, 1440493800], [0.026666666666666665, 1440494400], [0.026666666666666672, 1440495000], [0.025500000000000002, 1440495600], [0.025000000000000005, 1440496200], [0.025000000000000005, 1440496800], [0.025000000000000005, 1440497400], [0.025000000000000005, 1440498000], [0.025000000000000005, 1440498600], [0.025000000000000005, 1440499200], [0.025000000000000005, 1440499800], [0.025000000000000005, 1440500400], [0.025000000000000005, 1440501000], [0.025000000000000005, 1440501600], [0.025000000000000005, 1440502200], [0.025000000000000005, 1440502800], [0.025833333333333337, 1440503400], [0.027500000000000004, 1440504000], [0.027500000000000004, 1440504600], [0.027500000000000004, 1440505200], [0.027500000000000004, 1440505800], [0.027500000000000004, 1440506400], [0.027500000000000004, 1440507000], [0.027500000000000004, 1440507600], [0.027500000000000004, 1440508200], [0.025500000000000002, 1440508800], [0.02518518518518519, 1440509400], [null, 1440510000]]}]

我只是简单的说明了下API的使用,API还有非常多的函数可供选择,每次当你有新的需求不妨先翻翻是不是有现成的函数或者方法可供使用。

监控这个老生常谈的话题,其实没有多少干货,看似简单其实做好并不容易。很多东西并不复杂,最重要的是要契合自己的业务,知道自己的关注点。Enjoy yourself !