基于Prometheus监控的应用与实践

监控与告警

为什么要做监控告警?
  • 系统监控:CPU、内存、硬盘使用情况
  • 网络监控:网络上行、下行速率
  • 服务监控:应用程序的健康性、可用性
  • 反馈通知:告知维护人员,并及时修复问题
监控与告警遇到的挑战
  • 实时性:从数据变化到可视化、告警的时间
  • 适应性:满足基础设施快速增长时的需求
  • 服务集成:关注业务层面的监控

监控工具对比

Nagios
  • 优点
    • 监控所有协议(HTTP, FTP, SSH, POP3, SMTP, SNMP, MySQL…)
    • 完全独立,没有依赖
    • 支持震荡检测
    • 插件化
  • 缺点
    • Web页面不友好
    • 不支持数据的图表显示
Zabbix
  • 优点
    • 监控所有协议(HTTP, FTP, SSH, POP3, SMTP, SNMP, MySQL…)
    • Web界面友好
    • 可以监控Log文件
    • 支持Client agent (Pull、Push model)
  • 缺点
    • 配置比较复杂
    • 需要关系型数据库支持 (mysql、PostgreSQL..)
Prometheus
  • 优点
    • 用Go编写,性能好
    • 支持多语言客户端 (sdk)
    • 支持Pull和Push模式
    • 支持多种数据可视化模式 (Grafana)
  • 缺点
    • 缺少插件支持

使用Prometheus搭建监控系统

Prometheus架构

  • Job / Exporter
    • promethues提供用来获取监控数据的exporter
    • exporter可以直接从系统、数据库中获取监控数据
  • Promethues Server
    • 从exporter或者服务提供的metrics中pull数据
    • 存储到自己的数据库中
    • 提供PromQL为前端提供查询语言
  • Interface
    • 提供默认的Web UI
    • 提供Promethues Dashboard
    • 支持Grafana作为数据展示的Dashboard
    • 提供Client API
  • PushGateway
    • 为服务级别监控提供push的机制
    • 为Prometheus提供合并后的暂时性业务数据
    • Promethues Server可以直接从PushGateway中批量pull数据
  • AlertManager
    • 接收promethues发送的告警内容
    • 按照告警配置处理告警内容
    • 通过不同渠道将告警发送给不同责任人
用Docker搭建Prometheus

docker-compose.yml

prometheus:
  image: prom/prometheus
  volumes:
	- ./prometheus.yml:/etc/prometheus/prometheus.yml
  ports:
	- "9090:9090"
  command: -config.file=/etc/prometheus/prometheus.yml
  • 配置文件在:/etc/prometheus/prometheus.yml
  • Web Interface启动在9090端口
Prometheus的配置
scrape_configs:
  # Scrape Prometheus itself every 5 seconds.
  - job_name: 'prometheus'
	scrape_interval: 5s
    static_configs:
	  - targets: ['localhost:9090']
  • 把Prometheus自身作为一个target,每5秒获取一次数据
  • Prometheus Server安装了client_golang,通过 /matrics 提供监控数据
服务级别监控矩阵
  • 打开http://localhost:9090/graph
  • 可以看到prometheus服务自身的监控矩阵

系统级别监控

docker-compose.yml

node_exporter:
  image: prom/node-exporter
  ports:
	- "9100:9100"
  • 在服务器上安装node-exporter,服务启动在9100端口
  • 通过 /matrics提供监控数据
Prometheus的配置
  # Scrape the Node Exporter every 5 seconds.
  - job_name: 'node'
    scrape_interval: 5s
	static_configs:
      - targets: ['node_exporter:9100']
  • 这个节点命名为 node
  • node_exporter作为一个target,每5秒获取一次数据
系统级别监控矩阵
  • 打开http://localhost:9090/graph
  • 可以看到node-exporter的监控矩阵

Spring Boot服务监控
  • 启动一个Event Service

