grafana加载缓慢解决方案

news2024/9/29 10:11:12

背景

目前随着数据和图表的逐渐增多,Grafana 页面加载速度明显变慢,严重影响了用户体验,几次都有骂娘的冲动=.=,因此我们需要对 Grafana 进行优化,以提升加载性能。

对于速度优化,我们可以从以下方面进行入手:

  • 优化前端资源加载

    使用反向代理和压缩:通过 NGINX 或其他反向代理服务器启用 gzip 压缩和缓存静态资源,减少页面加载的时间。

    静态资源缓存:确保静态资源如 CSS、JS 等在浏览器中缓存,以避免每次加载都重新获取这些资源。

  • 优化grafana server端服务器资源

    增加服务器性能:检查服务器的 CPU、内存和 I/O 是否有瓶颈,适当增加服务器资源配置。

    调整 Grafana 服务器配置:增加 Grafana 的 concurrent_requests_limit 设置,允许更多的并发请求。

  • 数据库优化

    如果你使用的是 Grafana 自己的 sqliteMySQL/PostgreSQL,请确保这些数据库被适当优化,数据库性能问题也可能导致慢加载。

  • 分离数据源

    多实例 Prometheus:如果你使用的是 Prometheus 数据源,可以考虑使用多个 Prometheus 实例来分担负载,特别是如果你的查询数据量很大。

  • 优化数据源查询

    减少查询时间范围:设置默认时间范围为较短的时间段(如过去 5 分钟或 15 分钟),以减少加载时的数据量。

    使用高效的数据源:检查你的数据源(如 Prometheus 或 Elasticsearch)是否有性能瓶颈。数据源的响应速度慢会直接影响 Grafana 的加载速度。

    优化查询:确保你的查询尽可能高效,避免不必要的复杂计算或过滤条件。使用 rate()avg_over_time() 等函数优化大数据量的查询。

  • 检查网络延迟

这些方案从易到难顺序如下: 检查网络延迟 < 优化数据源查询 < 优化grafana server端服务器资源 < 分离数据源 < 优化前端资源加载 < 数据库优化

目前我遇到的问题是网络没有延迟,数据源采集到的数据量不大,使用了多个prometheus实例,而且grafana server端内存使用率不到 30% ,所以只剩两个选择了,一个是前端资源优化,一个是数据库优化

数据库优化涉及到一个备份迁移的过程,感觉相对来说复杂点,所以尝试了一下优化grafana前端资源

本篇文章主要涉及的是 优化grafana前端资源

实践

下面内容是基于docker的方式进行演示

缓存哪部分内容

grafana静态文件的目录是在/usr/share/grafana/public

在这里插入图片描述

我们需要将这部分内容放到缓存中或者CDN或者OSS中

由于CDN和OSS都需要花钱,我们暂时就用nginx来做一个类似缓存的功能

注意事项:

这里我建议直接在正在运行的grafana容器中把这个public包下载下来(想办法下载,比如压缩后下载,docker cp也行),因为grafana运行了很长时间,里面或多或少会新增一些js文件,而这些文件,是在官方纯净版public是没有的

官方纯净版:Download Grafana | Grafana Labs 选择对应的版本,下载window版本,解压后里面有public文件

nginx操作

部署一个nginx,将public静态文件夹放到nginx下面

default.conf如下:

server {
    listen       80;
    listen  [::]:80;
    server_name  xx.xx.xx;
    
    location /grafana-oss/9.5.7/public/ {
        alias   /tmp/public/;
        
        # 跨域配置
        add_header 'Access-Control-Allow-Origin' '*';
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
        add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';
 
        autoindex on;
        autoindex_exact_size on;
        autoindex_localtime on;
    }
    error_page   500 502 503 504  /50x.html;
    
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
  }

内容解释

location 必须是/grafana-oss/你的grafana版本/public/,因为grafana后台请求时,这些是它源码里面携带的地址,你自己改不了

alias /tmp/public/ 这个路径是 下载下来的public 放在 nginx容器里面的某个位置(我这里是/tmp/public/),可以自定义,当然你也可以是用root,两者的区别:nginx 中location中root和alias的区别

配置完成后,执行下面命令,进行热加载(如果你选择重启容器,下面命令可以不执行)

nginx -t # nginx校验
nginx -s reload  # nginx热加载,不用启动容器

接下来验证一下:

访问地址:域名/grafana-oss/9.5.7/public

在这里插入图片描述

修改grafana配置文件

配置文件的位置一般在:/etc/grafana/grafana.ini

在[server]下增加以下内容 cdn_url = https://xxx 这个是刚刚nginx的地址(https://ip:port即可)

