计算机性能监控体系:Quark2.0

一、背景

在过去的IT日常支持场景中,因为服务的用户、终端、系统等等因业务而异,往往会遇到以下类似这些问题或需求:

  • IT工程师定位终端问题跨越不同的平台或系统,低效繁琐
  • 用户想要获取一些个人相关的IT环境信息,只能咨询IT部门
  • 电脑终端的软硬件资源类性能消耗无法集中宏观监控、数字化管理
  • 主动预判终端问题的客观依据和快速定位能力有差异化

通过建设一套“IT用户终端信息一体化管理平台”,采集用户信息、机器信息、软件信息、权限信息、网络信息等等,实现数据入库、实时更新、可视化。具备提供一站式查询管理、缩短case定位时间、集中数字化管理、提前预警终端软硬件风险等能力。

其中针对电脑及性能数据的采集,面临着指标多样性、数据实时性存储、系统差异性等高要求,下面针对电脑终端信息采集的Quark 2.0体系进行详细的介绍。

二、架构

Quark 2.0体系是为“IT用户终端信息一体化管理平台”建立的一套计算机性能监控体系,作为IT资产管理的延伸,帮助IT人员完成日常维护、故障排查和资源统计等工作。

该体系架构示意图如下:

安装在办公电脑的Agent按单位时间一次的心跳频率,采集计算机的CPU、内存、磁盘、网络、电池、进程占用等信息上报给Master集群,并把历史数据打点存入InfluxDB。支持Windows和MacOS两种主流的办公电脑操作系统。Master集群接收到Agent上报的心跳数据,将其存入Redis,并通过Etcd进行节点注册和健康检测。Registry集群作为IT一体化自助查询平台的后端服务器集群,承担了多个数据来源的集中查询、日志记录、任务调度等功能。

Agent客户端支持采集的数据类型如下:

心跳上报:实时获取最新数据,新数据会覆盖旧数据
数据打点:存储最新数据,保留旧数据

类型

指标

采集方式

备注

系统

操作系统

心跳上报

Windows/MacOS,包括具体版本号

计算机名

心跳上报

内核架构

心跳上报

例:x86_64

硬件

序列号

心跳上报

制造厂商

心跳上报

产品型号

心跳上报

CPU

型号

心跳上报

厂商

心跳上报

核数

心跳上报

占用核数

数据打点

频率

心跳上报

使用率

数据打点

user、sys、iowait、idle、busy

温度

数据打点

内存

容量

心跳上报/数据打点

单位:GiB

使用量

心跳上报/数据打点

单位:GiB

频率

心跳上报

磁盘

总空间

心跳上报/数据打点

单位:GiB

已使用空间

心跳上报/数据打点

单位:GiB

分区

心跳上报/数据打点

单位:GiB

驱动

心跳上报

包括型号、类型、状态

读写字节数

数据打点

单位:GiB

读写速度

数据打点

单位:KiB/s

读写次数

数据打点

网络

网络名

心跳上报

MTU

心跳上报

Mac地址

心跳上报

IP地址

心跳上报

驱动

心跳上报

包括名称、描述、厂商、产品号

上下行字节数

数据打点

单位:GiB

上下行数据包总数

数据打点

上下行速度

数据打点

单位:KiB/s

电池

状态

心跳上报/数据打点

状态码

心跳上报/数据打点

例:有无电池、使用电池/AC电源、是否满电

剩余电量

心跳上报/数据打点

剩余使用时间

心跳上报/数据打点

部分系统版本不支持此指标

进程

占用CPU进程

数据打点

记录前五个

占用内存进程

数据打点

占用IO进程

数据打点

WiFi

ESSID

数据打点

BSSID

数据打点

信号强度

数据打点

联网情况

ping内网

数据打点

min_rtt、max_rtt、avg_rtt、std_dev_rtt、loss

ping外网

数据打点

ping网关

数据打点

DNS解析

数据打点

是否能解析特定域名

三、数据采集

Agent客户端基于Go语言开发,通过gopsutil库、wmic等采集计算机数据。对于MacOS,则以解析ioreg、system_profiler等指令获取对应指标。由于采集指标众多,下面仅以电池和WiFi作为示例,讲解具体的数据采集原理。

