从零开始写一个APM监控程序(一)协议

APM(Application Performance Monitoring)是一种用于监控和管理应用程序性能的解决方案。它通过收集、分析和报告应用程序的性能数据,帮助开发人员和系统管理员更好地了解应用程序的运行状况,识别潜在的性能问题,并进行优化。

一般来说,APM 工具提供以下功能:

  1. 性能监控: 实时监控应用程序的性能指标,包括响应时间、吞吐量、错误率等。

  2. 事务追踪: 能够跟踪和记录应用程序中各个事务的执行情况,从而了解事务的执行路径、时间分布等。

  3. 错误检测: 检测并报告应用程序中的错误和异常,帮助快速定位和解决问题。

  4. 性能分析: 分析应用程序的性能瓶颈,提供可视化的分析工具,帮助开发人员优化代码和系统配置。

  5. 资源利用率监控: 监控硬件资源(如 CPU、内存、磁盘等)的利用率,帮助发现资源瓶颈。

APM 工具通常可以与各种类型的应用程序一起使用,包括 Web 应用、移动应用、微服务架构等。它们通过在应用程序中嵌入代理或采集器来收集数据,并将数据传送到中央存储或云服务中进行分析和展示。

一些常见的 APM 工具包括 New Relic、AppDynamics、Datadog、Elastic APM 等。这些工具的具体特性和支持的技术栈可能有所不同,选择合适的工具通常取决于应用程序的特点和需求。

国产的开源东西主要是SkyWalking。Apache SkyWalking 是一个开源的应用性能管理(APM)系统,用于监控、诊断和优化分布式系统的性能。它支持多种语言,包括 Java、.NET、Node.js、Go 等,可以跟踪分布式系统中的请求流,并提供详细的性能数据和可视化的监控工具。

以下是一些 SkyWalking 的主要特点:

  1. 分布式追踪: SkyWalking 提供了分布式追踪能力,可以跟踪请求在整个分布式系统中的传播路径,包括服务之间的调用和调用链路的详细信息。

  2. 性能指标: 提供系统的性能指标,包括吞吐量、响应时间、错误率等,以便开发人员和运维人员更好地了解系统的运行状况。

  3. 自动仪表板: 提供直观的仪表板和可视化工具,帮助用户监控和诊断分布式应用程序的性能问题。

  4. 跨语言支持: SkyWalking 支持多种语言,使其适用于各种技术栈和混合语言环境。

  5. 插件扩展: 具有插件系统,可以通过插件扩展功能,支持集成其他系统和工具。

  6. 开源社区: 作为 Apache 项目,SkyWalking 拥有活跃的开源社区,不断更新和改进系统。

SkyWalking 有助于开发团队识别性能瓶颈、优化代码,并提高系统的可维护性。

但是,别人的东西永远不一定完全适合自己,大多数时候改造的成本比从零开始写一个成本更高。

典型的APM(Application Performance Monitoring)通常是通过收集、分析和展示应用程序的性能数据,以监控和优化应用程序的运行状态。以下是一般的 APM 实现思路:

  1. 数据采集(Instrumentation): 在应用程序代码中插入监控点,收集关键性能指标。这通常包括跟踪请求、记录方法执行时间、捕获错误、以及收集资源利用情况等。开发者需要在代码中嵌入监控仪器,以便收集有关应用程序性能的数据。

  2. 数据传输: 将采集到的数据传输到中央收集点。这可以通过使用 Agent、SDK 或代理来完成。这些组件可以负责收集数据并将其传输到 APM 系统的后端。

  3. 数据存储: 将数据存储在后端数据库或数据仓库中,以供分析和查询。通常,APM 系统会使用数据库或其他持久性存储来保存监控数据。

  4. 数据分析: 对收集到的数据进行分析,以识别性能瓶颈、错误和潜在的优化点。分析可能包括生成报告、绘制性能图表、检测异常等。

  5. 可视化: 将分析结果以可视化的方式展示给开发者、运维人员和其他利益相关者。这可以通过仪表板、图表、报表等方式呈现。

  6. 告警和通知: 在性能达到或超过阈值时,发出告警,通知相关人员。这有助于快速响应性能问题,保持应用程序在高性能状态。

  7. 追踪请求和事务: 通过追踪请求和事务,可以了解整个系统的性能状况,包括前端和后端服务的交互。

  8. 支持多语言和多平台: APM 工具通常需要支持多种编程语言和运行环境,以便适用于各种应用程序和服务。

  9. 安全性: 保护监控数据的安全性,确保监控数据不被未授权的访问。