mongo:
	image: mongo
  event-service:
	build: .
	command: java -jar /app/event-service-latest.jar --		spring.data.mongodb.host="mongo"
	ports:
	  - "8080:8080"
	depends_on:
      - mongo
	  - pushgateway
  • 在Event Service的build.gradle中配置prometheus的依赖

compile('io.prometheus:simpleclient:0.0.16')
compile('io.prometheus:simpleclient_common:0.0.16')
compile('io.prometheus:simpleclient_hotspot:0.0.16')    
compile('io.prometheus:simpleclient_spring_boot:0.0.16')
compile('io.prometheus:simpleclient_servlet:0.0.16')
compile('io.prometheus:client:0.0.10')
  • 添加Metrics的Configuration

@Configuration
public class MetricsConfiguration {

@Bean
public ServletRegistrationBean servletRegistrationBean() {
    DefaultExports.initialize();
	return new ServletRegistrationBean(new MetricsServlet(), "/prometheus");
}

@Bean
public SpringBootMetricsCollector 				springBootMetricsCollector(Collection<PublicMetrics> publicMetrics) {
    SpringBootMetricsCollector springBootMetricsCollector = 
    new SpringBootMetricsCollector(publicMetrics);
	springBootMetricsCollector.register();
    return springBootMetricsCollector;
	}
}
  • 在prometheus的配置文件中添加一个target
  • 设置metrics_path

#Scrape the event-service every 5 seconds.
  - job_name: 'event-service'
	scrape_interval: 5s
	static_configs:
	  - targets: ['event-service:8080']
    metrics_path: /prometheus
  • 打开http://localhost:9090/graph

  • 可以看到event-service的监控矩阵

push-gateway

docker-compose.yml

pushgateway:
  image: prom/pushgateway
  ports:
	- "9091:9091"
  • pushgateway的服务启动在9091端口
push-gateway的配置

/etc/prometheus/prometheus.yml

  - job_name: 'pushgateway'
	scrape_interval: 5s
    static_configs:
	  - targets: ['pushgateway:9091'] * 给Prometheus配置pushgateway作为target * pushgateway服务启动在9091端口
服务中的PUSH-GateWay配置
  • 不同语言的client都提供了PushGateway的API
  • 在build.gradle中引入 io.prometheus:simpleclient_pushgateway
  • 在服务中注册自定义的监控

@SpringBootApplication
public class Application {
static final CollectorRegistry pushRegistry = new CollectorRegistry();
static final Gauge gauge = (Gauge) 		Gauge.build().name("SpringBootPushMetric").help("test").register(pushRegistry);

public static void main(String[] args) throws IOException {
	SpringApplication.run(Application.class, args);
    PushGateway pg = new PushGateway("pushgateway:9091");
    gauge.set(42);
	pg.push(pushRegistry, "PushGatewayJob");
	}
}
push-gateway监控数据
  • 打开http://localhost:9090/graph
  • 可以看到event-service通过pushgateway发送的监控数据

Targets
  • 打开 http://localhost:9090/targets,查看所有targets

完整的工程

$ git clone https://git.coding.net/microservice_ops/training-all-in-one.git
$ cd training-all-in-one/monitoring/prometheus
$ ./gradlew build
$ docker-compose up

OneAlert告警

AlertManager

Alert Manager独立于Prometheus,在Prometheus Server中设置报警规则,Prometheus会把告警内容发送给 Alert Manager。然后 Alert Manager负责管理这些告警,包括聚合、抑制、静默等操作,通过email、pageduty、hipchat等方式发送通知。

OneAlert

OneAlert是一个基于SaaS模式的云告警平台,集成国内外主流监控/支撑系统,更可用更灵活的 Email 和 Rest API 的方式接入自定义告警消息,通过短信、电话、微信等方式,发送通知。实现了一个平台处理所有IT告警与事件。

OneAlert集成Prometheus告警解决方案

OneAlert微信通知