电池信息

对于Windows,通过wmic指令调用Win32_Batteryapi,获取电脑的状态、状态码、剩余电量等信息。

//go:build windows

// +build windows

package battery

import (

       "errors"

       "math"

       "git.ppd.com/quark/pkg/logger"

       "git.ppd.com/quark/pkg/metrics"

       "github.com/shopspring/decimal"

       "github.com/yusufpapurcu/wmi"

)

type batteryInfo struct {

       Availability             aStatus

       BatteryStatus            bStatus

       Status                   string

       EstimatedChargeRemaining uint16

       EstimatedRunTime         uint32

       DesignCapacity           uint32

       FullChargeCapacity       uint32

}

func win32BatteryInfo() (*batteryInfo, error) {

       var batteryInfo []batteryInfo

      err := wmi.Query("SELECT * FROM Win32_Battery", &batteryInfo)

       if err != nil {

              return nil, err

       }

       if len(batteryInfo) > 0 {

              return &batteryInfo[0], nil

       }

       return nil, errors.New("empty battery info")

}

func BatteryInfo() metrics.BatteryInfo {

       battery, err := win32BatteryInfo()

       if err != nil {

              logger.Errorf("get BatteryInfo error: %s", err.Error())

              return metrics.BatteryInfo{Status: "NoBattery"}

       }

       var estimatedRunTime float64

       if battery.EstimatedRunTime == uint32(math.Pow(2, 32)/60) {

              estimatedRunTime = 0

       } else {

              tmpRunTime := decimal.NewFromFloat(float64(battery.EstimatedRunTime) / 60)

              estimatedRunTime, _ = tmpRunTime.Round(1).Float64()

       }

       return metrics.BatteryInfo{

              Status: battery.Status,

              Availability: metrics.BatStatus{

                     Code: uint16(battery.Availability),

                     Desc: battery.Availability.String(),

              },

              BatteryStatus: metrics.BatStatus{

                     Code: uint16(battery.BatteryStatus),

                     Desc: battery.BatteryStatus.String(),

              },

              CurrentCap:     float64(battery.FullChargeCapacity),

              DesignCap:      float64(battery.DesignCapacity),

              EstimatedTime:  estimatedRunTime,

             EstimatedPower: int64(battery.EstimatedChargeRemaining),

       }

}

对于MacOS,则通过解析system_profiler SPPowerDataType和pmset -g batt指令的返回获取电池的对应信息。

WiFi信息

对于Windows,通过解析netsh wlan show interfaces指令的返回获取WiFi的BSSID、ESSID和信号强度。

对于MacOS,则通过析/System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport -I和ioreg -l -n AirPortDriver | perl -lne print $1 if $_ =~ /IO80211BSSID.*<(.*)>/指令获取WiFi的对应信息。

四、心跳上报

QRPC组件

Master集群与Agent客户端之间基于自研的QRPC组件进行长连接通信。与市面上常见的开源RPC组件相比,QRPC组件具有通信简单、连接管理透明、完全可控等优点。

开发者

简述

优点

缺点

GRPC

Google

功能强大,是一款非常完善的rpc框架

功能强大完善;多语言支持;序列化效率高

学习、维护的成本较高;引入大量第三方库,存在潜在风险

net/rpc(标准库)

GO Team

内置RPC包

标准库内置,无需引入新库

TCP网络连接管理缺失;序列化(GO内置)效率较低

QRPC

自研

用于Master集群与Agent客户端的通信

轻量化框架;通信简单;连接管理透明

适用性较窄

通信过程

首次心跳上报时,Agent需要先从Etcd中获取一个可用的Master节点,并采用Hash算法保证Master集群的负载均衡。获取到Master节点之后,建立长连接并写入Agent配置。Master节点接收到连接请求之后完成握手连接,并将心跳数据存储到Redis中,完成本次通信。如果发生意外导致连接中断或Master节点挂掉,Agent会自动重新获取新的可用节点。

获取Master节点实现如下:

import (

       "encoding/json"

       "fmt"

       "hash/fnv"

       "git.ppd.com/quark/agent_v2/config"

       "git.ppd.com/quark/agent_v2/stats"

       "git.ppd.com/quark/pkg/client/etcd"

       "git.ppd.com/quark/pkg/logger"

       "git.ppd.com/quark/pkg/metrics"

)

func (a *Agent) getMasterIP() (string, error) {

       // 获取本机IP

       localIP := stats.IP()

       if localIP == "" {

              return "", fmt.Errorf("get local_ip failed: local_ip is <nil>")

       }

       // 获取所有可用的Master节点

       // 要求:当前节点负载低于预设的最大负载

       var assignAddrs []string

       maxLoad := config.Config().MasterConfig.MaxLoad

       masterInfo := registryMasterNode()

       for _, v := range masterInfo {

              if v.ReportNum < maxLoad {

                     assignAddrs = append(assignAddrs, v.IP)

              }

       }

       // Hash算法获取Master节点

       hashValue := hash(localIP)

       index := int(hashValue) % len(assignAddrs)

       masterNode := assignAddrs[index]

       return masterNode, nil

}

// 获取已注册的Master节点

func registryMasterNode() map[string]*metrics.MasterHeartBeat {

       tmp := make(map[string]*metrics.MasterHeartBeat, 0)

       // etcd初始化

       cfg := config.Config().EtcdConfig

       etcd.Init(cfg.EtcdAddr)

       defer func() {

              if err := etcd.EClient.Close(); err != nil {

                     logger.Errorf("close etcd client failed: %s", err.Error())

              }

       }()

      resp, err := etcd.EClient.Get(cfg.MasterPath, clientv3.WithPrefix())

       if err != nil {

              logger.Errorf("从etcd获取master节点列表失败: %s", err.Error())

              return tmp

       }

       for k, v := range resp.Kvs {

              master := &metrics.MasterHeartBeat{}

              err := json.Unmarshal(v.Value, &master)

              if err != nil {

                     logger.Errorf("master节点%d序列化失败: %s", k, err.Error())

                     continue

              }

              tmp[master.IP] = master

       }

       return tmp

}

// Hash: string to int

func hash(key string) uint32 {

       h := fnv.New32a()

       h.Write([]byte(key))

       return h.Sum32()

}

Agent在线状态管理

Master获取Agent在线状态,主要是通过Redis的键过期订阅机制。预先设置Agent键的过期时间,每次心跳上报时更新值,同时重置初始时间。超过过期时间仍未更新,则视为Agent已离线。

五、历史数据打点

InfluxDB

InfluxDB是一个用于存储和分析时间序列数据的开源数据库,主要特性如下:

  • 内置HTTP接口,使用方便
  • 数据可以打标记,查询很灵活
  • 类SQL的查询语句
  • 安装管理简单,并且读写数据高效
  • 支持实时查询

Quark 2.0体系基于InfluxDB v1的HTTP POST方式,对Agent采集的历史数据进行打点存储。

InfluxDB-Relay

由于InfluxDB v1开源版不支持集群模式,故采用官方推荐的社区开源高可用方案InfluxDB-Relay。

InfluxDB-Relay为InfluxDB提供双写能力,确保其中一个节点挂掉后数据不会丢失。注意InfluxDB-Relay只代理写流量,查询数据时直接访问InfluxDB。

influxdb-relay.toml 配置如下:

[[http]]

name = "influx-http"

bind-addr = "127.0.0.1:9096"

output = [

    { name="db1", location = "http://XX.XXX.XX.XXX:8086/write" },

    { name="db2", location = "http://XX.XXX.XX.XXX:8086/write" },

    { name="db3", location = "http://XX.XXX.XX.XXX:8086/write" },

]

页面交互

“IT用户终端信息一体化管理平台”支持根据域账号和计算机名查询对应信息,包括用户的基本信息、名下资产和所在群组、办公电脑的IT资产信息、心跳数据和历史数据等。

六、未来展望

在后续的平台建设中,“IT用户终端信息一体化管理平台”还将完善接入更完整的其他用户信息,例如各相关系统权限、入网认证各环节状态、虚拟资产等信息,进行一体化关联,为实现终端智能化管理夯实基础。

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

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

相关文章