采集数据的部分分为探针和SDK两种,比如是JAVA和dotNet有虚拟机的,可以使用hook技术来拦截自己需要的方法,如果是编译型语言基本上使用的是SDK,程序员插码的方式实现。当然在linux下也可以使用eBPF的方式来构建挂钩程序,但是做到通用比较麻烦。

我认为与其在后期加HOOK,不如在项目之初就考虑需要监控的位置,用SDK来解决。

首先我们要解决交换协议:

一般,采集的内容分类3类:

  • 某个代码块执行的时长效果等数据叫span,多个span可以串为一个trace;
  • 针对硬件使用率的监控一般叫metric;
  • 再有,就是分级部署时候探针(sdk)与后端之间还有一级,会对数据融合一次,减少数据量。

我打算采用protobuf3的方式定义数据交互格式,每个消息都定义最基本的常用的数据,其他的部分作为键值对可以扩展,后续只需要定义键值对就好了;其实也没有啥好扩展的,这么多年就这么点东西;数据传输可以用json,也可以用protobuf编码,目前大多数产品都是http传输,我觉得可以再进一步,使用http2或者websocket更好。

syntax = "proto3";
package model;
option go_package = "birdim/server/pb";// 服务定义
service ApmService {rpc AgentEvent (ApmAgentMsg) returns (ApmServerMsg);rpc FrontEvent (ApmAgentMsg) returns (ApmServerMsg);
}// 发送起端都是ApmAgentRequest     接收端应答ApmResponse
// 具体根据类型字段区分
// 1) ApmHello     ----> ApmHelloReply
// 2) ApmSpan      ----> ApmReply
// 3) ApmStatistic ----> ApmReply
// 4) APmUsage     ----> ApmReply
// 5) ApmHeartBeat ----> ApmReply | ApmCtrl// 服务端发起参数调整        执行后应答
// 6) ApmCtrl      ----> ApmReply// 展示端发起查询           服务端返回数据
// 7) ApmQuery     ----> ApmData// 消息的所有类型
enum ApmMsgType {// Invalid value. The name must be globally unique.AMTUnused = 0;AMTHello= 1;AMTHelloReply = 2;AMTSpan = 3;AMTStatistic =  4;AMTCtrl = 5;AMTReply = 6;AMTQuery = 7;AMTData = 8;AMTHeartBeat = 9;AMTUsage = 10;
}// 控制命令代码
enum ApmCmdCode{ACUnused = 0;ACRestart = 1;ACSuspend = 2;ACResume = 3;ACConfig = 4;
}// 执行状态代码
enum ApmStateCode{ASUnused = 0;ASOk = 1;ASFail = 2;ASPending = 3;
}// 键值对,未用
message KeyValuePair {// 定义单个键值对string key = 1;string value = 2;
}// 如果需要登录,则需要认证
enum ApmAuthType{AUTNone = 0;  // 可以不使用AUTPass = 1;  // 前端客户使用AUTKey = 2;   // agent 使用
}// 如果需要登录,一定是从客户端发起
message ApmHello{int64 seq = 1;int64 tm = 2;string u_id = 3;ApmAuthType auth_type = 4;  // 认证类型string secret = 5;     // 密码或者key,或者啥也不用map<string, string> params = 6;
}// 协商的应答
message ApmHelloReply{int64 seq = 1;int64 tm = 2;string u_id = 3;      // 应答者的身份string state = 4;     // 继续其他步骤,成功或者错误map<string, string> params = 6;
}// 采集的具体内容
message ApmSpan{// Request fields hereint64 seq = 1;int64 tm = 2;string u_id = 3;// APM-related fieldsstring trace_id = 4;string trace_name = 5;string span_id = 6;string parent_span_id = 7;string span_name = 8;string file = 9;string class = 10;string func = 11;string line = 12;int64 tm_start = 13;int64 tm_end = 14;ApmStateCode state = 15;string detail = 16;map<string, string> params = 17;
}// 如果需要在agent或者collector 统计过滤
message ApmStatistic{int64 seq = 1;int64 tm = 2;string u_id = 3;string trace_name = 4;string span_name = 5;int64 tm_start = 6;int64 tm_end = 7;int64 span_count = 8;int64 span_errors = 9;int64 span_slow_count = 10;int64 span_avg_time_cost = 11;int64 span_max_time_cost = 12;int64 span_min_time_cost = 13;map<string, string> params = 14;
}message ApmCtrl{int64 seq = 1;int64 tm = 2;string u_id =3;ApmCmdCode code = 4;  // 控制的代码string cmd = 5;string detail = 6;map<string, string> params = 7;
}// 应答一条或者多条上报
message ApmReply{int64 seq = 1;int64 tm = 2;string u_id = 3;int64 ref_seq1 = 4;int64 ref_seq2 = 5;int32 state = 6;string detail = 7;
}// 心跳数据
message ApmHearBeat{int64 seq = 1;int64 tm = 2;string u_id = 3;
}// 使用率
message ApmUsage{int64 seq = 1;int64 tm = 2;string u_id = 3;int64 start_tm = 4;   // 搜索开始时间int64 end_tm = 5;     // 搜索结束时间int64 delta_tm = 6;   // 时间片大小map<string, string> params = 7;  // 内存,CPU,磁盘;的最大值,最小值,平均值,
}// 查询类型
enum ApmQueryType{AQTUnused = 0;AQTUsage = 1;          // 利用率按时间片绘图AQTSpanDetail = 2;     //AQTSpanStatistic = 3;
}enum ApmOpCodeType{AOCTUnused = 0;         // 说明是一个括号,里面有多个childAOCTEqual = 1;          // x = 1AOCTUnEqual = 2;        // x != 1AOCTBetween = 3;        // 1 < x < 2AOCTBetweenBoth = 4;    // 1 <= x <= 2AOCTBetweenLeft = 5;    // 1 <= x < 2AOCTBetweenRight = 6;   // 1 < x <= 2AOCTGreaterThan = 7;    // x > 1AOCTGreaterOrEqual = 8; // x >= 1AOCTLessThan = 9;       // x < 9AOCTLessOrEqual = 10;   // x <= 9AOCTLike = 11;          // 正则匹配字符串AOCTUnlike = 12;AOCTIn = 13;            // 集合之中
}// 定义一个查询条件的树状结构
message ApmQueryCondition{string name = 1;string field = 2;              // 字段,ApmOpCodeType  op_code = 3;    // 计算符,值个数与运算符有关bool  join_code = 4;           // 同级条件合并运算符,and --> true, or ---> falserepeated string values = 5;   // 根据字段的类型做数据转换repeated ApmQueryCondition children = 6;   // 如果有多级,就用子节点方式,本级就相当于一个括号,op = Unused
}// 查询, 查询条件为空,就是认为全都要,统计类型需要时间分片大小,而详情不需要
message ApmQuery{int64 seq = 1;int64 tm = 2;string u_id = 3;int64 start_tm = 4;   // 搜索开始时间int64 end_tm = 5;     // 搜索结束时间int64 delta_tm = 6;   // 时间片大小ApmQueryType type = 7;repeated ApmQueryCondition conditions = 8;   // 一级条件也是一组,按照顺序合并}// 使用率的列表
message ApmUsageList{repeated ApmUsage list = 1;
}// 上报详细情况列表
message ApmSpanList{repeated ApmSpan list = 1;
}message ApmStatisticList{repeated ApmStatistic list = 1;
}// 查询数据得到的结果
message ApmData{int64 seq = 1;int64 tm = 2;string u_id = 3;int64 start_tm = 4;   // 搜索开始时间int64 end_tm = 5;     // 搜索结束时间int64 delta_tm = 6;   // 时间片大小ApmQueryType type = 7;oneof message {ApmUsageList usages = 8;ApmSpanList  spans = 9;ApmStatisticList statistic = 10;}}// the message that one agent would send
message ApmAgentMsg{ApmMsgType date_type=1;oneof message {ApmHello hello = 2;ApmSpan span = 3;ApmStatistic statistic = 4;ApmUsage usage = 5;ApmReply reply = 6;}
}// 前端查询使用
message ApmFrontMsg{ApmMsgType date_type=1;oneof message{ApmHello  hello = 2;ApmQuery  query = 3;}
}// reponse from server, collector or agent
message ApmServerMsg{ApmMsgType date_type=1;oneof message{ApmHelloReply hello_reply = 2;ApmReply reply = 3;ApmCtrl  ctrl = 4;ApmData  data = 5;}
}

未完待续……

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

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

相关文章

卷积神经网络(CNN)衣服图像分类的实现

文章目录 前期工作1. 设置GPU&#xff08;如果使用的是CPU可以忽略这步&#xff09;我的环境&#xff1a; 2. 导入数据3.归一化4.调整图片格式5. 可视化 二、构建CNN网络模型三、编译模型四、训练模型五、预测六、模型评估 前期工作 1. 设置GPU&#xff08;如果使用的是CPU可以…

Office文件在线预览大全-Word文档在线预览的实现方法-OFD文档在线预览-WPS文件在线预览

Office文件在线预览大全-Word文档在线预览的实现方法-OFD文档在线预览-WPS文件在线预览 Office文件在线预览指的是文件在浏览器中可以直接预览查看&#xff0c;不需要安装任何插件就可以实现文档的在线预览功能、打印功能、文件转PDF功能、文件转OFD功能、文档内容提取功能、自…

JVM——运行时数据区(程序计数器+栈)

目录 1.程序计数器2.栈Java虚拟机栈 - 栈帧的组成1.Java虚拟机栈-局部变量表3.Java虚拟机栈-操作数栈3.Java虚拟机栈-帧数据 3.Java虚拟机栈-栈内存溢出4.本地方法栈 ⚫ Java虚拟机在运行Java程序过程中管理的内存区域&#xff0c;称之为运行时数据区。 ⚫ 《Java虚拟机规范》中…

Unity减少发布打包文件的体积(二)——设置WebGL发布时每张图片的压缩方式

一个项目在发布成WebGL后&#xff0c;其体积至关重要&#xff0c;体积太大&#xff0c;用户加载会经历一个漫长的等待…轻则骂娘&#xff0c;重则用脚把电脑踢烂(扣质保金)… 那么如何减少发布后的体积呢&#xff0c;本文从图片的压缩开始入手。 前传回顾&#xff1a; Unity减…

Linux mmap 的作用是什么?

文章目录 1.简介2.相关函数3.mmap和常规文件操作的区别4.作用参考文献 1.简介 mmap&#xff08;memory map&#xff09;即内存映射&#xff0c;用于将一个文件或设备映射到进程的地址空间。 2.相关函数 创建映射函数&#xff1a; #include <sys/mman.h>void *mmap(v…

Upwork 新手使用指南——如何快速在Upwork上接单

Upwork 这个自由职业平台不知道大家听说过没&#xff0c;在 Upwork&#xff0c;如果你是自由职业者&#xff0c;你可以接单&#xff1b;如果你是客户&#xff0c;你可以找人干活。但对于新手来说&#xff0c;怎么使用 Upwork 并且用好 Upwork 是一大难题。因此今天给大家分享 U…

你好,我叫Python,欢迎你认识派森。(来自关于Python语言的全方位自我介绍。

文章目录 自我简介一、Python的发展历程二、Python的特色1.语言特色2.语法特色 三、Python2与Python3的比较1.print 函数2.Unicode3.除法运算4.异常5.八进制字面量表示6.不等运算符7.python 3.0严格使用tab键进行缩进 四、Python适用开发场景及成果1.应用领域2.Python开发出的应…

20231120_python练习_天气网爬取城市近七天温度情况

先根据城市名找到对应编码&#xff0c;然后获取近七天天气情况 淄博 101120301 [‘20日&#xff08;今天&#xff09;’] [‘晴’] <class ‘list’> [‘7℃’] [‘\n’, ‘<3级’, ‘\n’] 淄博 101120301 [‘21日&#xff08;明天&#xff09;’] [‘晴转阴’] <…

python科研绘图:P-P图与Q-Q图

目录 什么是P-P图与Q-Q图 分位数 百分位数 Q-Q图步骤与原理 Shapiro-Wilk检验 绘制Q-Q图 绘制P-P图 什么是P-P图与Q-Q图 P-P图和Q-Q图都是用于检验样本的概率分布是否服从某种理论分布。 P-P图的原理是检验实际累积概率分布与理论累积概率分布是否吻合。若吻合&#xf…

srs webrtc推拉流环境搭建(公网)

本地环境搭建 官方代码https://github.com/ossrs/srs 拉取代码&#xff1a; git clone https://github.com/ossrs/srs.gitcd ./configure make ./objs/srs -c conf/https.rtc.confsrs在公网上&#xff0c;由于srs是lite-ice端&#xff0c;导致他不会主动到srs获取自己的公网i…

MySQL的执行器是怎么工作的

作为优化器后的真正执行语句的层&#xff0c;执行器有三种方式和存储引擎&#xff08;一般是innoDB&#xff09;交互 主键索引查询 查询的条件用到了主键&#xff0c;这个是全表唯一的&#xff0c;优化器会选择const类型来查询&#xff0c;然后while循环去根据主键索引的B树结…

nn.KLDivLoss,nn.CrossEntropyLoss,nn.MSELoss,Focal_Loss

KL loss&#xff1a;https://blog.csdn.net/qq_50001789/article/details/128974654 https://pytorch.org/docs/stable/nn.html 1. nn.L1Loss 1.1 公式 L1Loss: 计算预测 x和 目标y之间的平均绝对值误差MAE, 即L1损失&#xff1a; l o s s 1 n ∑ i 1 , . . . n ∣ x i…

Java 设计模式——桥接模式

目录 1.概述2.结构3.实现3.1.实现化类3.2.具体实现化类3.3.抽象化类3.4.扩展抽象化类3.5.测试 4.优缺点5.使用场景 1.概述 &#xff08;1&#xff09;现在有一个需求&#xff0c;需要创建不同的图形&#xff0c;并且每个图形都有可能会有不同的颜色。我们可以利用继承的方式来…

数据结构与算法之美学习笔记:22 | 哈希算法(下):哈希算法在分布式系统中有哪些应用?

目录 前言应用五&#xff1a;负载均衡应用六&#xff1a;数据分片应用七&#xff1a;分布式存储解答开篇 & 内容小结 前言 本节课程思维导图 今天&#xff0c;我们再来看剩余三种应用&#xff1a;负载均衡、数据分片、分布式存储。你可能已经发现&#xff0c;这三个应用都…

详解Java设计模式之职责链模式

原文&#xff1a;详解Java设计模式之职责链模式_java_脚本之家 责任链模式是一种行为设计模式&#xff0c;使多个对象都有机会处理请求&#xff0c;从而避免请求的发送者和接收者之间的耦合关系&#xff0c;文中通过代码示例给大家介绍的非常详细,需要的朋友可以参考下 − 目…

直播美颜SDK对比评测:技术原理与应用实践

直播行业蓬勃发展&#xff0c;其中&#xff0c;美颜滤镜技术在直播中扮演着至关重要的角色。本文将深入探讨不同直播美颜SDK的技术原理&#xff0c;并通过对比评测它们在实际应用中的表现&#xff0c;以揭示各SDK的优劣之处。 一、背景 随着直播技术的不断进步&#xff0c;直…

【前端知识】Node——events模块的相关方法

一、events模块的常用方法 // 事件总线 const EventsEmitter require(events);const emitter new EventsEmitter();function HLog(msg){console.log(msg); }// 监听 emitter.on(hlog, HLog);setTimeout(() > {// 触发&#xff0c;打印emitter.emit(hlog, hello emitter!)…

虚幻C++ day5

角色状态的常见机制 创建角色状态设置到UI上 在MainPlayer.h中新建血量&#xff0c;最大血量&#xff0c;耐力&#xff0c;最大耐力&#xff0c;金币变量&#xff0c;作为角色的状态 //主角状态UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category "Playe Stats&…

配置Nginx服务器用于Web应用代理和SSL{仅配置文件}

在本篇博文中&#xff0c;我们将深入讨论如何配置Nginx服务器&#xff0c;使其成为一个强大的Web应用代理&#xff0c;并通过SSL协议加强通信的安全性。 1. 服务器监听与SSL设置 首先&#xff0c;我们要配置Nginx服务器以监听HTTPS流量并设置SSL证书&#xff0c;确保通信的安…

基于人工水母算法优化概率神经网络PNN的分类预测 - 附代码

基于人工水母算法优化概率神经网络PNN的分类预测 - 附代码 文章目录 基于人工水母算法优化概率神经网络PNN的分类预测 - 附代码1.PNN网络概述2.变压器故障诊街系统相关背景2.1 模型建立 3.基于人工水母优化的PNN网络5.测试结果6.参考文献7.Matlab代码 摘要&#xff1a;针对PNN神…