[analytics]
check_for_updates = true
[grafana_net]
url = https://xxx
[log]
mode = console
[paths]
data = /var/lib/grafana/
logs = /var/log/grafana
plugins = /var/lib/grafana/plugins
provisioning = /etc/grafana/provisioning
[server]
domain = xxxxx
root_url = https://xxxx
cdn_url = https://xxx
[auth.gitlab]
enabled = true
allow_sign_up = true
...
[database]
type=sqlite3
cache_mode = shared

注意,这里你的grafana地址是https的话,建议你nginx也是https,因为https跳转http的话会有点问题

配置完成之后,重启grafana容器即可

验证

此时打开grafana,如果发现地址是修改后的nginx地址,即修改成功

在这里插入图片描述

如果是404的话,有下面几个原因:

  • public没有相对应的文件;
  • nginx location有问题,或者alias有问题;
  • 跨域问题

拓展

修复sqlite3数据库

在替换完成之后,我在保存图表的过程报错,error saving dashboard failed to save dashboard

后台日志为:

logger=context userId=0 orgId=0 uname= t=2024-09-20T02:58:49.667754459Z level=info msg="Request Completed" method=GET path=/api/live/ws status=401 remote_addr=103.90.188.115 time_ms=11 duration=11.749188ms size=27 referer= handler=/api/live/ws
logger=context userId=1 orgId=1 uname=admin t=2024-09-20T02:58:49.893549608Z level=error msg="Failed to save dashboard" error="saving dashboard failed: database disk image is malformed" remote_addr=xxxxx traceID=
logger=context userId=1 orgId=1 uname=admin t=2024-09-20T02:58:49.893663102Z level=error msg="Request Completed" method=POST path=/api/dashboards/db/ status=500 remote_addr=xxx time_ms=101 duration=101.326151ms size=51 referer="https://grafana.ljdong.net/d/ea7794xxxxfrom=now-30m&orgId=1&to=now" handler=/api/dashboards/db

注意看,他有一个database disk image is malformed,这个代表是sqlite3文件数据库损坏了,所以保存不了

解决方案:

  • 修复sqlite数据库
  • 切换mysql或者其他数据库(更稳定)
  • 权限问题

修复sqlite数据库的方案:

https://www.sqlite.org/download.html 网站上下载 sqlite-tools 工具

解压上面的压缩包,并在命令行模式下进入该目录运行 sqlite3.exe

# 打开损坏的数据库文件
.open d:/grafana.db
# 进行检测
PRAGMA integrity_check;
# 设置导出文件为 tmp.sql
.output d:/tmp.sql
# 将 grafana.db 中的内容以 sql 方式导出到 tmp.sql
.dump 
# 创建 temp.db 数据库
.open d:/temp.db 
# 从 tmp.sql 中导入数据
.read d:/tmp.sql 
# 退出
.quit 


# temp即为修复好的数据库

还有一种方案是使用SQLite Expert Professional 工具提供的 repair 来修复 db 文件,这种方案我没试通,感兴趣的可以试试

在这里插入图片描述

k8s部署nginx脚本

方便测试

deployment.yaml

---
apiVersion: apps/v1
kind: Deployment
metadata:
  annotations: {}
  labels:
    app: nginx-grafana
  name: nginx-grafana
  namespace: tools
spec:
  progressDeadlineSeconds: 600
  replicas: 1
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      app: nginx-grafana
  strategy:
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 25%
    type: RollingUpdate
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: nginx-grafana
      namespace: tools
    spec:
      containers:
        - image: 'docker-cf.registry.cyou/nginx:1.22.0'
          imagePullPolicy: IfNotPresent
          name: nginx
          ports:
            - containerPort: 80
              protocol: TCP
          resources: {}
          terminationMessagePath: /dev/termination-log
          terminationMessagePolicy: File
          volumeMounts:
            - mountPath: /etc/nginx/conf.d/
              name: nginx-config
              readOnly: true
            - mountPath: /tmp
              name: storage
      dnsPolicy: ClusterFirst
      restartPolicy: Always
      schedulerName: default-scheduler
      securityContext: {}
      terminationGracePeriodSeconds: 30
      volumes:
        - configMap:
            defaultMode: 420
            name: grafana-nginx
          name: nginx-config
        - name: storage
          persistentVolumeClaim:
            claimName: pvc-grafana

---
apiVersion: v1
kind: Service
metadata:
  annotations: {}
  labels:
    app: nginx-grafana
  name: nginx-grafana
  namespace: tools
spec:
  internalTrafficPolicy: Cluster
  ipFamilies:
    - IPv4
  ipFamilyPolicy: SingleStack
  ports:
    - port: 80
      protocol: TCP
      targetPort: 80
  selector:
    app: nginx-grafana
  sessionAffinity: None
  type: ClusterIP