【新闻转载】“假冒 LockBit”来袭:勒索软件借助 AWS S3 偷窃数据,威胁升级

关键要点 Trend团队发现了一些利用 Amazon S3&#xff08;简单存储服务&#xff09;传输加速功能的 Golang 勒索软件样本&#xff0c;用于窃取受害者的文件并上传至攻击者控制的 S3 存储桶。 这些样本中硬编码的 Amazon Web Services (AWS) 凭证被用于追踪与恶意活动关联的 AW…

python之数据结构与算法(数据结构篇)-- 栈

一、栈的概念 这里我们不去了解教科书上面的“教条概念”&#xff0c;其实“栈”的概念和古代的时候的“客栈”是有异曲同工之妙的。 在这里我们把客栈看成“栈”&#xff0c;旅客看作“栈元素” 1.当旅客进来住店时&#xff0c;叫做“入栈”&#xff1b; 2.当旅客退房时&#…

【银河麒麟高级服务器操作系统】虚拟机lvm分区丢失现象分析及解决建议

了解更多银河麒麟操作系统全新产品&#xff0c;请点击访问 麒麟软件产品专区&#xff1a;https://product.kylinos.cn 开发者专区&#xff1a;https://developer.kylinos.cn 文档中心&#xff1a;https://documentkylinos.cn 环境描述 系统环境 物理机/虚拟机/云/容器 虚拟…

论文速读:完全测试时域适应(Test-time Adaptation)目标检测(CVPR2024)

原文标题&#xff1a;Fully Test-time Adaptation for Object Detection 中文标题&#xff1a;完全测试时间适应目标检测 通过百度网盘分享的文件&#xff1a;Fully_Test-time_Adaptation_for_Obje... 链接&#xff1a; 百度网盘 请输入提取码 提取码&#xff1a;yrvz 代码地址…

蔚来汽车 AI产品经理面经

问的问题都比较深入&#xff0c;要求有项目基础&#xff0c;祝好&#x1f970; 1、自我介绍 2、你的产品上线后有没有关注用户反馈&#xff1f; 3、给客户交付时&#xff0c;如果产品能力还没ready&#xff0c;你会怎么办&#xff1f; 4、你们团队需求一般来源于哪里&#…

国内短剧源码短剧系统搭建小程序部署H5、APP打造短剧平台

​在当今的互联网时代&#xff0c;短剧作为一种新兴的娱乐形式&#xff0c;受到了越来越多用户的喜爱。为了提供更好的用户体验和满足用户需求&#xff0c;一个好的短剧系统需要具备多元化的功能和优质的界面设计。 本文将介绍国内短剧源码短剧系统搭建小程序部署H5、APP所需的…

深入浅出了解AI教育发展与落地应用情况

2023年,是生成式AI能力涌现的一年,通用大模型是其中的主旋律。经过一年的发展,通用大模型格局已初步形成,生成式AI也从能力展示走向应用落地。进入2024年,对生成式AI的讨论和实践也都转向如何赋能产业。相比于通用大模型,进入产业内的大模型需要的是对行业的Know-How,以…

‘随机失活’:人工智能真的在模仿人脑吗?

序言&#xff1a;过拟合是人工智能训练中的一个常见问题&#xff0c;类似于一位“读死书”的学生&#xff0c;他只能机械地背诵书本内容&#xff0c;缺乏灵活性&#xff0c;一旦题目稍有变化便无法理解。为了解决这一问题&#xff0c;科学家们从人脑的学习方式中获得启发&#…

【机器学习】揭秘XGboost:高效梯度提升算法的实践与应用

目录 &#x1f354; XGBoost 原理 1.1 目标函数确定和树的复杂度介绍 1.2 XGBoost目标函数的推导 1.3 泰勒公式展开 1.4 化简目标函数 1.5 问题再次转换 1.6 对叶子结点求导 1.7 XGBoost的回归树构建方法 &#x1f354; XGBoost API 2.1 通用参数 2.2 Booster 参数 …

Transformer的Pytorch实现【1】

使用Pytorch手把手搭建一个Transformer网络结构并完成一个小型翻译任务。 首先&#xff0c;对Transformer结构进行拆解&#xff0c;Transformer由编码器和解码器&#xff08;Encoder-Decoder&#xff09;组成&#xff0c;编码器由Multi-Head Attention Feed-Forward Network组…

