旅游网站功能简介,万和城官方网站,商务类网站,网站的基本建设投资APM#xff08;Application Performance Monitoring#xff09;是一种用于监控和管理应用程序性能的解决方案。它通过收集、分析和报告应用程序的性能数据#xff0c;帮助开发人员和系统管理员更好地了解应用程序的运行状况#xff0c;识别潜在的性能问题#xff0c;并进行…APMApplication Performance Monitoring是一种用于监控和管理应用程序性能的解决方案。它通过收集、分析和报告应用程序的性能数据帮助开发人员和系统管理员更好地了解应用程序的运行状况识别潜在的性能问题并进行优化。
一般来说APM 工具提供以下功能 性能监控 实时监控应用程序的性能指标包括响应时间、吞吐量、错误率等。 事务追踪 能够跟踪和记录应用程序中各个事务的执行情况从而了解事务的执行路径、时间分布等。 错误检测 检测并报告应用程序中的错误和异常帮助快速定位和解决问题。 性能分析 分析应用程序的性能瓶颈提供可视化的分析工具帮助开发人员优化代码和系统配置。 资源利用率监控 监控硬件资源如 CPU、内存、磁盘等的利用率帮助发现资源瓶颈。
APM 工具通常可以与各种类型的应用程序一起使用包括 Web 应用、移动应用、微服务架构等。它们通过在应用程序中嵌入代理或采集器来收集数据并将数据传送到中央存储或云服务中进行分析和展示。
一些常见的 APM 工具包括 New Relic、AppDynamics、Datadog、Elastic APM 等。这些工具的具体特性和支持的技术栈可能有所不同选择合适的工具通常取决于应用程序的特点和需求。
国产的开源东西主要是SkyWalking。Apache SkyWalking 是一个开源的应用性能管理APM系统用于监控、诊断和优化分布式系统的性能。它支持多种语言包括 Java、.NET、Node.js、Go 等可以跟踪分布式系统中的请求流并提供详细的性能数据和可视化的监控工具。
以下是一些 SkyWalking 的主要特点 分布式追踪 SkyWalking 提供了分布式追踪能力可以跟踪请求在整个分布式系统中的传播路径包括服务之间的调用和调用链路的详细信息。 性能指标 提供系统的性能指标包括吞吐量、响应时间、错误率等以便开发人员和运维人员更好地了解系统的运行状况。 自动仪表板 提供直观的仪表板和可视化工具帮助用户监控和诊断分布式应用程序的性能问题。 跨语言支持 SkyWalking 支持多种语言使其适用于各种技术栈和混合语言环境。 插件扩展 具有插件系统可以通过插件扩展功能支持集成其他系统和工具。 开源社区 作为 Apache 项目SkyWalking 拥有活跃的开源社区不断更新和改进系统。
SkyWalking 有助于开发团队识别性能瓶颈、优化代码并提高系统的可维护性。 但是别人的东西永远不一定完全适合自己大多数时候改造的成本比从零开始写一个成本更高。
典型的APMApplication Performance Monitoring通常是通过收集、分析和展示应用程序的性能数据以监控和优化应用程序的运行状态。以下是一般的 APM 实现思路 数据采集Instrumentation 在应用程序代码中插入监控点收集关键性能指标。这通常包括跟踪请求、记录方法执行时间、捕获错误、以及收集资源利用情况等。开发者需要在代码中嵌入监控仪器以便收集有关应用程序性能的数据。 数据传输 将采集到的数据传输到中央收集点。这可以通过使用 Agent、SDK 或代理来完成。这些组件可以负责收集数据并将其传输到 APM 系统的后端。 数据存储 将数据存储在后端数据库或数据仓库中以供分析和查询。通常APM 系统会使用数据库或其他持久性存储来保存监控数据。 数据分析 对收集到的数据进行分析以识别性能瓶颈、错误和潜在的优化点。分析可能包括生成报告、绘制性能图表、检测异常等。 可视化 将分析结果以可视化的方式展示给开发者、运维人员和其他利益相关者。这可以通过仪表板、图表、报表等方式呈现。 告警和通知 在性能达到或超过阈值时发出告警通知相关人员。这有助于快速响应性能问题保持应用程序在高性能状态。 追踪请求和事务 通过追踪请求和事务可以了解整个系统的性能状况包括前端和后端服务的交互。 支持多语言和多平台 APM 工具通常需要支持多种编程语言和运行环境以便适用于各种应用程序和服务。 安全性 保护监控数据的安全性确保监控数据不被未授权的访问。
采集数据的部分分为探针和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或者啥也不用mapstring, string params 6;
}// 协商的应答
message ApmHelloReply{int64 seq 1;int64 tm 2;string u_id 3; // 应答者的身份string state 4; // 继续其他步骤成功或者错误mapstring, 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;mapstring, 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;mapstring, string params 14;
}message ApmCtrl{int64 seq 1;int64 tm 2;string u_id 3;ApmCmdCode code 4; // 控制的代码string cmd 5;string detail 6;mapstring, 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; // 时间片大小mapstring, 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_type1;oneof message {ApmHello hello 2;ApmSpan span 3;ApmStatistic statistic 4;ApmUsage usage 5;ApmReply reply 6;}
}// 前端查询使用
message ApmFrontMsg{ApmMsgType date_type1;oneof message{ApmHello hello 2;ApmQuery query 3;}
}// reponse from server, collector or agent
message ApmServerMsg{ApmMsgType date_type1;oneof message{ApmHelloReply hello_reply 2;ApmReply reply 3;ApmCtrl ctrl 4;ApmData data 5;}
} 未完待续……