---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations: {}
  name: nginx-grafana
  namespace: tools
spec:
  ingressClassName: nginx
  rules:
    - host: xxxxxxx
      http:
        paths:
          - backend:
              service:
                name: nginx-grafana
                port:
                  number: 80
            path: /
            pathType: Prefix
  tls:
    - hosts:
        - xxxxx
      secretName: xxxxx

configmap.yaml

---
apiVersion: v1
data:
  default.conf: |
    server {
        listen       80;
        listen  [::]:80;
        server_name  xxxx;
    
        location /grafana-oss/9.5.7/public/ {
            alias   /tmp/public/;
    
            add_header 'Access-Control-Allow-Origin' '*';
            add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
            add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';
    
            autoindex on;
            autoindex_exact_size on;
            autoindex_localtime on;
        }
        error_page   500 502 503 504  /50x.html;
    
        location = /50x.html {
            root   /usr/share/nginx/html;
        }
      }
kind: ConfigMap
metadata:
  name: grafana-nginx
  namespace: tools

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

小程序-使用npm包

小程序对 npm 的支持与限制 目前&#xff0c;小程序中已经支持使用 npm 安装第三方包&#xff0c;从而来提高小程序的开发效率。但是&#xff0c;在小程序中使用 npm 包有如下 3 个限制&#xff1a; 不支持依赖于 Node.js 内置库的包不支持依赖于浏览器内置对象的包不支持依赖…

2015年国赛高教杯数学建模B题互联网+时代的出租车资源配置解题全过程文档及程序

2015年国赛高教杯数学建模 B题 互联网时代的出租车资源配置 出租车是市民出行的重要交通工具之一&#xff0c;“打车难”是人们关注的一个社会热点问题。随着“互联网”时代的到来&#xff0c;有多家公司依托移动互联网建立了打车软件服务平台&#xff0c;实现了乘客与出租车司…

在VM虚拟机上进行磁盘扩容

将/dev/mapper/ol-root从100G扩容到105G 初始状态的/dev/mapper/ol-root分配了100G 在VM上新增一个5G的物理硬盘 创建PV并纳入VG 对原本的LV扩容 扩大文件系统 完成。

vue框架学习 -- 日历控件 FullCalendar 使用总结

最近在项目中要实现日期排班的功能&#xff0c;正好要用到日历视图的控件&#xff0c;经过对比发现&#xff0c;vue 中 使用 FullCalendar 可以实现相关需求&#xff0c;下面对使用过程做一个总结。 一. 引入 FullCalendar 控件 package.json 中添加相关依赖 "dependen…

无人机专业实操重要性凸显,组装、调试、改装技术详解

无人机专业的实操性在当今技术飞速发展的背景下显得尤为重要&#xff0c;这不仅体现在无人机的日常应用上&#xff0c;还贯穿于无人机的组装、调试及改装等关键环节中。以下是对这些技术环节的详细解析&#xff1a; 一、无人机组装技术 无人机的组装是无人机技术的基础&#x…

828华为云征文|使用sysbench对Flexus X实例对mysql进行性能测评

目录 一、Flexus X实例概述 1.1 Flexus X实例 1.2 在mysql方面的优势 二、在服务器上安装MySQL 2.1 在宝塔上安装docker 2.2 使用宝塔安装mysql 2.3 准备测试数据库和数据库表 三、安装sysbench并进行性能测试 3.1 使用yum命令sysbench 3.2 运行 sysbench 并进行性能测…

Jumpserver堡垒机应用部署案例

本案例主要讲述了如何安装Jumpserver堡垒机应用&#xff0c;以及使用Jumpserver堡垒机对接OpenStack平台进行管理 一、OpenStack平台对接堡垒机 案例准备 1.规划节点 IP 主机名 节点 192.168.20.21 controller OpenStack Controller节点 192.168.20.22 jumpserver O…

0基础跟德姆(dom)一起学AI 机器学习02-KNN算法

【理解】KNN算法思想 K-近邻算法&#xff08;K Nearest Neighbor&#xff0c;简称KNN&#xff09;。比如&#xff1a;根据你的“邻居”来推断出你的类别 KNN算法思想&#xff1a;如果一个样本在特征空间中的 k 个最相似的样本中的大多数属于某一个类别&#xff0c;则该样本也属…

从事人工智能学习Python还是学习C++?

人工智能&#xff08;Artificial Intelligence&#xff0c;简称AI&#xff09;是当今科技领域最热门的研究方向之一。AI 涉及多个学科和技术&#xff0c;特别是机器学习、神经网络、深度学习等技术的应用。在AI的开发过程中&#xff0c;编程语言的选择对于开发效率和项目实现至…

