聊聊dubbo-go的PrometheusReporter
时间:2022-07-22
本文章向大家介绍聊聊dubbo-go的PrometheusReporter,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
序
本文主要研究一下dubbo-go的PrometheusReporter
PrometheusReporter
dubbo-go-v1.4.2/metrics/prometheus/reporter.go
const (
reporterName = "prometheus"
serviceKey = constant.SERVICE_KEY
groupKey = constant.GROUP_KEY
versionKey = constant.VERSION_KEY
methodKey = constant.METHOD_KEY
timeoutKey = constant.TIMEOUT_KEY
providerKey = "provider"
consumerKey = "consumer"
// to identify the metric's type
histogramSuffix = "_histogram"
// to identify the metric's type
summarySuffix = "_summary"
)
var (
labelNames = []string{serviceKey, groupKey, versionKey, methodKey, timeoutKey}
namespace = config.GetApplicationConfig().Name
reporterInstance *PrometheusReporter
reporterInitOnce sync.Once
)
// should initialize after loading configuration
func init() {
extension.SetMetricReporter(reporterName, newPrometheusReporter)
}
// PrometheusReporter
// it will collect the data for Prometheus
// if you want to use this, you should initialize your prometheus.
// https://prometheus.io/docs/guides/go-application/
type PrometheusReporter struct {
// report the consumer-side's summary data
consumerSummaryVec *prometheus.SummaryVec
// report the provider-side's summary data
providerSummaryVec *prometheus.SummaryVec
// report the provider-side's histogram data
providerHistogramVec *prometheus.HistogramVec
// report the consumer-side's histogram data
consumerHistogramVec *prometheus.HistogramVec
}
- PrometheusReporter定义了consumerSummaryVec、providerSummaryVec、providerHistogramVec、consumerHistogramVec
newPrometheusReporter
dubbo-go-v1.4.2/metrics/prometheus/reporter.go
// newPrometheusReporter create new prometheusReporter
// it will register the metrics into prometheus
func newPrometheusReporter() metrics.Reporter {
if reporterInstance == nil {
reporterInitOnce.Do(func() {
reporterInstance = &PrometheusReporter{
consumerSummaryVec: newSummaryVec(consumerKey),
providerSummaryVec: newSummaryVec(providerKey),
consumerHistogramVec: newHistogramVec(consumerKey),
providerHistogramVec: newHistogramVec(providerKey),
}
prometheus.MustRegister(reporterInstance.consumerSummaryVec, reporterInstance.providerSummaryVec,
reporterInstance.consumerHistogramVec, reporterInstance.providerHistogramVec)
})
}
return reporterInstance
}
- newPrometheusReporter方法实例化PrometheusReporter
newSummaryVec
dubbo-go-v1.4.2/metrics/prometheus/reporter.go
// newSummaryVec create SummaryVec, the Namespace is dubbo
// the objectives is from my experience.
func newSummaryVec(side string) *prometheus.SummaryVec {
return prometheus.NewSummaryVec(
prometheus.SummaryOpts{
Namespace: namespace,
Help: "This is the dubbo's summary metrics",
Subsystem: side,
Name: serviceKey + summarySuffix,
Objectives: map[float64]float64{
0.5: 0.01,
0.75: 0.01,
0.90: 0.005,
0.98: 0.002,
0.99: 0.001,
0.999: 0.0001,
},
},
labelNames,
)
}
- newSummaryVec方法执行prometheus.NewSummaryVec,其中SummaryOpts设置了0.5、0.75、0.90、0.98、0.99、0.999的Objectives
newHistogramVec
dubbo-go-v1.4.2/metrics/prometheus/reporter.go
func newHistogramVec(side string) *prometheus.HistogramVec {
mc := config.GetMetricConfig()
return prometheus.NewHistogramVec(
prometheus.HistogramOpts{
Namespace: namespace,
Subsystem: side,
Name: serviceKey + histogramSuffix,
Help: "This is the dubbo's histogram metrics",
Buckets: mc.GetHistogramBucket(),
},
labelNames)
}
- newHistogramVec方法执行prometheus.NewHistogramVec
Report
dubbo-go-v1.4.2/metrics/prometheus/reporter.go
// Report report the duration to Prometheus
// the role in url must be consumer or provider
// or it will be ignored
func (reporter *PrometheusReporter) Report(ctx context.Context, invoker protocol.Invoker, invocation protocol.Invocation, cost time.Duration, res protocol.Result) {
url := invoker.GetUrl()
var sumVec *prometheus.SummaryVec
var hisVec *prometheus.HistogramVec
if isProvider(url) {
sumVec = reporter.providerSummaryVec
hisVec = reporter.providerHistogramVec
} else if isConsumer(url) {
sumVec = reporter.consumerSummaryVec
hisVec = reporter.consumerHistogramVec
} else {
logger.Warnf("The url is not the consumer's or provider's, "+
"so the invocation will be ignored. url: %s", url.String())
return
}
labels := prometheus.Labels{
serviceKey: url.Service(),
groupKey: url.GetParam(groupKey, ""),
versionKey: url.GetParam(versionKey, ""),
methodKey: invocation.MethodName(),
timeoutKey: url.GetParam(timeoutKey, ""),
}
costMs := float64(cost.Nanoseconds() / constant.MsToNanoRate)
sumVec.With(labels).Observe(costMs)
hisVec.With(labels).Observe(costMs)
}
// whether this url represents the application received the request as server
func isProvider(url common.URL) bool {
role := url.GetParam(constant.ROLE_KEY, "")
return strings.EqualFold(role, strconv.Itoa(common.PROVIDER))
}
// whether this url represents the application sent then request as client
func isConsumer(url common.URL) bool {
role := url.GetParam(constant.ROLE_KEY, "")
return strings.EqualFold(role, strconv.Itoa(common.CONSUMER))
}
- Report方法根据url来判断是provider还是consumer,若为provider则获取reporter.providerSummaryVec、reporter.providerHistogramVec;若为consumer则获取reporter.consumerSummaryVec、reporter.consumerHistogramVec;之后设置labels,然后执行sumVec.With(labels).Observe(costMs)及hisVec.With(labels).Observe(costMs)
小结
PrometheusReporter定义了consumerSummaryVec、providerSummaryVec、providerHistogramVec、consumerHistogramVec;Report方法根据url来判断是provider还是consumer,若为provider则获取reporter.providerSummaryVec、reporter.providerHistogramVec;若为consumer则获取reporter.consumerSummaryVec、reporter.consumerHistogramVec;之后设置labels,然后执行sumVec.With(labels).Observe(costMs)及hisVec.With(labels).Observe(costMs)
doc
- sysfs_create_group创建sysfs接口
- apache服务器配置
- Android i2c-tools移植
- 高通GPIO驱动(DTS方式)
- Dos烧录脚本
- 使用ServiceStack构建Web服务
- 《Redis设计与实现》读书笔记(二十三) ——Redis服务器初始化
- 警惕:Oracle中删除的分区不会进入回收站(Recyclebin)
- 《Redis设计与实现》读书笔记(二十五) ——Redis主从复制具体过程
- 基于input子系统的sensor驱动调试(一)
- 《Redis设计与实现》读书笔记(二十六) ——Redis哨兵(sentinel)启动与建立监听机制
- 《Redis设计与实现》读书笔记(二十七) ——Redis哨兵(sentinel)主服务器下线判断与故障转移
- 基于input子系统的sensor驱动调试(二)
- 编程语言中的闭包
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Android StartService()源码分析(一)
- JDK 8 新特性 之 default关键字
- 设计模式 之 单例模式
- SpringBoot 配置多数据源
- git pull 报错:The following untracked working tree files would be overwritten by merge
- Docker 使用Dockerfile构建Docker(三)
- Docker-compose 安装与基本使用(四)
- Docker-compose 常用命令及网络设置(五)
- HashMap 源码分析
- Java 按位运算符(&,|,^,>>,<<,>>>)
- LinkedList 源码分析
- Logstash:多个配置文件(conf)
- ArrayList 源码分析
- IllegalArgumentException:argument type mismatch
- String equals()方法 源码分析