业务指标可视化及监控系统搭建

加入新公司后不久开始怀念xflush,大部分情况下只需在页面上配置, 就可以实现业务指标的可视化及异常报警。
尝试利用现有的开源系统搭建,经过调研分析,最终确定的方案为statsd+influxdb+grafana。目前已上线,运行稳定。
具体过程不再细说,其中重要的取舍和配置介绍如下。

设计取舍

graphite:

老牌的企业级的监控工具。
环境搭建繁琐: 参考官方文档和网上各种文档,踩各种坑,加上工作上有其它事情在忙,搭建花了2-3天之久。
性能: graphite的存储组件whisper 是零散小文件存储,这样写指标文件会造成随机io。性能不敢恭维。
界面: 比较传统的树形结构,略显土气。进一步调研时发现了grafana。

引入StatsD

对数据时间范围内汇总,大大减少了db的压力。并能进行min, max, avg多维度统计。

存储选型InfluxDB

使用 Go 语言编写,无需外部依赖。反之OpenTSDB 是一种基于 HBase 的时间序列数据库。
最新版本的存储引擎底层是B+树, 也支持批量写入和缓存。
InfluxDB内部集成支持 graphite数据格式。 每次统计指标的min, max, avg对应到数据库中是一条记录的多个列, 相比graphite降低了不必要的io开销。

可视化Grafana:

界面相当漂亮,功能齐全的度量仪表盘和图形编辑器和查询编辑器。

监控报警

当时使用了kapacitor。 目前grafana4.0 已经release, 直接支持alerting。

业务指标采集

业务指标的主要内容: qps/qpm, 延迟。
对java-statsd-client进行了封装,使用注解和aop xml配置进行业务指标汇报,业务代码无侵入。
java-statsd-client 内部使用udp发送指标统计到StatsD,没有复杂的状态管理。对业务影响很小。另外一种方案就是记录到日志,flume收集后再发送到StatsD,彻底隔离对业务的影响。

性能扩展

StatsD为无状态节点,可通过负载均衡器部署多台保证可靠性和可伸缩性。
InfluxDB存储到达瓶颈后,可以做分库的方案,增加一个代理层。StatsD和Grafana通过代理层访问InfluxDB。

环境搭建

搭建statsD

安装

sudo yum install epel
sudo yum install nodejs
cd /opt/
sudo git clone git://github.com/etsy/statsd.git
sudo cp exampleConfig.js Config.js
sudo vim Config.js 
{
  graphitePort: 2003
, graphiteHost: "x.x.x.x"
, port: 8125
, flushInterval: 60000
,backends: [ "./backends/graphite", "./backends/console" ]
,debug: true
}
statsD默认为qps统计,如修改为qpm, 修改lib/process_metrics.js
current_timer_data["count_ps"]  修改为 current_timer_data["count_ps"] = timer_counters[key];
counter_rates[key]  修改为 counter_rates[key]  = value ;

运行

可直接运行 node stats.js config.js
另外node-forever 提供了守护的功能和LOG日志记录功能

wget  http://npmjs.org/install.sh --no-check-certificate 
sh install.sh   -- install nodejs first
[sudo] npm install forever
forever start stats.js config.js
forever list
  [0] stats.js [ 24597, 24596 ]

看日志 forever -o out.log -e err.log stats.js

搭建grafana

sudo rpm -ivh grafana-3.1.1-1470047149.x86_64.rpm
启动用户 grafana
服务名称 grafana-server
默认端口 3000
账号 admin
密码 admin
sudo service grafana-server start

搭建InfluxDB:

下载移步:https://www.influxdata.com/downloads/#influxdb

安装(RedHat&CentOS):

cat << EOF | sudo tee /etc/yum.repos.d/influxdb.repo
[influxdb]
name = InfluxDB Repository - RHEL \$releasever
baseurl = https://repos.influxdata.com/rhel/\$releasever/\$basearch/stable
enabled = 1
gpgcheck = 1
gpgkey = https://repos.influxdata.com/influxdb.key
EOF

sudo yum install influxdb
sudo service influxdb start

graphite plugin配置

InfluxDB内部有支持 graphite的plugin。 修改配置文件 /etc/influxdb/influxdb.conf 的graphite section, 增加相关的template

[[graphite]]
  enabled = true
  database = "mydb"
  bind-address = ":2003"
  protocol = "tcp"
  consistency-level = "one"

  # These next lines control how batching works. You should have this enabled
  # otherwise you could get dropped metrics or poor performance. Batching
  # will buffer points in memory if you have many coming in.

  batch-size = 5000 # will flush if this many points get buffered
  batch-pending = 10 # number of batches that may be pending in memory
  batch-timeout = "1s" # will flush at least this often even if we haven't hit buffer limit
  udp-read-buffer = 0 # UDP Read buffer size, 0 means OS default. UDP listener will fail if set above OS max.

  # This string joins multiple matching 'measurement' values providing more control over the final measurement name.
  separator = "."

  # Default tags that will be added to all metrics.  These can be overridden at the template level
  # or by tags extracted from metric
  #tags = ["region=us-east", "zone=1c"]

  # Each template line requires a template pattern.  It can have an optional
  # filter before the template and separated by spaces.  It can also have optional extra
  # tags following the template.  Multiple tags should be separated by commas and no spaces
  # similar to the line protocol format.  There can be only one default template.
  templates = [
    ## stats.company.services.facade.apay.PayFacade.*
    #"stats.company.services.facade.* ....measurement.servicename.facadename.field",
    "stats.*.services.facade.* .measurement...servicename.facadename.method",

    ## stats_counts.company.services.facade.servicename.facadename.methodname
    "stats_counts.*.services.facade.* measurement.measurement...servicename.facadename.method",

    ## stats.timers.company.services.facade.apay.PayFacade.*.mean
    "stats.timers.*.services.facade.* .measurement.measurement...servicename.facadename.methodname.field",
  ]

你可能感兴趣的:(业务指标可视化及监控系统搭建)