性能监控与告警系统实战从0到可观测性的完整技术路线性能监控的三个核心层次独立开发者的产品有了真实用户后系统还活着吗就不应该是靠用户投诉来发现的。你需要一套性能监控与告警系统。我把它分为三个层次对应不同的工程成熟度和产品规模L1基础监控Infrastructure Monitoring服务器的CPU、内存、磁盘、网络。数据库的连接数、查询性能。以及应用进程是否还运行。这是让系统在用户投诉之前就被修复的基础。L2应用性能监控Application Performance Monitoring, APM不只是系统还活着而是系统运行得怎么样。API响应时间、错误率、数据库慢查询、外部API调用延迟。这是在用户体验恶化之前发现问题的关键。L3业务指标监控Business Metrics Monitoring系统和应用都健康但业务还健康吗。新用户注册量突然下降、付费转化率突然降低、核心功能的使用率突然下滑。这是在业务出问题之前发现趋势的核心。L1实战Prometheus Grafana的基础监控搭建为什么选Prometheus Grafana这两个工具的组合是开源监控领域的事实标准。Prometheus负责采集和存储指标Grafana负责可视化指标和配置告警。核心概念指标Metric一个可时间序列化的测量值。如cpu_usage_percent、memory_usage_bytes、http_requests_total。采集ScrapingPrometheus定期如每15秒从配置的采集目标Targets拉取指标数据。存储StoragePrometheus用自研的时序数据库TSDB存储指标数据。默认保留15天可配置。实战搭建以监控一个Node.js应用为例第一步让应用暴露指标给Prometheus用prom-client库Node.js生态最流行的Prometheus客户端库// metrics.ts import client from prom-client; // 创建一个Registry指标注册表 const register new client.Registry(); // 1. 默认的系统指标如CPU、内存、事件循环延迟 client.collectDefaultMetrics({ register }); // 2. 自定义指标HTTP请求_duration直方图 const httpRequestDuration new client.Histogram({ name: http_request_duration_seconds, help: Duration of HTTP requests in seconds, labelNames: [method, route, status_code], buckets: [0.1, 0.5, 1, 2, 5] // 响应时间的分桶 }); register.registerMetric(httpRequestDuration); // 3. 写一个/metrics端点返回Prometheus格式的指标 app.get(/metrics, async (req, res) { try { const metrics await register.metrics(); res.set(Content-Type, register.contentType); res.send(metrics); } catch (error) { res.status(500).end(error); } }); // 4. 在中间件里记录每个请求的响应时间 app.use((req, res, next) { const startTime Date.now(); res.on(finish, () { const duration (Date.now() - startTime) / 1000; httpRequestDuration .labels(req.method, req.route?.path || req.path, res.statusCode.toString()) .observe(duration); }); next(); });第二步配置Prometheus来采集这个/metrics端点创建prometheus.yml配置文件global: scrape_interval: 15s # 每15秒采集一次 scrape_configs: - job_name: my-nodejs-app static_configs: - targets: [localhost:3000] # 你的应用的地址运行Prometheus用Dockerdocker run -d \ --nameprometheus \ -p 9090:9090 \ -v $(pwd)/prometheus.yml:/etc/prometheus/prometheus.yml \ prom/prometheus现在访问http://localhost:9090在Graph页面里输入rate(http_request_duration_seconds_count[5m])就能看到过去5分钟内每秒HTTP请求数的变化。第三步用Grafana可视化这些指标运行Grafana用Dockerdocker run -d \ --namegrafana \ -p 3000:3000 \ grafana/grafana访问http://localhost:3000默认用户名/密码admin/admin。在Grafana里添加Prometheus作为数据源Data Source。导入现成的Node.js应用监控仪表盘Grafana官网有社区贡献的仪表盘JSON可以直接导入。L2实战用Sentry做应用性能监控APMPrometheus Grafana擅长监控系统级指标CPU、内存、请求率。但应用内部发生了什么——哪个SQL查询最慢哪个外部API调用延迟最高用户的一次请求在服务器端花了多长时间——这些需要专门的APM工具。为什么选Sentry它也提供APM功能我已经用Sentry做错误追踪前面文章写过。Sentry从2023年开始也提供了Performance模块——自动追踪应用性能且和错误追踪深度集成这个慢请求有没有关联的错误。核心概念分布式追踪Distributed Tracing现代应用通常不是一个函数处理一个请求。一个请求可能经过负载均衡器 → API服务器 → 数据库 → 外部API如Claude API。分布式追踪给每个请求分配一个唯一的trace_id然后在请求经过的每个服务里记录这个服务花了多长时间处理这叫一个span。最后把这些span在时间轴上连起来就能看到用户请求 → 数据库查询50ms→ AI API调用2000ms→ 返回响应的完整时间线。在Node.js应用里启用Sentry Performance// sentry.ts import * as Sentry from sentry/node; import { Elysium } from sentry/tracing; Sentry.init({ dsn: your-sentry-dsn, environment: process.env.NODE_ENV, tracesSampleRate: 1.0, // 采集100%的请求生产环境可以降到0.1-0.2 integrations: [ new Elysium({ additionalOptions: { trackLayers: true } }), ], }); // 在应用入口处初始化 app.use(Sentry.Handlers.requestHandler()); app.use(Sentry.Handlers.tracingHandler()); // 在应用出口处错误处理之前 app.use(Sentry.Handlers.errorHandler()); app.use(Sentry.Handlers.tracingHandler());启用后Sentry会自动追踪每个HTTP请求的响应时间每个数据库查询的执行时间如果用的是受支持的ORM如Prisma、TypeORM每个外部HTTP调用的耗时如fetch()或axios在Sentry后台查看Performance登录Sentry后台进入Performance页面。你会看到一个Transaction Summary事务摘要列表。每个Transaction对应一个被追踪的操作如一个HTTP请求、一个数据库查询。点击一个慢事务可以看到它的Trace Details追踪详情——一个时间轴展示这个事务所包含的所有span如POST /api/generate → prisma.query → fetch(https://api.anthropic.com)。实战价值找到性能瓶颈2024年8月我通过Sentry Performance发现我的产品的AI生成功能平均响应时间是8秒。但AI API的调用本身只需要5秒。那剩下的3秒花在哪里了查看追踪详情后发现在调用AI API之前我的代码做了一次检查用户订阅状态的数据库查询但这个查询没有加索引导致每次都全表扫描300ms。给这个字段加上索引后查询时间降到了5ms。总响应时间从8秒降到了5.5秒。L3实战业务指标监控的技术实现业务指标如每日新注册用户数、付费转化率通常不是技术指标而是产品指标。但它们对产品的健康度同样重要甚至更重要。为什么不能直接用Google AnalyticsGoogle AnalyticsGA是做网站流量分析的利器。但它有两个局限它追踪的是前端事件如页面浏览、按钮点击。后端发生的业务事件如用户订阅了Pro计划很难用GA准确追踪。它的数据更新有延迟通常24-48小时。你不能在GA里实时看到过去1小时的注册量。我的方案把业务指标存在PostgreSQL里用Grafana做实时仪表盘。第一步设计业务指标的数据表-- 每日指标汇总表用PostgreSQL的物化视图或定时任务填充 CREATE TABLE daily_business_metrics ( id SERIAL PRIMARY KEY, date DATE NOT NULL, new_registrations INTEGER DEFAULT 0, pro_subscriptions INTEGER DEFAULT 0, churn_count INTEGER DEFAULT 0, active_users INTEGER DEFAULT 0, created_at TIMESTAMP DEFAULT NOW() ); -- 可以每天凌晨用定时任务Cron Job计算并插入前一天的指标第二步用Node.js定时任务填充这个表// cron/update-daily-metrics.ts import cron from node-cron; import prisma from prisma/client; const prisma new PrismaClient(); // 每天凌晨2点执行 cron.schedule(0 2 * * *, async () { const yesterday new Date(); yesterday.setDate(yesterday.getDate() - 1); const dateStr yesterday.toISOString().split(T)[0]; // 计算昨天的指标 const newRegistrations await prisma.user.count({ where: { createdAt: { gte: new Date(${dateStr}T00:00:00Z), lt: new Date(${dateStr}T23:59:59Z) } } }); const proSubscriptions await prisma.subscription.count({ where: { plan: PRO, status: ACTIVE, createdAt: { gte: new Date(${dateStr}T00:00:00Z), lt: new Date(${dateStr}T23:59:59Z) } } }); // ... 计算其他指标 // 插入或更新 await prisma.dailyBusinessMetrics.upsert({ where: { date: yesterday }, update: { newRegistrations, proSubscriptions }, create: { date: yesterday, newRegistrations, proSubscriptions } }); });第三步在Grafana里添加PostgreSQL作为数据源并创建仪表盘在Grafana里添加PostgreSQL数据源填数据库地址、用户名、密码。创建一个新的Dashboard添加一个Time series面板。在查询编辑器里写SQLSELECT date, new_registrations, pro_subscriptions FROM daily_business_metrics ORDER BY date;Grafana会自动把结果渲染成时间序列图。现在我可以在一个仪表盘里同时看到系统指标CPU、内存、请求率→ 来自Prometheus应用性能指标响应时间、错误率、慢查询→ 来自Sentry业务指标注册量、付费转化、留存率→ 来自PostgreSQL告警配置从邮件轰炸到精准通知监控系统搭好了但如果每次CPU超过10%就发一封告警邮件你会在3天内关掉所有告警。这就是告警疲劳Alert Fatigue。我的告警分级策略P0致命立即通知生产环境API完全不可用如负载均衡器返回502超过5分钟数据库连接完全断开支付系统故障通知方式电话 SMS SlackP1严重15分钟内通知API错误率超过5%持续10分钟服务器内存使用率超过90%核心业务指标如日注册量日环比下跌超过30%通知方式Slack 邮件P2需关注每日汇总非核心功能的错误服务器磁盘使用率超过80%业务指标周环比轻微波动通知方式每日汇总邮件在Prometheus Alertmanager里配置告警规则创建alerts.ymlgroups: - name: app_alerts rules: # P1告警API错误率超过5% - alert: HighApiErrorRate expr: rate(http_requests_total{status_code~5..}[5m]) / rate(http_requests_total[5m]) 0.05 for: 10m # 持续10分钟才触发避免短暂波动 labels: severity: P1 annotations: summary: API错误率超过5% description: 当前错误率{{ $value | humanizePercentage }} # P1告警内存使用率超过90% - alert: HighMemoryUsage expr: (1 - (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes)) 0.9 for: 10m labels: severity: P1 annotations: summary: 服务器内存使用率超过90%然后在prometheus.yml里配置Alertmanager的地址alerting: alertmanagers: - static_configs: - targets: [localhost:9093] # Alertmanager的地址在Alertmanager里配置通知路由如P1告警发到SlackP0告警发到PagerDuty。结论性能监控与告警系统不是有了就好而是准确率要高疲劳度要低。独立开发者不需要像大厂那样搭建复杂的可观测性平台用几百个Dashboard和几千条告警规则但至少需要L1基础监控用Prometheus Grafana、L2应用性能监控用Sentry、以及一两条最核心的业务指标告警如日注册量为0。这三项加起来能拦住95%的线上事故。
性能监控与告警系统实战:从0到可观测性的完整技术路线
性能监控与告警系统实战从0到可观测性的完整技术路线性能监控的三个核心层次独立开发者的产品有了真实用户后系统还活着吗就不应该是靠用户投诉来发现的。你需要一套性能监控与告警系统。我把它分为三个层次对应不同的工程成熟度和产品规模L1基础监控Infrastructure Monitoring服务器的CPU、内存、磁盘、网络。数据库的连接数、查询性能。以及应用进程是否还运行。这是让系统在用户投诉之前就被修复的基础。L2应用性能监控Application Performance Monitoring, APM不只是系统还活着而是系统运行得怎么样。API响应时间、错误率、数据库慢查询、外部API调用延迟。这是在用户体验恶化之前发现问题的关键。L3业务指标监控Business Metrics Monitoring系统和应用都健康但业务还健康吗。新用户注册量突然下降、付费转化率突然降低、核心功能的使用率突然下滑。这是在业务出问题之前发现趋势的核心。L1实战Prometheus Grafana的基础监控搭建为什么选Prometheus Grafana这两个工具的组合是开源监控领域的事实标准。Prometheus负责采集和存储指标Grafana负责可视化指标和配置告警。核心概念指标Metric一个可时间序列化的测量值。如cpu_usage_percent、memory_usage_bytes、http_requests_total。采集ScrapingPrometheus定期如每15秒从配置的采集目标Targets拉取指标数据。存储StoragePrometheus用自研的时序数据库TSDB存储指标数据。默认保留15天可配置。实战搭建以监控一个Node.js应用为例第一步让应用暴露指标给Prometheus用prom-client库Node.js生态最流行的Prometheus客户端库// metrics.ts import client from prom-client; // 创建一个Registry指标注册表 const register new client.Registry(); // 1. 默认的系统指标如CPU、内存、事件循环延迟 client.collectDefaultMetrics({ register }); // 2. 自定义指标HTTP请求_duration直方图 const httpRequestDuration new client.Histogram({ name: http_request_duration_seconds, help: Duration of HTTP requests in seconds, labelNames: [method, route, status_code], buckets: [0.1, 0.5, 1, 2, 5] // 响应时间的分桶 }); register.registerMetric(httpRequestDuration); // 3. 写一个/metrics端点返回Prometheus格式的指标 app.get(/metrics, async (req, res) { try { const metrics await register.metrics(); res.set(Content-Type, register.contentType); res.send(metrics); } catch (error) { res.status(500).end(error); } }); // 4. 在中间件里记录每个请求的响应时间 app.use((req, res, next) { const startTime Date.now(); res.on(finish, () { const duration (Date.now() - startTime) / 1000; httpRequestDuration .labels(req.method, req.route?.path || req.path, res.statusCode.toString()) .observe(duration); }); next(); });第二步配置Prometheus来采集这个/metrics端点创建prometheus.yml配置文件global: scrape_interval: 15s # 每15秒采集一次 scrape_configs: - job_name: my-nodejs-app static_configs: - targets: [localhost:3000] # 你的应用的地址运行Prometheus用Dockerdocker run -d \ --nameprometheus \ -p 9090:9090 \ -v $(pwd)/prometheus.yml:/etc/prometheus/prometheus.yml \ prom/prometheus现在访问http://localhost:9090在Graph页面里输入rate(http_request_duration_seconds_count[5m])就能看到过去5分钟内每秒HTTP请求数的变化。第三步用Grafana可视化这些指标运行Grafana用Dockerdocker run -d \ --namegrafana \ -p 3000:3000 \ grafana/grafana访问http://localhost:3000默认用户名/密码admin/admin。在Grafana里添加Prometheus作为数据源Data Source。导入现成的Node.js应用监控仪表盘Grafana官网有社区贡献的仪表盘JSON可以直接导入。L2实战用Sentry做应用性能监控APMPrometheus Grafana擅长监控系统级指标CPU、内存、请求率。但应用内部发生了什么——哪个SQL查询最慢哪个外部API调用延迟最高用户的一次请求在服务器端花了多长时间——这些需要专门的APM工具。为什么选Sentry它也提供APM功能我已经用Sentry做错误追踪前面文章写过。Sentry从2023年开始也提供了Performance模块——自动追踪应用性能且和错误追踪深度集成这个慢请求有没有关联的错误。核心概念分布式追踪Distributed Tracing现代应用通常不是一个函数处理一个请求。一个请求可能经过负载均衡器 → API服务器 → 数据库 → 外部API如Claude API。分布式追踪给每个请求分配一个唯一的trace_id然后在请求经过的每个服务里记录这个服务花了多长时间处理这叫一个span。最后把这些span在时间轴上连起来就能看到用户请求 → 数据库查询50ms→ AI API调用2000ms→ 返回响应的完整时间线。在Node.js应用里启用Sentry Performance// sentry.ts import * as Sentry from sentry/node; import { Elysium } from sentry/tracing; Sentry.init({ dsn: your-sentry-dsn, environment: process.env.NODE_ENV, tracesSampleRate: 1.0, // 采集100%的请求生产环境可以降到0.1-0.2 integrations: [ new Elysium({ additionalOptions: { trackLayers: true } }), ], }); // 在应用入口处初始化 app.use(Sentry.Handlers.requestHandler()); app.use(Sentry.Handlers.tracingHandler()); // 在应用出口处错误处理之前 app.use(Sentry.Handlers.errorHandler()); app.use(Sentry.Handlers.tracingHandler());启用后Sentry会自动追踪每个HTTP请求的响应时间每个数据库查询的执行时间如果用的是受支持的ORM如Prisma、TypeORM每个外部HTTP调用的耗时如fetch()或axios在Sentry后台查看Performance登录Sentry后台进入Performance页面。你会看到一个Transaction Summary事务摘要列表。每个Transaction对应一个被追踪的操作如一个HTTP请求、一个数据库查询。点击一个慢事务可以看到它的Trace Details追踪详情——一个时间轴展示这个事务所包含的所有span如POST /api/generate → prisma.query → fetch(https://api.anthropic.com)。实战价值找到性能瓶颈2024年8月我通过Sentry Performance发现我的产品的AI生成功能平均响应时间是8秒。但AI API的调用本身只需要5秒。那剩下的3秒花在哪里了查看追踪详情后发现在调用AI API之前我的代码做了一次检查用户订阅状态的数据库查询但这个查询没有加索引导致每次都全表扫描300ms。给这个字段加上索引后查询时间降到了5ms。总响应时间从8秒降到了5.5秒。L3实战业务指标监控的技术实现业务指标如每日新注册用户数、付费转化率通常不是技术指标而是产品指标。但它们对产品的健康度同样重要甚至更重要。为什么不能直接用Google AnalyticsGoogle AnalyticsGA是做网站流量分析的利器。但它有两个局限它追踪的是前端事件如页面浏览、按钮点击。后端发生的业务事件如用户订阅了Pro计划很难用GA准确追踪。它的数据更新有延迟通常24-48小时。你不能在GA里实时看到过去1小时的注册量。我的方案把业务指标存在PostgreSQL里用Grafana做实时仪表盘。第一步设计业务指标的数据表-- 每日指标汇总表用PostgreSQL的物化视图或定时任务填充 CREATE TABLE daily_business_metrics ( id SERIAL PRIMARY KEY, date DATE NOT NULL, new_registrations INTEGER DEFAULT 0, pro_subscriptions INTEGER DEFAULT 0, churn_count INTEGER DEFAULT 0, active_users INTEGER DEFAULT 0, created_at TIMESTAMP DEFAULT NOW() ); -- 可以每天凌晨用定时任务Cron Job计算并插入前一天的指标第二步用Node.js定时任务填充这个表// cron/update-daily-metrics.ts import cron from node-cron; import prisma from prisma/client; const prisma new PrismaClient(); // 每天凌晨2点执行 cron.schedule(0 2 * * *, async () { const yesterday new Date(); yesterday.setDate(yesterday.getDate() - 1); const dateStr yesterday.toISOString().split(T)[0]; // 计算昨天的指标 const newRegistrations await prisma.user.count({ where: { createdAt: { gte: new Date(${dateStr}T00:00:00Z), lt: new Date(${dateStr}T23:59:59Z) } } }); const proSubscriptions await prisma.subscription.count({ where: { plan: PRO, status: ACTIVE, createdAt: { gte: new Date(${dateStr}T00:00:00Z), lt: new Date(${dateStr}T23:59:59Z) } } }); // ... 计算其他指标 // 插入或更新 await prisma.dailyBusinessMetrics.upsert({ where: { date: yesterday }, update: { newRegistrations, proSubscriptions }, create: { date: yesterday, newRegistrations, proSubscriptions } }); });第三步在Grafana里添加PostgreSQL作为数据源并创建仪表盘在Grafana里添加PostgreSQL数据源填数据库地址、用户名、密码。创建一个新的Dashboard添加一个Time series面板。在查询编辑器里写SQLSELECT date, new_registrations, pro_subscriptions FROM daily_business_metrics ORDER BY date;Grafana会自动把结果渲染成时间序列图。现在我可以在一个仪表盘里同时看到系统指标CPU、内存、请求率→ 来自Prometheus应用性能指标响应时间、错误率、慢查询→ 来自Sentry业务指标注册量、付费转化、留存率→ 来自PostgreSQL告警配置从邮件轰炸到精准通知监控系统搭好了但如果每次CPU超过10%就发一封告警邮件你会在3天内关掉所有告警。这就是告警疲劳Alert Fatigue。我的告警分级策略P0致命立即通知生产环境API完全不可用如负载均衡器返回502超过5分钟数据库连接完全断开支付系统故障通知方式电话 SMS SlackP1严重15分钟内通知API错误率超过5%持续10分钟服务器内存使用率超过90%核心业务指标如日注册量日环比下跌超过30%通知方式Slack 邮件P2需关注每日汇总非核心功能的错误服务器磁盘使用率超过80%业务指标周环比轻微波动通知方式每日汇总邮件在Prometheus Alertmanager里配置告警规则创建alerts.ymlgroups: - name: app_alerts rules: # P1告警API错误率超过5% - alert: HighApiErrorRate expr: rate(http_requests_total{status_code~5..}[5m]) / rate(http_requests_total[5m]) 0.05 for: 10m # 持续10分钟才触发避免短暂波动 labels: severity: P1 annotations: summary: API错误率超过5% description: 当前错误率{{ $value | humanizePercentage }} # P1告警内存使用率超过90% - alert: HighMemoryUsage expr: (1 - (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes)) 0.9 for: 10m labels: severity: P1 annotations: summary: 服务器内存使用率超过90%然后在prometheus.yml里配置Alertmanager的地址alerting: alertmanagers: - static_configs: - targets: [localhost:9093] # Alertmanager的地址在Alertmanager里配置通知路由如P1告警发到SlackP0告警发到PagerDuty。结论性能监控与告警系统不是有了就好而是准确率要高疲劳度要低。独立开发者不需要像大厂那样搭建复杂的可观测性平台用几百个Dashboard和几千条告警规则但至少需要L1基础监控用Prometheus Grafana、L2应用性能监控用Sentry、以及一两条最核心的业务指标告警如日注册量为0。这三项加起来能拦住95%的线上事故。