GORM数据库连接池对接Prometheus

一、背景与介绍

        Golang的database/sql包定了关于操作数据库的相关接口,但是没有去做对应数据库的实现。这些实现是预留给开发者或者对应厂商进行实现的。

        其中让我比较关注的是Golang的sql包有没有实现连接池pool的机制呢?  毕竟Golang是静态语言,类似Java我们看到很多连接池的实现例如阿里巴巴的Apache druid。给开发者提供了一个高效的数据库连接池,提高应用的性能,连接池保持与后端数据库的长连接,在需要的时候直接使用即可。使用完毕后,将连接归还到连接池中。  并且还提供可视化界面,查看连接池的运行情况、连接数情况、活跃数、空闲数等等。

        我们通过源码可以发现,Golang底层的sql包是实现了数据库连接池的逻辑。但是Golang的连接池,都是隐式/惰性使用,只有在执行到查询SQL或者执行SQL的时候,才从pool中拿到连接进行执行, 不会像Java一样显式使用,需要从pool中拿到连接对象,再通过这个连接对象执行SQL.

二、GORM配置prometheus

1、对接Prometheus的目的

        GORM支持配置Promtehues的export, 这样我们再结合Grafana面板就能很直观地对Go程序的SQL连接池进行监控。

        可以监控到当前连接池的连接数有没有超过最大连接数、空闲连接数等等,由此来保证我们程序的正常运行。

        一般我们的Go项目都使用到GROM, 既然GORM实现了Prometheus的export,那么就使用内置功能进行测试。 其实我们也可以自己实现这个exporter, 通过DB对象的Stats()方法,返回连接池统计数据,再封装为exporter接口暴露出来即可。     

2、开启Promtheus exporter

db.go测试代码:

