上一篇【第43篇】OAL实现原理从脚本到字节码的魔法之旅下一篇【第45篇】OAP集群的计算流两级聚合的优雅舞蹈一、开篇内置指标不够用自己造SkyWalking默认提供了几十个APM指标——服务响应时间、成功率、吞吐量等等。但现实世界中的业务需求远不止这些电商平台想知道每个商品类别的下单成功率金融系统想监控转账接口的金额分布SaaS平台想追踪每个租户的API调用量这些垂直场景的指标内置OAL覆盖不了。好消息是你可以自己定义OAL指标而且不用重启OAP。----------------------------------------------------------- | 指标需求金字塔 | | | | / \ | | / 自定义指标 \ | | / (业务相关) \ | | /_________________\ | | / \ | | / SkyWalking内置 \ | | / (APM通用指标) \ | | /_________________________\ | | | ----------------------------------------------------------- 图1内置指标是地基自定义指标是上层建筑二、应用场景什么时候需要自定义OAL场景示例OAL写法业务指标监控某接口的下单成功率order_success_rate from Endpoint.(name /api/order).avg(status true ? 100 : 0);按租户统计每个租户的API调用量tenant_call_cpm from Endpoint.(tag[tenant] ! null).count();特定错误码监控HTTP 500错误的分布http_500_count from Service.(httpResponseStatusCode 500).count();流量来源分析来自移动端的请求占比mobile_request_ratio from Service.(tag[platform] mobile).count();性能分段监控不同响应时间的请求分布latency_dist from Service.histogram(latency, 50, 200, 1000, 5000);三、Step 1编写自定义OAL文件在OAP的配置目录下创建自定义OAL文件# 创建自定义OAL文件目录mkdir-p$OAP_HOME/config/oal/# 创建自定义OAL文件touch$OAP_HOME/config/oal/custom-business-metrics.oal编写业务指标定义// // 文件: config/oal/custom-business-metrics.oal// 自定义业务指标定义// // 一、订单业务指标 // 1. 订单接口调用次数order_api_cpmfromEndpoint.(name like/api/order/%).count();// 2. 下单成功率排除支付接口order_create_success_ratefromEndpoint.(name/api/order/createstatustrue).count();// 3. 高价值订单数量标签中amount10000high_value_order_countfromEndpoint.(name/api/order/createtag(amount).toLong()10000).count();// 二、用户行为指标 // 4. 登录接口调用量login_api_cpmfromEndpoint.(name/api/user/login||name/api/auth/login).count();// 5. 登录失败率login_failure_ratefromEndpoint.(name like/api/%/loginstatusfalse).count();// 6. 搜索接口平均响应时间search_endpoint_avgfromEndpoint.(name like/api/search/%).avg(latency);// 三、支付业务指标 // 7. 支付接口调用次数payment_api_cpmfromEndpoint.(name/api/payment/process).count();// 8. 支付接口P99响应时间payment_p99fromEndpoint.(name/api/payment/process).p99(latency);// 9. 支付失败数量payment_failure_countfromEndpoint.(name/api/payment/processstatusfalse).count();// 四、性能分段监控 // 10. 订单接口响应时间分布直方图order_latency_distributionfromEndpoint.(name like/api/order/%).histogram(latency,50,100,200,500,1000,3000,5000);四、Step 2通过动态配置加载自定义OALSkyWalking支持配置中心动态下发OAL配置。这是不重启OAP修改指标的关键。4.1 使用配置文件方式# config/application.ymloal:# 启用自定义OAL目录customOALDir:${SW_OAL_CUSTOM_DIR:config/oal}# 结合内置OALcombineWithCoreOAL:true# 自定义OAL文件列表customOALFiles:-custom-business-metrics.oal-custom-database-metrics.oal4.2 使用Nacos动态配置推荐生产使用# 在Nacos中创建配置# Data ID: skywalking-oal-custom# Group: skywalking# 配置内容就是OAL脚本# 通过Nacos API或控制台上传curl-XPOSThttp://nacos:8848/nacos/v1/cs/configs\-ddataIdskywalking-oal-custom\-dgroupskywalking\-dcontent$(catcustom-business-metrics.oal|base64)# OAP的配置指向Nacosconfiguration:selector:${SW_CONFIGURATION:nacos}nacos:serverAddr:${SW_CONFIG_NACOS_SERVER_ADDR:127.0.0.1:8848}namespace:${SW_CONFIG_NACOS_NAMESPACE:}group:skywalking# 动态OAL配置period:60# 每60秒检查一次配置变更五、Step 3在Dashboard中展示自定义指标自定义指标写好了但Dashboard上还看不到。需要配置Widget来展示5.1 添加Widget配置// ui-initialized-templates/custom-business-dashboard.json{name:业务监控大盘,type:DASHBOARD,children:[{name:订单业务指标,children:[{name:订单接口调用量,widget:{title:订单接口调用量 (CPM),type:Line,metrics:[order_api_cpm],aggregation:/,aggregationNum:1}},{name:下单成功率,widget:{title:下单成功率 (%),type:Line,metrics:[order_create_success_rate],aggregation:/,unit:%}},{name:订单接口响应时间分布,widget:{title:订单接口响应分布,type:Heatmap,metrics:[order_latency_distribution],chartType:ChartHeatmap}}]},{name:支付业务指标,children:[{name:支付接口P99延迟,widget:{title:支付接口 P99 延迟,type:Line,metrics:[payment_p99],aggregation:/,unit:ms}},{name:支付失败次数,widget:{title:支付失败数,type:Line,metrics:[payment_failure_count],aggregation:/}}]}]}5.2 查询自定义指标数据# 通过GraphQL API查询自定义指标curl-XPOST http://localhost:12800/graphql\-HContent-Type: application/json\-d{ query: query { readMetricsValues( condition: { name: \order_api_cpm\, entity: {scope: Endpoint} }, duration: {start: \2026-07-01 0000\, end: \2026-07-02 0000\, step: HOUR} ) { label values { values { id value } } } } }六、Step 4自定义指标的性能影响评估新增指标不是免费午餐。每个指标都会增加CPU和内存开销。下面是评估方法6.1 CPU开销评估公式每个指标的CPU消耗 ≈ (数据量/秒) × (聚合函数复杂度) × (时间粒度数) 示例估算 每秒1000条Endpoint数据 avg函数复杂度: 1x 3个时间粒度(分钟/小时/天) 一个avg指标:C PU消耗 1000 × 1 × 3 3000 ops/s 每秒1000条Endpoint数据 percentile(p99)复杂度: 10x (需要维护排序结构) 3个时间粒度 一个p99指标: CPU消耗 1000 × 10 × 3 30000 ops/s6.2 内存开销评估每个指标的内存消耗 ≈ (实体数量) × (聚合计算所需内存) × (时间窗口数) 示例估算 100个服务实体1000个端点实体 avg聚合每个实体: ~48 bytes 每分钟窗口: 保留2分钟的数据 每小时窗口: 保留3小时的数据 每天窗口: 保留45天的数据 端点avg指标: 1000 × 48 × (2 3 45) 2.4 MB 如果加了p99聚合: 1000 × 1024 × 50 51.2 MB6.3 基准测试脚本#!/bin/bash# 自定义指标性能基准测试# 1. 记录基准性能无自定义指标echo 基准性能测试 foriin{1..5};docurl-shttp://localhost:12800/graphql\-d{query:{ getClusterBrief { numOfService numOfEndpoint numOfDatabase } }}\|jq.datasleep10done# 2. 加载自定义指标cpcustom-business-metrics.oal$OAP_HOME/config/oal/echo自定义指标已加载,等待生效...# 3. 等待30秒后重新测试性能sleep30echo 加载自定义指标后性能测试 foriin{1..5};docurl-shttp://localhost:12800/graphql\-d{query:{ getClusterBrief { numOfService numOfEndpoint numOfDatabase } }}\|jq.datasleep10done# 4. 检查JVM内存使用jcmd$(pgrep-foapService)GC.heap_info6.4 性能优化建议------------------------------------------------------------------- | 自定义指标性能优化建议 | ------------------------------------------------------------------- | | | 1. 能不用分位数就不用分位数 | | avg比p99便宜10倍如果只是看趋势用avg就够了 | | | | 2. Filter先于聚合 | | 好的写法Endpoint.(latency 3000).count() | | 不好的写法先用count()再筛选 | | 先用Filter过滤掉大部分数据聚合的计算量就小了 | | | | 3. 使用disable关闭不需要的内置指标 | | disable(service_resp_time_histogram); | | 每个关闭的指标都是资源节约 | | | | 4. 合理设置时间窗口保留策略 | | 分钟级指标保留2-7天即可 | | 天级指标才需要保留更长时间 | | | | 5. 控制自定义指标的总数量 | | 建议不超过20个自定义指标 | | 如果确实需要更多考虑增加OAP节点 | | | ------------------------------------------------------------------- 图2自定义指标性能优化五原则七、实战案例电商双十一指标监控// // 双十一专项指标 - 1111-metrics.oal// // 1. 总订单量每分钟total_ordersfromEndpoint.(name/api/order/create).count();// 2. 秒杀接口响应时间flash_sale_avgfromEndpoint.(name like/api/flashsale/%).avg(latency);// 3. 优惠券使用量coupon_usagefromEndpoint.(name/api/coupon/use).count();// 4. 退款率refund_ratefromEndpoint.(name like/api/refund/%).count();// 5. 支付成功量按支付渠道alipay_successfromEndpoint.(name/api/payment/alipaystatustrue).count();wechatpay_successfromEndpoint.(name/api/payment/wechatstatustrue).count();// 6. 下单响应时间分布order_response_distfromEndpoint.(name like/api/order/%).histogram(latency,50,100,200,500,1000,3000,10000);// 7. P99延迟用于SLA告警flash_sale_p99fromEndpoint.(name like/api/flashsale/%).p99(latency);对应告警配置# alarm-settings.ymlrules:flash_sale_p99_alert:metrics-name:flash_sale_p99op:threshold:1000period:3count:2message:秒杀接口P99延迟超过1秒当前值: {value}msrefund_rate_alert:metrics-name:refund_rateop:threshold:100period:10count:3message:退款率异常升高当前值: {value}/每分钟八、总结自定义OAL指标是SkyWalking从通用APM走向业务可观测的桥梁。通过今天的学习你应该能根据业务需求编写自定义OAL文件通过动态配置实现不重启修改指标在Dashboard中可视化自定义指标评估自定义指标的性能影响关键提醒指标不是越多越好。每新增一个指标特别是分位数/直方图类的都要评估对OAP集群的资源影响。上一篇【第43篇】OAL实现原理从脚本到字节码的魔法之旅下一篇【第45篇】OAP集群的计算流两级聚合的优雅舞蹈