戴尔电脑怎么开启vt虚拟化_戴尔电脑新旧机型开启vt虚拟化教程

最近使用戴尔电脑的小伙伴们问我&#xff0c;戴尔电脑怎么开启vt虚拟。大多数可以在Bios中开启vt虚拟化技术&#xff0c;当CPU支持VT-x虚拟化技术&#xff0c;有些电脑会自动开启VT-x虚拟化技术功能。而大部分的电脑则需要在Bios Setup界面中&#xff0c;手动进行设置&#xff…

C++ | Leetcode C++题解之第443题压缩字符串

题目&#xff1a; 题解&#xff1a; class Solution { public:int compress(vector<char>& chars) {int n chars.size();int write 0, left 0;for (int read 0; read < n; read) {if (read n - 1 || chars[read] ! chars[read 1]) {chars[write] chars[re…

QT九月28日

1.实现登录界面 头文件 #ifndef WIDGET_H #define WIDGET_H#include <QWidget>class Widget : public QWidget {Q_OBJECTpublic:Widget(QWidget *parent nullptr);~Widget(); }; #endif // WIDGET_H源文件 #include "widget.h" #include <QIcon> #in…

服务器分类极简理解

塔式服务器 塔式服务器外形类似于电脑主机机箱&#xff0c;它的特点有易于维护、灵活性高、噪音低、无需专门的机架 塔式服务器适用于中小型企业或办公室等环境 刀片服务器 刀片服务器是在标准高度的机架式机箱内可插装多个卡式的服务器单元&#xff0c;它的特点是高可用性、…

openEuler 下载rpm 包

有2种方式 1、使用dnf 下载软件包 2、或者开启缓存&#xff0c;安装自动获取rpm其他事项 3、dnf 安装数据库的机器&#xff0c;应屏蔽数据软件的更新 4、下载的rpm 莫名奇妙的不能安装1、dnf download 下载软件包 # resolve 解决依赖 ,destdir 指定下载路径 dnf download -…

文章解读与仿真程序复现思路——电网技术EI\CSCD\北大核心《基于变分模态分解和组合深度神经网络的综合能源系统多元负荷预测》

本专栏栏目提供文章与程序复现思路&#xff0c;具体已有的论文与论文源程序可翻阅本博主免费的专栏栏目《论文与完整程序》 论文与完整源程序_电网论文源程序的博客-CSDN博客https://blog.csdn.net/liang674027206/category_12531414.html 电网论文源程序-CSDN博客电网论文源…

「漏洞复现」九块九付费进群系统 wxselect SQL注入漏洞

0x01 免责声明 请勿利用文章内的相关技术从事非法测试&#xff0c;由于传播、利用此文所提供的信息而造成的任何直接或者间接的后果及损失&#xff0c;均由使用者本人负责&#xff0c;作者不为此承担任何责任。工具来自网络&#xff0c;安全性自测&#xff0c;如有侵权请联系删…

数据结构与算法笔记7:最小生成树-Prim和Kruskal算法

常用的最小生成树的算法主要有两种&#xff0c;一种是Prim算法&#xff0c;一种是Kruskal算法。题目链接&#xff1a;KamaCoder 53. 寻宝&#xff08;第七期模拟笔试&#xff09; 这里假设有V个节点&#xff0c;因为我们的节点的标号是1~V&#xff0c;这样我们直接使用标号作…

JSON的C实现(上)

JSON的C实现&#xff08;上&#xff09; JSON的C实现&#xff08;上&#xff09;前言JSON简介JSON的C实现思路小结 JSON的C实现&#xff08;上&#xff09; 前言 JSON是众多项目中较为常见的数据交换格式&#xff0c;为不同项目、系统间的信息交换提供了一个规范化标准。JSON…

1.7 软件缺陷管理

欢迎大家订阅【软件测试】 专栏&#xff0c;开启你的软件测试学习之旅&#xff01; 文章目录 前言1 缺陷介绍2 缺陷描述及提交3 缺陷跟踪流程4 案例分析 前言 在软件开发和测试过程中&#xff0c;缺陷&#xff08;通常称为“bug”&#xff09;是不可避免的。了解和有效管理这些…

[Unity Demo]从零开始制作空洞骑士Hollow Knight第十二集:制作完整地图和地图细节设置以及制作相机系统的跟随玩家和视角锁定功能

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、制作完整的地图和地图细节设置 1.制作地图前的设置2.制作地图前期该做的事3.制作地图之堆叠素材4.制作地图后期该做的事5.制作地图之修复意想不到的Bug二、…