
应用性能管理(APM) 是一种定期跟踪、测量和分析软件应用程序性能及可用性的实践。APM可以帮助你在复杂的微服务环境中获得可见性,这些环境可能会让站点可靠性工程(SRE)团队感到不堪重负。通过生成的洞察,我们可以为用户创造最佳体验并实现预期的业务成果。尽管这是一个复杂的过程,但目标很简单:确保应用程序顺利运行并满足用户和业务的期望。
对应用程序操作的清晰理解以及主动的APM实践对于维护高性能软件应用至关重要。APM不应成为事后的想法,而应该从一开始就考虑。当主动实施时,可以通过将监控组件直接嵌入到应用程序中来整合到软件的运行中。
应用性能管理 涵盖了对应用程序后端和前端性能的持续监控、分析和管理。应用监控正在不断扩展和演变,但APM策略不应孤立创建。至关重要的是将多个利益相关者、业务专家、应用开发者和运营团队结合起来。一个成功的APM策略不仅关注运行时间或服务器健康状况,还关注在问题发生前应用程序的服务水平目标(SLOs)。
现代APM实施涉及到对应用程序进行检测以收集三种类型的遥测数据:追踪(请求流)、指标(聚合测量)和日志(离散事件)。挑战不只是收集数据,而是收集不会影响性能的“正确”数据。
有多种检测方法,但最有效的策略是将自动检测(用于框架和库)与手动检测(用于业务逻辑)相结合。使用OpenTelemetry代理的自动检测可以在最少的代码修改下捕获你80%的可观察性需求:
# 自动检测会自动处理这些
@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在开发APM策略时,组织或企业需要考虑以下几个组件:
有效的应用性能管理的核心原则是端到端可见性(从用户的浏览器到数据库)、实时监控和洞察,以及以用户和业务目标为中心的关注点。APM可以通过实现持续改进和提高性能来改善应用程序的可扩展性。
在创建APM策略时,以下是一些关键原则:
1. 主动监控: 在问题影响用户之前,通过设置警报和快速响应任何异常来预防问题。但要避免警报疲劳。将自动警报与人工监督结合,以免错过重要问题,关注结果而非系统指标。
2. 实时洞察: 超越记录问题,基于实时数据和实时仪表板做出快速决策,优先处理最关键的业务事务。使用遥测数据(日志、指标和追踪)解析你的性能洞察。
3. 端到端可见性: 监控整个环境、整个用户流程和所有层次的应用程序,从前端到后端。
4. 用户中心的方法: 从最终用户的角度优先考虑性能和体验,同时考虑关键业务目标。
5. 实际用户监控: 当应用程序在用户手中时,工作并没有结束。通过监控他们的体验,可以根据反馈进行迭代和改进。
6. 持续改进: 利用洞察进行优化,定期发现和解决未报告的问题。问题应动态解决,而不是在定期性能评估中发现后再解决。
7. 上下文传播: 确保追踪上下文流经整个请求路径,尤其是在跨服务边界时:
# 传出请求 - 注入上下文
headers = {}
propagate.inject(headers)
response = requests.post('http://service-b/process', headers=headers)8. 采样策略: 使用智能采样在可见性与性能之间取得平衡:
合适的APM解决方案应以最小的检测工作量支持你的技术栈。OpenTelemetry 已成为行业标准,提供跨语言的供应商中立检测:
@RestController
public class OrderController {
@PostMapping("/orders")
public ResponseEntity<Order> createOrder(@RequestBody OrderRequest request) {
// 自动检测自动捕获此端点
// 添加自定义业务上下文
Span.current().setAttributes(Attributes.of(
stringKey("order.value"), String.valueOf(request.getTotal()),
stringKey("user.tier"), request.getUserTier()
));
return ResponseEntity.ok(processOrder(request));
}
}如何正确实施:
# 良好的 - 有界基数
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()) # 无限个值slos:
- name: checkout_availability
target: 99.9%
window: 7d
- name: checkout_latency
target: 95% # 95%的请求在500ms以内
window: 7d成功的应用性能管理策略的关键方面是考虑如何以及何时使用不同的监控方法。考虑监控策略的组合至关重要,因为应用程序的不同组件(如用户体验或基础设施)需要量身定制的方法来有效地检测和解决问题。多样化的策略确保全面覆盖、更快的分析、更少的应用程序中断,以及更满意的最终用户。
有多种监控方法可供考虑:
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)// 关键用户流程的合成检查
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();
}
};# 事件驱动系统 - 通过消息传播上下文
def publish_order_event(order_data):
headers = {}
propagate.inject(headers)
message = {
'data': order_data,
'trace_headers': headers # 保持追踪上下文
}
kafka_producer.send('order-events', message)监控和收集数据只是开始。企业需要了解如何解释应用性能管理数据以进行调整和决策。
识别趋势和模式帮助团队主动检测问题。使用相关性分析将用户投诉与后端性能联系起来。以下是使用ES|QL(Elastic的查询语言)的示例:
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优化代码:
# 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 - 使用Spring Cloud自动传播
@PostMapping("/orders")
public ResponseEntity<Order> createOrder(@RequestBody OrderRequest request) {
Span.current().setAttributes(Attributes.of(
stringKey("order.type"), request.getOrderType(),
longKey("order.value"), request.getTotalValue()));
// OpenFeign自动将上下文传播到下游服务
return paymentClient.processPayment(request.getPaymentData());
}// 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()
// 继续保持追踪上下文
}遗留系统集成: 为无法直接检测的系统创建可观察性桥梁:
# 使用关联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的查询语言将用户投诉与后端性能联系起来:
-- 在投诉时间段内查找慢请求
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事件驱动架构模式: 通过消息头显式传播上下文以进行异步处理:
# 生产者 - 将上下文注入消息
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'])Elastic Observability 通过提供统一的可观察性,将应用性能数据与日志、指标和追踪结合在一个强大的平台上,使得应用性能管理策略的实施变得无缝。使用Elastic的OpenTelemetry发行版(EDOT)收集数据使得开始收集APM数据变得快速而简单。
开发人员可以设置异常警报,使用分布式追踪优化特定服务或事务,减少延迟,并通过负载均衡和缓存增强性能稳定性。
通过代码分析,团队可以识别性能热点、低效的代码路径、内存泄漏或减慢应用程序速度的资源密集型操作。企业可以创建自定义仪表板来跟踪KPI,最终支持更好的业务成果。
在Elastic Observability Labs中探索更多技术可观察性内容。
其他APM资源
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。