【MySQL】存储引擎

MySQL采用的是可插拔的存储引擎架构&#xff0c;也就是说在运行期间可以动态的加载或卸载存储引擎&#xff1b;查看当前服务器存储引擎的方法show engines&#xff0c;其中重点关注两个字段即可&#xff0c;其一是Support-表示当前服务器是否支持&#xff0c;其二是它的数值yes…

构建校园社团信息管理平台:Spring Boot技术的核心要点

6系统测试 6.1概念和意义 测试的定义&#xff1a;程序测试是为了发现错误而执行程序的过程。测试(Testing)的任务与目的可以描述为&#xff1a; 目的&#xff1a;发现程序的错误&#xff1b; 任务&#xff1a;通过在计算机上执行程序&#xff0c;暴露程序中潜在的错误。 另一个…

RAG工具:FlashRAG用于高效 RAG 研究的 Python 工具包

随着大语言模型的火热&#xff0c;如何提高生成内容的准确性和可靠性&#xff0c;成为各行业关注的重点。检索增强生成&#xff08;RAG&#xff09;正是通过将强大的检索功能与语言模型结合&#xff0c;在生成文本时引入来自外部的实时信息。 今天&#xff0c;我们来了解一款为…

任天堂新款闹钟被玩家破解,竟能运行《毁灭战士》游戏!

任天堂于10月9日推出的Nintendo Sound Clock Alarmo闹钟在市场上引起了强烈反响。这款定价为99.99美元&#xff08;约706元人民币&#xff09;的闹钟&#xff0c;在日本则以12980日元&#xff08;约619元人民币&#xff09;的价格迅速被抢购一空。 近日&#xff0c;首批收到闹钟…

我笑了,居民日均劳动不满3.5小时

鸭鸭是一位现代都市青年&#xff0c;生活节奏规律&#xff0c;时间安排精细&#xff0c;非常符合国家统计局发布的时间利用调查报告中的数据。以下是鸭鸭一天的生活日常&#xff1a; 早上 7:00 - 鸭鸭准时起床&#xff0c;开始一天的生活。他通常会在床上稍微刷刷手机&#xf…

django快速基本配置(2)

知识星球 | 深度连接铁杆粉丝&#xff0c;运营高品质社群&#xff0c;知识变现的工具 目录 配置开发目录 配置MySQL数据库 配置Redis数据库 配置工程日志 用户注册 跨域CORS 注意 配置开发目录 libs 存放第三方的库文件 utils 存放项目自己定义的公共函数或类等 apps 存…

前端技术月刊-2024.11

本月技术月刊聚焦于前端技术的最新发展和业务实践。业界资讯部分&#xff0c;React Native 0.76 版本发布&#xff0c;带来全新架构&#xff1b;Deno 2.0 和 Node.js 23 版本更新&#xff0c;推动 JavaScript 生态进步&#xff1b;Flutter 团队规模缩减&#xff0c;引发社区关注…

Golang的Web应用架构设计

# Golang的Web应用架构设计 介绍 是一种快速、高效、可靠的编程语言&#xff0c;它在Web应用开发中越来越受欢迎。Golang的Web应用架构设计通常包括前端、后端和数据库三个部分。在本篇文章中&#xff0c;我们将详细介绍Golang的Web应用架构设计及其组成部分。 前端 在Golang的…

element-plus按需引入报错AutoImport is not a function

官网文档&#xff1a;快速开始 | Element Plus webpack配置 // webpack.config.js const AutoImport require(unplugin-auto-import/webpack) const Components require(unplugin-vue-components/webpack) const { ElementPlusResolver } require(unplugin-vue-components…

【51单片机】串口通信原理 + 使用

学习使用的开发板&#xff1a;STC89C52RC/LE52RC 编程软件&#xff1a;Keil5 烧录软件&#xff1a;stc-isp 开发板实图&#xff1a; 文章目录 串口硬件电路UART串口相关寄存器 编码单片机通过串口发送数据电脑通过串口发送数据控制LED灯 串口 串口是一种应用十分广泛的通讯接…