整体架构
安装prometheus
mac安装方式
1.下载安装包
https://prometheus.io/download/
2.解压运行
解压后,运行./prometheus --config.file=prometheus.yml
这里mac系统可能会碰到无法打开的问题,按照如下操作之后,再次运行命令
a.点击屏幕左上角的苹果图标,选择菜单:系统偏好设置...。
b.打开系统偏好设置界面,点击"安全性与隐私"->"通用"。
c.在窗口底部会看到:已阻止使用“XXX”,因为来自身份不明的开发者。点击后面的"仍要打开"按钮
3.访问
浏览器地址输入:http://localhost:9090/,即可访问
使用prometheus监控go应用
默认监控项
在go项目中引入prometheus之后,默认已经有监控项了,我们可以在prometheus的监控面板中看到,比如下面的例子
1)编写一个最简go应用
package main import ( "net/http" "github.com/prometheus/client_golang/prometheus/promhttp" ) func main() { http.Handle("/metrics", promhttp.Handler()) //暴露 metrics 指标 http.ListenAndServe(":8091", nil) //启动Server }
2)查看默认指标
2.1. 运行上面的go程序
go run main.go
2.2 浏览器访问http://localhost:8091/metrics 然后查看默认指标输出
这里我们关注promhttp_metric_handler_requests_total指标,表示http访问量,每次刷新这个指标会+1。
3)将go应用节点添加到prometheus的prometheus.yml配置
追加配置到prometheus.yml中
# 这里新增一个监控Go应用节点 - job_name: "gomonitor" # metrics_path defaults to '/metrics' # scheme defaults to 'http'. static_configs: - targets: ["localhost:8091"]
4)重启promethueus
./prometheus --config.file=prometheus.yml
5)查看prometheus监控面板
点击Execute可以看到监控面板的http访问趋势
prometheus术语解释
指标名称(metric name)
表示了被测系统的一般特征,即一个可以度量的指标
它采用了普遍的名称来描述一个时间序列,例如
1)promhttp_metric_handler_requests_total 表示请求总数
2)go_goroutines go运行的协程数量
标签(label)
当指标名称需要细化的时候,可以使用标签进行扩展,相同指标名称的任何给定标签组合标识该指标的特定维度实例
例如:
1)promhttp_metric_handler_requests_total{method=POST} 表示有POST标签的请求总数
2)promhttp_metric_handler_requests_total{status=200} 表示有状态码为200标签的请求总数
样本(sample)
按照某个时序以时间维度采集的数据称为样本,实际的时间序列,每个序列包括一个float64的值和一个毫秒级的unix时间戳,本质上属于单值模型,例如:
1)在某个采集的时刻,指标输出为"promhttp_metric_handler_requests_total{code="200"} 126" 表示这一刻的样本值为126
整个prometheus的数据存储可以用下面的模型来表示
1)其中横轴是时间,纵轴是时间线,时间线就是指标名称和一组标签的组合
2)区域内每个点就是数据点
3)在同一时刻,每条时间线只会产生一个数据点,但同时会有多条时间线产生数据
自定义监控项
很多情况下prometheus提供的go sdk并不能很好的满足我们业务上的应用,所以我们还有自定义监控指标的需求。
prometheus提供了四大度量指标
Counter (计数器)
描述
常用方法
方法名 | 作用 |
---|---|
Inc | 将计数器递增1 |
Add (float64) | 将给定添加计数器中,小于0报错 |
应用例子
package main import ( "net/http" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promhttp" ) func main() { //申明一个Counter var AccessCounter = prometheus.NewCounterVec( prometheus.CounterOpts{ Name: "http_server_requests_bucket", }, []string{"path"}, ) //将申明的Counter注册 prometheus.MustRegister(AccessCounter) //这里是业务逻辑,假设有一个获取用户信息接口 http.HandleFunc("/getUser", func(w http.ResponseWriter, r *http.Request) { //这里针对接口访问量进行递增,这里简单起见,写死了path AccessCounter.With(prometheus.Labels{ "path": "getUser", }).Add(1) }) http.Handle("/metrics", promhttp.Handler()) //暴露 metrics 指标 http.ListenAndServe(":8091", nil) //启动Server }
启动之后,先访问接口使得指标递增
http://localhost:8091/getUser
然后再访问prometheus监控界面,这条曲线永远是递增的
Gauge (仪表盘)
描述
常用方法
方法名 | 作用 |
---|---|
Set(float64) | 将仪表设置为任意值 |
Inc() | 将仪表增加 1 |
Dec() | 将仪表减少 1 |
Add(float64) | 将给定值添加到仪表,该值如果为负数,那么将导致仪表值减少 |
Sub(float64) | 从仪表中减去给定值,该值如果为负数,那么将导致仪表值增加 |
SetToCurrentTime() | 将仪表设置为当前Unix时间(以秒为单位) |
应用例子
package main import ( "fmt" "time" "net/http" "math/rand" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promhttp" ) func main() { //申明一个Counter var QueueGauge = prometheus.NewGaugeVec( prometheus.GaugeOpts{ Name: "queue_num_total", }, []string{"name"}, ) //将申明的Counter注册 prometheus.MustRegister(QueueGauge) //这里是业务逻辑,设置队列长度的接口 http.HandleFunc("/queueNum", func(w http.ResponseWriter, r *http.Request) { rand.Seed(time.Now().UnixNano()) num := rand.Intn(81)//这里模拟队列长度 QueueGauge.With(prometheus.Labels{ "name":"queue_order", }).Set(float64(num)) fmt.Println(num) }) http.Handle("/metrics", promhttp.Handler()) //暴露 metrics 指标 http.ListenAndServe(":8091", nil) //启动Server }
启动之后,先访问接口使得指标随机
http://localhost:8091/queueNum
然后再访问prometheus监控界面,这条曲线永远是有增有减的
Histogram(累积直方图)
描述
Histogram 类型将会在一段时间范围内对数据进行采样(通常是请求持续时间或响应大小等等),并将其计入可配置的存储桶(bucket)中,后续可通过指定区间筛选样本,也可以统计样本总数。
数据模型
1)这里的bucket是设置的上下限,比如落在区间[0.1-0.2]的样本数量,但是这里有一个区别,后一个区间会累加上前一个区间
2)统计分位数的时候,其实是拟合的区间进行统计的,如果bucket区间设置合理,这个值具备参考性,否责误差很大
常用方法
方法名 | 作用 |
---|---|
Observe(float64) | 将一个观察值添加到直方图。 |
应用例子
package main import ( "fmt" "time" "net/http" "math/rand" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promhttp" ) func main() { //申明 var HttpHistogram = prometheus.NewHistogramVec( prometheus.HistogramOpts{ Name: "http_durations_histogram_seconds", Buckets: []float64{0.2, 0.5, 1, 2, 5, 10, 30}, }, []string{"path"}, ) //将申明的注册 prometheus.MustRegister(HttpHistogram) //这里是业务逻辑,设置队列长度的接口 http.HandleFunc("/queueNum", func(w http.ResponseWriter, r *http.Request) { rand.Seed(time.Now().UnixNano()) num := rand.Intn(30) HttpHistogram.With(prometheus.Labels{ "path": "/user/info", }).Observe(float64(num)) fmt.Println(num) }) http.Handle("/metrics", promhttp.Handler()) //暴露 metrics 指标 http.ListenAndServe(":8091", nil) //启动Server }
启动之后,先访问接口使得指标随机
http://localhost:8091/queueNum
Summary(摘要)
描述
常用方法
方法名 | 作用 |
---|---|
Observe(float64) | 将一个观察值添加到直方图。 |
应用例子
package main import ( "fmt" "time" "net/http" "math/rand" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promhttp" ) func main() { //申明 var HttpDurations = prometheus.NewSummaryVec( prometheus.SummaryOpts{ Name: "http_durations_seconds", Objectives: map[float64]float64{0.5: 0.05, 0.9: 0.01, 0.99: 0.001}, }, []string{"path"}, ) //将申明的注册 prometheus.MustRegister(HttpDurations) //这里是业务逻辑,设置队列长度的接口 http.HandleFunc("/queueNum", func(w http.ResponseWriter, r *http.Request) { rand.Seed(time.Now().UnixNano()) num := rand.Intn(30) HttpDurations.With(prometheus.Labels{"path": "/user/phone"}).Observe(float64(num)) fmt.Println(num) }) http.Handle("/metrics", promhttp.Handler()) //暴露 metrics 指标 http.ListenAndServe(":8091", nil) //启动Server }
启动之后,先访问接口使得指标随机
http://localhost:8091/queueNum
写在最后
最后,一般公司架构都集成了prometheus,无需自己单独搭建这一套,包括监控MySQL,Redis社区内也有非常好的解决方案。作为业务开发,将花费精力放在通用prometheus指标没有覆盖的地方,然后建立业务专属的监控指标
No Leanote account? Sign up now.