package dbimport ("gorm.io/driver/mysql""gorm.io/gorm""gorm.io/gorm/logger""gorm.io/plugin/prometheus""log""os""sync""time"
)var db *gorm.DB
var once sync.Once
var getDbConnErr error
var dsn = "root:root@tcp(127.0.0.1:3307)/test?charset=utf8mb4&parseTime=True&loc=Local"// GetDbConn 获取mysql连接
func GetDbConn() *gorm.DB {once.Do(func() {logfile, _ := os.OpenFile("./sql.log", os.O_CREATE|os.O_APPEND|os.O_RDWR, 0666)newLogger := logger.New(log.New(logfile, "\r\n", log.LstdFlags), logger.Config{SlowThreshold: time.Second,LogLevel:      logger.Info,})db, getDbConnErr = gorm.Open(mysql.Open(dsn), &gorm.Config{Logger: newLogger,})if getDbConnErr != nil {panic(getDbConnErr)}db.Use(prometheus.New(prometheus.Config{DBName:          "db1",                       // 使用 `DBName` 作为指标 labelRefreshInterval: 15,                          // 指标刷新频率(默认为 15 秒)PushAddr:        "prometheus pusher address", // 如果配置了 `PushAddr`,则推送指标StartServer:     true,                        // 启用一个 http 服务来暴露指标HTTPServerPort:  8080,                        // 配置 http 服务监听端口,默认端口为 8080 (如果您配置了多个,只有第一个 `HTTPServerPort` 会被使用)MetricsCollector: []prometheus.MetricsCollector{&prometheus.MySQL{Prefix:        "gorm_mysql_stats_",Interval:      15,VariableNames: []string{"Threads_running"},},}, // 用户自定义指标}))DB, _ := db.DB()// 最大连接数DB.SetMaxOpenConns(2)// 最大空闲连接数 <= 最大连接数DB.SetMaxIdleConns(1)// 连接数的生命周期, 从创建开始记时,到时间点会被销毁DB.SetConnMaxLifetime(time.Hour * 7)// 最大空闲时间, 这个链接距离上一次被使用的时间段,超过这个时间则认为该连接已过期DB.SetConnMaxIdleTime(time.Hour)})return db
}

 main.go测试代码:

package mainimport (db "awesomeProject1/db""fmt"_ "gorm.io/driver/mysql""gorm.io/gorm""math/rand""time"
)func main() {dbConn := db.GetDbConn()for i := 0; i < 10; i++ {go func(conn *gorm.DB) {for {time.Sleep(time.Second * time.Duration(rand.Intn(10)))rows := dbConn.Raw("select * from users")var res []map[string]interface{}fmt.Println(rows.Scan(&res))}}(dbConn)}for {time.Sleep(time.Second * 2)fmt.Println("running....")}
}

 访问http://localhost:8080/metrics 查看到指标数据:

3、采集metrics到Promtehus

promethues.yaml配置添加采集任务: 

4、Grafana配置监控面板

1、通过图表能看到,我们配置了连接池最大连接数是2个, 但是有10个协程去执行查询SQL,观察wait_count指标曲线在持续上涨, 此时有26个协程还在阻塞等待获取数据库连接,同时查看右边是等待获取数据库连接等待耗时曲线,也是一直在上涨,此时我们应该判定数据库连接池满了。那么例如生产环境,看到这种曲线要么我们设置的连接池最大连接数过小,要么mysql的连接数已经跑满了。 此时应该告警,查看异常的情况。

2、我们将最大连接数调整为20以后再观察监控面板:

   最大连接数已从2调整为20(2->20), 此时再看监控面板, 等待的协程数量wait_count:0、同时协程等待获取数据库连接的时间已经降为了0ns, 此时数据库连接池不再是爆满的状态。

三、总结

        无论Golang的什么ORM框架,GORM也好、XORM也罢, 底层还是去使用了database/sql这个包,这个包底层实现了连接池的抽象,同时提供了获取连接池相关统计信息的接口。 我们再结合Prometheus将这些指标暴露出来,结合Grafana这套告警体系,就可以实时监控和观察我们Go程序MySQL连接池的情况。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/322772.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何理解vlanif接口无法up的原因?直连不通(PVID问题)?如何排查?

目录 案列一&#xff1a;如何理解vlanif接口无法up的原因&#xff1f; 案例二&#xff1a;vlan接口正常up&#xff0c;同网段&#xff0c;无法ping通&#xff1f;&#xff08;PVID&#xff09; 原因一&#xff1a;pvid&#xff08;native vlan&#xff09;两端不一致——帧的…

Baidu Comate:智能编码,编程效率的革新者

文章目录 一、何为智能编码助手&#xff1f;二、Baidu Comate智能编码助手简介三、Baidu Comate注册四、Baidu Comate体验Comate插件功能1.注释生成代码2.函数注释生成3.行间注释生成4.生成代码解释5. 调优建议 五、插件功能的使用体验感受和建议 &#x1f6a9;结语 一、何为智…

文件快递柜-免费开源-FileCodeBox

像拿快递一样取文件 什么FileCodeBox FileCodeBox 中文名是 文件快递柜&#xff0c;取文件像取快递一样&#xff0c;支持通过匿名口令分享文本&#xff0c;文件。 很多时候&#xff0c;我们都想将一些文件或文本传送给别人&#xff0c;或者跨端传递一些信息&#xff0c;但是我…

QT+网络调试助手+TCP客户端

一、网络调试助手UI界面 编程主要思路&#xff1a; 首先将水平的控件 水平布局 &#xff0c;然后相对垂直的控件 垂直布局 &#xff0c;哪怕是底下的groupBox也需要和里面的内容 水平布局&#xff0c;然后最后框选全部 栅格布局。如果需要界面自适应窗口大小&#xff0c…

品牌舆情监测工作要怎么做?

一个负面舆论的传播&#xff0c;可能在短时间内对企业品牌形象造成巨大损害&#xff0c;甚至引发舆情危机。因此&#xff0c;如何有效地进行品牌舆情监测&#xff0c;成为企业不可忽视的问题。伯乐网络传媒多年网络公关、舆情监测经验&#xff0c;今天就来给大家分享一下。 一、…

探索全新商业模式:循环购的奥秘

你是否曾经遇到过这样的疑问&#xff1a;为何有的商家会推出“消费1000送2000”的优惠活动&#xff1f;每天还有钱可以领取&#xff0c;甚至还能提现&#xff1f;这背后究竟隐藏着怎样的商业逻辑&#xff1f;今天&#xff0c;作为你们的私域电商顾问&#xff0c;我将带大家深入…

Android 高版本实现沉浸式状态栏

目前实现的android高版本沉浸式状态栏分为两类&#xff1a; 1、是纯透明状态栏&#xff1b; 2、是纯透明状态栏&#xff0c;但是状态栏字体是黑色&#xff1b; 将状态栏的代码封装到BaseActivity中更方便使用&#xff1a; BaseActivity: public abstract class BaseActivit…

腾讯游戏海外扩张,增持芬兰游戏开发商股份持股比例增至14.8%

易采游戏网5月8日消息&#xff0c;近日腾讯再次出手&#xff0c;大幅增持了芬兰知名游戏开发商Remedy Entertainment的股份&#xff0c;持股比例猛增至14.8%。这一举动引起了业界和投资者的广泛关注。 据了解&#xff0c;腾讯此次增持是在2024年4月24日完成的。根据芬兰法律规…

Web实操(6),基础知识学习(24~)

1.[ZJCTF 2019]NiZhuanSiWei1 &#xff08;1&#xff09;进入环境后看到一篇php代码&#xff0c;开始我简单的以为是一题常规的php伪协议&#xff0c;多次试错后发现它并没有那么简单&#xff0c;它包含了基础的文件包含&#xff0c;伪协议还有反序列化 &#xff08;2&#x…

ES与关系数据库的同步练习(hotel_admin)

目录 1 es与数据库同步的方法2 实践2.1 任务介绍2.2 MQ方面操作2.2.1 声明交换机队列并且绑定2.2.2 hotel_admin端web层设置mq发送消息2.3 hotel_demo端监听接受消息并执行es操作 1 es与数据库同步的方法 方式一&#xff1a;同步调用 优点&#xff1a;实现简单&#xff0c;粗…

Python爬虫基础知识学习(以爬取某二手房数据、某博数据与某红薯(书)评论数据为例)

一、爬虫基础流程 爬虫的过程模块化&#xff0c;基本上可以归纳为以下几个步骤&#xff1a; 1、分析网页URL&#xff1a;打开你想要爬取数据的网站&#xff0c;然后寻找真实的页面数据URL地址&#xff1b; 2、请求网页数据&#xff1a;模拟请求网页数据&#xff0c;这里我们介…

Qt QImageReader类介绍

1.简介 QImageReader 是用于读取图像文件的类。它提供了读取不同图像格式的功能&#xff0c;包括但不限于 PNG、JPEG、BMP 等。QImageReader 可以用于文件&#xff0c;也可以用于任何 QIODevice&#xff0c;如 QByteArray &#xff0c;这使得它非常灵活。 QImageReader 是一个…

不走寻常路!酷开科技不断升级酷开系统满足消费者日益增长的需求

在科技日新月异的今天&#xff0c;人们对生活品质的要求越来越高。为此&#xff0c;酷开科技不断升级酷开系统&#xff0c;以满足消费者日益增长的需求。为了让消费者体验更好的服务&#xff0c;在酷开系统中设立了酷开会员&#xff0c;满足消费者的更多需求。丰富的特权和定制…

mysql其它补充

exist和in的区别 exists 用于对外表记录做筛选。 exists 会遍历外表&#xff0c;将外查询表的每一行&#xff0c;代入内查询进行判断。 当 exists 里的条件语句能够返回记录行时&#xff0c;条件就为真&#xff0c;返回外表当前记录。反之如果 exists 里的条件语句不能返回记…

46. UE5 RPG 增加角色受击反馈

在前面的文章中&#xff0c;我们实现了对敌人的属性的初始化&#xff0c;现在敌人也拥有的自己的属性值&#xff0c;技能击中敌人后&#xff0c;也能够实现血量的减少。 现在还需要的就是在技能击中敌人后&#xff0c;需要敌人进行一些击中反馈&#xff0c;比如敌人被技能击中后…

ASP.NET 两种开发模式

1》》WebForm 开发模式 1. 服务器端控件 2. 一般处理程序html静态页Ajax 3. 一般处理程序html模板 如下图 2》》MVC 太复杂的系统&#xff0c;会造成Controller 过复杂。 后来就诞生了 MVP、MVVM等模式

基于php+mysql+html图书管理系统(含实训报告)

博主介绍&#xff1a; 大家好&#xff0c;本人精通Java、Python、Php、C#、C、C编程语言&#xff0c;同时也熟练掌握微信小程序、Android等技术&#xff0c;能够为大家提供全方位的技术支持和交流。 我有丰富的成品Java、Python、C#毕设项目经验&#xff0c;能够为学生提供各类…

linux数据备份与恢复

目录 前言 1、数据备份和恢复中的两个关键性指标 2、linux系统的定时任务 1&#xff09;本地定时任务crontab 在实验测试过程中&#xff0c;遇到多次crontab任务不执行问题 &#xff0c;总结下来主要有几个方面原因&#xff1a; 2)分布式定时任务系统Jenkins 3、备份存储…

【报错处理】ib_write_bw执行遇到Found Incompatibility issue with GID types.原因与解决办法

文章目录 拓扑现象根因解决办法解决后效果 拓扑 #mermaid-svg-zheSkw17IeCpjnVA {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-zheSkw17IeCpjnVA .error-icon{fill:#552222;}#mermaid-svg-zheSkw17IeCpjnVA .error…

企业邮箱系统搭建的流程方案

随着互联网、5G、物联网等新技术的发展&#xff0c;数字化办公已经成为现代企业工作方式的重要组成部分。作为数字化办公的重要组成部分之一&#xff0c;企业邮箱在日常办公中已经得到了广泛的应用。但是传统的租用企业邮箱已经不能满足企业对于数据的安全性、收发的稳定性、系…