看不见的服务是无法维护的。在微服务时代,我们需要 Metrics (指标) 和 Tracing (追踪) 来洞察系统内部。
1. Metrics (Prometheus)
我们需要导出关键指标,如 QPS、连接数、延迟等。
1.1. 暴露指标接口
利用 evhttp 开一个 /metrics
接口。
void metrics_handler(struct evhttp_request *req, void *arg) {
struct evbuffer *buf = evbuffer_new();
// 格式化 Prometheus 文本格式
evbuffer_add_printf(buf, "# HELP active_connections Current active connections\n");
evbuffer_add_printf(buf, "# TYPE active_connections gauge\n");
evbuffer_add_printf(buf, "active_connections %d\n", current_connections);
evhttp_send_reply(req, HTTP_OK, "OK", buf);
evbuffer_free(buf);
}1.2. 关键指标
- 业务指标: QPS, 错误率。
- Libevent 指标:
event_base_get_num_events(base, EVENT_BASE_COUNT_ACTIVE): 当前激活事件数。event_base_get_num_events(base, EVENT_BASE_COUNT_ADDED): 总注册事件数。
2. Tracing (OpenTelemetry)
异步回调会导致 Trace Context 丢失。我们需要手动传递 Context。
2.1. Context 传递
在创建 bufferevent 时,将 Trace Context
封装在 ctx 结构体中,作为 cbarg
传入。
struct ConnectionContext {
opentelemetry::trace::SpanContext span_ctx;
// ...
};
void read_cb(struct bufferevent *bev, void *arg) {
ConnectionContext *ctx = (ConnectionContext *)arg;
// 恢复 Span
auto span = tracer->StartSpan("read_cb", ctx->span_ctx);
// ...
}3. 精细化耗时追踪
为了定位慢请求,我们需要记录每个阶段的耗时。 *
T0: accept 连接。 *
T1: read_cb 收到完整请求。 *
T2: 业务处理完成 (DB 返回)。 *
T3: write_cb 发送完成。
通过计算 T1-T0, T2-T1, T3-T2,我们可以绘制出请求的火焰图,精准定位瓶颈。
上一篇: 06-production/deployment-ops.md - 部署与运维 下一篇: 06-production/debugging.md - 异步调试与追踪