应用性能管理(APM) 是一种定期跟踪、测量和分析软件应用程序性能及可用性的实践。APM可以帮助你在复杂的微服务环境中获得可见性,这些环境可能会让站点可靠性工程(SRE)团队感到不堪重负。通过生成的洞察,我们可以为用户创造最佳体验并实现预期的业务成果。尽管这是一个复杂的过程,但目标很简单:确保应用程序顺利运行并满足用户和业务的期望。
对应用程序操作的清晰理解以及主动的APM实践对于维护高性能软件应用至关重要。APM不应成为事后的想法,而应该从一开始就考虑。当主动实施时,可以通过将监控组件直接嵌入到应用程序中来整合到软件的运行中。
什么是应用性能管理?应用性能管理 涵盖了对应用程序后端和前端性能的持续监控、分析和管理。应用监控正在不断扩展和演变,但APM策略不应孤立创建。至关重要的是将多个利益相关者、业务专家、应用开发者和运营团队结合起来。一个成功的APM策略不仅关注运行时间或服务器健康状况,还关注在问题发生前应用程序的服务水平目标(SLOs)。
现代APM实施涉及到对应用程序进行检测以收集三种类型的遥测数据:追踪(请求流)、指标(聚合测量)和日志(离散事件)。挑战不只是收集数据,而是收集不会影响性能的“正确”数据。
了解更多关于可观察性指标的信息。
有多种检测方法,但最有效的策略是将自动检测(用于框架和库)与手动检测(用于业务逻辑)相结合。使用OpenTelemetry代理的自动检测可以在最少的代码修改下捕获你80%的可观察性需求:
代码语言:python代码运行次数:0运行复制# 自动检测会自动处理这些
@app.route('/api/orders')
def create_order():
# 仅对关键业务逻辑添加手动跨度
with tracer.start_as_current_span("order.validation") as span:
span.set_attribute("order.value", order_total)
if not validate_order(order_data):
span.set_status(Status(StatusCode.ERROR))
return 400要做的: 从自动检测开始,然后为业务关键操作添加手动跨度。不要: 手动检测每一个函数调用——这将产生性能开销和噪音。陷阱: 过度检测可能增加15%到20%的延迟。通过基准性能比较来监控你的监控。在开发APM策略时,组织或企业需要考虑以下几个组件:
性能监控,包括评估延迟、服务水平目标、响应时间、吞吐量和请求量错误追踪,包括异常、崩溃和失败的API调用基础设施监控,包括支持应用程序的服务器、容器和云环境的健康和资源使用情况用户体验指标,包括加载时间、会话性能、点击路径和浏览器或设备详情(即使系统指标看起来正常,用户可能仍会遇到性能问题)有效APM的关键原则有效的应用性能管理的核心原则是端到端可见性(从用户的浏览器到数据库)、实时监控和洞察,以及以用户和业务目标为中心的关注点。APM可以通过实现持续改进和提高性能来改善应用程序的可扩展性。
要做的: 实现基于SLO的实时仪表板,而不是任意的阈值。不要: 仅依赖定期的性能评估或CPU/内存警报——需要检测用户体验指标。陷阱: 来自低级系统指标的警报疲劳。关注表明实际问题的用户面SLOs。在创建APM策略时,以下是一些关键原则:
1. 主动监控: 在问题影响用户之前,通过设置警报和快速响应任何异常来预防问题。但要避免警报疲劳。将自动警报与人工监督结合,以免错过重要问题,关注结果而非系统指标。
2. 实时洞察: 超越记录问题,基于实时数据和实时仪表板做出快速决策,优先处理最关键的业务事务。使用遥测数据(日志、指标和追踪)解析你的性能洞察。
3. 端到端可见性: 监控整个环境、整个用户流程和所有层次的应用程序,从前端到后端。
4. 用户中心的方法: 从最终用户的角度优先考虑性能和体验,同时考虑关键业务目标。
5. 实际用户监控: 当应用程序在用户手中时,工作并没有结束。通过监控他们的体验,可以根据反馈进行迭代和改进。
6. 持续改进: 利用洞察进行优化,定期发现和解决未报告的问题。问题应动态解决,而不是在定期性能评估中发现后再解决。
7. 上下文传播: 确保追踪上下文流经整个请求路径,尤其是在跨服务边界时:
代码语言:python代码运行次数:0运行复制# 传出请求 - 注入上下文
headers = {}
propagate.inject(headers)
response = requests.post('http://service-b/process', headers=headers)8. 采样策略: 使用智能采样在可见性与性能之间取得平衡:
高流量服务的1%到10%头部采样对错误和慢请求使用尾部采样进行100%采样监控检测开销——目标是<5%的性能影响APM实施的最佳实践合适的APM解决方案应以最小的检测工作量支持你的技术栈。OpenTelemetry 已成为行业标准,提供跨语言的供应商中立检测:
代码语言:java复制@RestController
public class OrderController {
@PostMapping("/orders")
public ResponseEntity
// 自动检测自动捕获此端点
// 添加自定义业务上下文
Span.current().setAttributes(Attributes.of(
stringKey("order.value"), String.valueOf(request.getTotal()),
stringKey("user.tier"), request.getUserTier()
));
return ResponseEntity.ok(processOrder(request));
}
}要做的: 实施采样策略并监控生产中的检测开销。不要: 对高流量服务使用100%采样——这会影响性能并增加存储成本。陷阱: 头部采样可能会错过关键错误追踪。使用尾部采样捕获所有错误,同时减少数据量。如何正确实施:
选择合适的APM解决方案: 合适的APM工具应与应用程序的架构和组织的需求相匹配。解决方案应为组织提供监控、追踪、测量和分析其软件应用程序所需的工具和能力。企业可能会使用OpenTelemetry,一个开源的可观察性框架,来检测和收集来自应用程序的遥测数据(追踪、指标和日志)。管理基数以控制成本: 高基数属性可能使指标变得不可用且昂贵:代码语言:python代码运行次数:0运行复制# 良好的 - 有界基数
span.set_attribute("user.tier", user.subscription_tier) # 3-5个值
span.set_attribute("http.status_code", response.status_code) # ~10个值
# 不良的 - 无界基数
span.set_attribute("user.id", user.id) # 数百万个值
span.set_attribute("request.timestamp", now()) # 无限个值基于SLO而非任意阈值设置智能警报。 使用错误预算来决定何时需要通知相关人员:代码语言:yaml复制slos:
- name: checkout_availability
target: 99.9%
window: 7d
- name: checkout_latency
target: 95% # 95%的请求在500ms以内
window: 7d培训团队并促进协作。 APM策略影响的不仅仅是开发人员,而是涉及广泛的利益相关者。确保在跨部门协作中参与IT团队和其他业务利益相关者。通过将APM纳入你的组织设置中来共同努力。确保设立与业务需求相符的清晰目标和关键绩效指标(KPIs),并考虑用户体验。审查和评估。 APM策略会随着应用程序和业务需求的变化而不断演变。APM中的监控策略成功的应用性能管理策略的关键方面是考虑如何以及何时使用不同的监控方法。考虑监控策略的组合至关重要,因为应用程序的不同组件(如用户体验或基础设施)需要量身定制的方法来有效地检测和解决问题。多样化的策略确保全面覆盖、更快的分析、更少的应用程序中断,以及更满意的最终用户。
有多种监控方法可供考虑:
实时监控: 持续跟踪实时系统性能,具有亚秒级粒度。为业务逻辑实施自定义指标,并结合技术指标:代码语言:python代码运行次数:0运行复制order_processing_duration = Histogram(
"order_processing_seconds",
"Time to process orders",
["payment_method", "order_size"]
)
with order_processing_duration.labels(
payment_method=payment.method,
order_size=get_size_bucket(order.total)
).time():
process_order(order)合成监控: 模拟用户交互,以在真实用户受到影响之前检测问题。对于外部依赖项尤为关键:代码语言:javascript代码运行次数:0运行复制// 关键用户流程的合成检查
const syntheticCheck = async () => {
const span = tracer.startSpan('synthetic.checkout_flow');
try {
await loginUser();
await addItemToCart();
await completePurchase();
span.setStatus({code: SpanStatusCode.OK});
} catch (error) {
span.recordException(error);
span.setStatus({code: SpanStatusCode.ERROR});
throw error;
} finally {
span.end();
}
};深入诊断和分析: 帮助排除复杂的性能瓶颈,包括第三方插件或工具。通过应用程序分析,你可以更深入地分析数据,了解其按功能的性能表现。分布式追踪: 对于微服务架构至关重要。仔细处理跨异步边界的上下文传播:代码语言:python代码运行次数:0运行复制# 事件驱动系统 - 通过消息传播上下文
def publish_order_event(order_data):
headers = {}
propagate.inject(headers)
message = {
'data': order_data,
'trace_headers': headers # 保持追踪上下文
}
kafka_producer.send('order-events', message)APM数据分析和洞察监控和收集数据只是开始。企业需要了解如何解释应用性能管理数据以进行调整和决策。
识别趋势和模式帮助团队主动检测问题。使用相关性分析将用户投诉与后端性能联系起来。以下是使用ES|QL(Elastic的查询语言)的示例:
代码语言:sql复制FROM traces-apm*
| WHERE user.id == "user_12345"
AND @timestamp >= "2024-06-06T09:00:00"
AND @timestamp <= "2024-06-06T10:00:00"
| EVAL duration_ms = transaction.duration.us / 1000
| KEEP trace.id, duration_ms, transaction.name, service.name, transaction.result
| WHERE duration_ms > 2000
| SORT duration_ms DESC
| LIMIT 10检测瓶颈: APM揭示了常见的性能反模式,如n+1问题,可以在下面的代码中看到。使用APM优化代码:
代码语言:python代码运行次数:0运行复制# APM检测的N+1查询问题
def get_user_orders_slow(user_id):
user = User.query.get(user_id)
orders = []
for order_id in user.order_ids: # 每次迭代 = 1次数据库查询
orders.append(Order.query.get(order_id))
return orders
# APM分析后的优化
def get_user_orders_fast(user_id):
return Order.query.filter(Order.user_id == user_id).all() # 单次查询关联指标并将用户投诉与后端性能数据(包括历史数据)联系起来,揭示系统不同部分的交互方式。这可以帮助团队准确诊断根本原因并理解性能问题的全部影响。
自动化根本原因分析 和使用基于AI/机器学习的工具,如AIOps,有助于加速诊断和解决问题,通过找出问题源头,减少停机时间,并释放资源。
使用数据的整体视图来指导未来的决策非常重要。你拥有的数据越多,可以利用的就越多。
要做的: 使用分布式追踪识别导致减速的特定服务和操作。不要: 认为相关性意味着因果关系——通过代码级分析数据进行验证。陷阱: 传统系统在追踪中通常看似黑盒。使用日志关联和合成跨度保持可见性。高级实施模式复杂的生产环境提出了独特的挑战,需要高级实施策略。本节介绍了处理多语言架构、遗留系统集成和复杂相关性分析的实用方法。
多语言环境中的上下文传播: 维护不同语言和框架间的追踪上下文需要对传播机制给予明确关注:
代码语言:java复制// Java - 使用Spring Cloud自动传播
@PostMapping("/orders")
public ResponseEntity
Span.current().setAttributes(Attributes.of(
stringKey("order.type"), request.getOrderType(),
longKey("order.value"), request.getTotalValue()));
// OpenFeign自动将上下文传播到下游服务
return paymentClient.processPayment(request.getPaymentData());
}代码语言:go复制// Go - 手动上下文提取和传播
func processHandler(w http.ResponseWriter, r *http.Request) {
ctx := otel.GetTextMapPropagator().Extract(r.Context(),
propagation.HeaderCarrier(r.Header))
ctx, span := tracer.Start(ctx, "process_payment")
defer span.End()
// 继续保持追踪上下文
}遗留系统集成: 为无法直接检测的系统创建可观察性桥梁:
代码语言:python代码运行次数:0运行复制# 使用关联ID的合成跨度进行大型机调用
with tracer.start_as_current_span("mainframe.account_lookup") as span:
correlation_id = format(span.get_span_context().trace_id, '032x')
logger.info("CICS调用已开始", extra={
"correlation_id": correlation_id,
"trace_id": span.get_span_context().trace_id
})
result = call_mainframe_service(account_data, correlation_id)
span.set_attribute("account.status", result.status)使用ES|QL的高级追踪分析: 使用Elastic的查询语言将用户投诉与后端性能联系起来:
代码语言:sql复制-- 在投诉时间段内查找慢请求
FROM traces-apm*
| WHERE user.id == "user_12345" AND @timestamp >= "2024-06-06T09:00:00"
| EVAL duration_ms = transaction.duration.us / 1000
| WHERE duration_ms > 2000
| STATS avg_duration = AVG(duration_ms) BY service.name, transaction.name
| SORT avg_duration DESC
-- 跨服务边界关联错误
FROM traces-apm*
| WHERE trace.id == "44b3c2c06e15d444a770b87daab45c0a"
| EVAL is_error = CASE(transaction.result == "error", 1, 0)
| STATS error_rate = SUM(is_error) / COUNT(*) * 100 BY service.name
| WHERE error_rate > 0事件驱动架构模式: 通过消息头显式传播上下文以进行异步处理:
代码语言:python代码运行次数:0运行复制# 生产者 - 将上下文注入消息
headers = {}
propagate.inject(headers)
message = {
'data': order_data,
'trace_headers': headers # 保持追踪上下文
}
await kafka_producer.send(''order-events', message)
# 消费者 - 提取并继续追踪
trace_headers = message.get('trace_headers', {})
context = propagate.extract(trace_headers)
with tracer.start_as_current_span("order.process", context=context):
await process_order(message['data'])要做的: 使用 ES|QL 进行复杂的追踪分析,传统仪表板无法处理的。不要: 直接尝试检测遗留系统——使用关联ID和合成跨度。陷阱: 消息队列和异步处理会打破追踪上下文,除非通过消息头显式传播。关键洞察: 完美的检测并不总是可能的。通过战略性地使用关联ID、合成跨度和智能查询,即使在复杂的混合环境中也能实现全面的可观察性。使用Elastic Observability进行性能优化的APMElastic Observability 通过提供统一的可观察性,将应用性能数据与日志、指标和追踪结合在一个强大的平台上,使得应用性能管理策略的实施变得无缝。使用Elastic的OpenTelemetry发行版(EDOT)收集数据使得开始收集APM数据变得快速而简单。
开发人员可以设置异常警报,使用分布式追踪优化特定服务或事务,减少延迟,并通过负载均衡和缓存增强性能稳定性。
通过代码分析,团队可以识别性能热点、低效的代码路径、内存泄漏或减慢应用程序速度的资源密集型操作。企业可以创建自定义仪表板来跟踪KPI,最终支持更好的业务成果。
在Elastic Observability Labs中探索更多技术可观察性内容。
其他APM资源
OTel最佳实践理解可观察性指标:类型、黄金信号和最佳实践APM处理性能使用Elastic Observability的APM性能调优事务采样Elastic连续第三年被评为2023年Gartner® APM和可观察性魔力象限™的远见者