【基于 Swoole+Hyperf 的微服务实战】第十周 · 周四: 完善监控:Prometheus 采集秒杀指标,Grafana 实时大屏 【基于 SwooleHyperf 的微服务实战】第十周 · 周四 完善监控Prometheus 采集秒杀指标Grafana 实时大屏今天我们进入第十周周四主题是完善监控Prometheus 采集秒杀指标Grafana 实时大屏。前面压测已经证明系统能抗住高并发但生产环境需要实时掌握秒杀活动的各项数据请求量、成功率、库存消耗速度、异常事件等以便快速响应。今天将为秒杀业务定制 Prometheus 指标并在 Grafana 中构建实时大屏让整个团队都能看清系统健康状态成为“作战指挥室”。今日目标在秒杀接口中埋入自定义 Prometheus 指标Counter、Gauge、Histogram记录秒杀请求总数、成功/失败数、库存剩余量。配置 Prometheus 抓取订单服务的/metrics端点验证指标正确暴露。在 Grafana 中创建秒杀活动监控仪表盘实时显示 QPS、成功率、库存消耗速度、P99 延迟。设置库存低位预警当 Redis 秒杀库存低于阈值时Grafana 面板变色告警。将仪表盘设置为全屏自动刷新模式模拟“大屏”效果。一、环境准备约 20 分钟确保 Prometheus、Grafana、订单服务含秒杀接口均已运行。docker-composeup-d进入订单服务容器docker-composeexecorder-servicebash# 假设容器名 order-servicecd/var/www/order确认hyperf/metric已安装之前已用于 HTTP 通用指标。如果没有请安装composerrequire hyperf/metric php bin/hyperf.php vendor:publish hyperf/metric二、知识核心自定义业务指标与 Grafana 大屏约 1 小时1. Prometheus 指标类型回顾Counter只增不减适合统计请求总数、错误数。每次增加固定值如 1。Gauge可增可减适合统计当前值如剩余库存、当前并发数。Histogram统计数据分布自动生成分位数适合统计请求延迟、响应大小。对于秒杀场景我们需要seckill_requests_totalCounter秒杀请求总量可按状态标签区分success、fail、error。seckill_stock_remainingGauge当前 Redis 剩余秒杀库存定期采集或每次更新后设置。seckill_request_duration_secondsHistogram秒杀接口处理耗时分布。2. 如何在 Hyperf 中暴露自定义指标hyperf/metric提供了Hyperf\Metric\MetricFactoryInterface通过它注册指标。在应用启动或请求处理时获取指标对象并操作。我们可以在秒杀控制器中注入工厂每次请求时增加 Counter 并观察 Histogram同时在扣减库存后更新 Gauge。3. Grafana 大屏设计要点实时性设置面板自动刷新间隔如 5 秒并固定时间范围为最近 5 分钟。可视化组件Stat显示总请求数、成功率、当前库存。Time seriesQPS 曲线、库存消耗曲线。Gauge库存百分比。Table最近错误日志可通过 Prometheus 指标标签展示或结合 Loki/ES。告警联动库存低于 10% 时面板变红并可触发 AlertManager 通知。三、实战秒杀指标埋点与 Grafana 大屏约 2.5 小时步骤 1在订单服务中注册自定义指标创建app/Metric/SeckillMetrics.php或直接在ConfigProvider中注册更推荐使用工厂模式。我们将指标定义为类的静态属性或通过工厂创建。新建app/Metric/SeckillMetric.php?phpnamespaceApp\Metric;useHyperf\Metric\MetricFactoryInterface;useHyperf\Di\Annotation\Inject;classSeckillMetric{#[Inject]privateMetricFactoryInterface$factory;publicfunction__construct(){// 注册指标在首次实例化时创建$this-factory-makeCounter(seckill_requests_total,count,[status])-with(status,success);// 初始化标签后续可动态设置$this-factory-makeCounter(seckill_requests_total,count,[status])-with(status,fail);$this-factory-makeGauge(seckill_stock_remaining,stock);$this-factory-makeHistogram(seckill_request_duration_seconds,[handler]);}publicfunctionincRequest(string$status):void{$counter$this-factory-makeCounter(seckill_requests_total,[status]);$counter-with(status,$status)-add(1);}publicfunctionsetStock(int$productId,int$remaining):void{$gauge$this-factory-makeGauge(seckill_stock_remaining,[product_id]);$gauge-with(product_id,(string)$productId)-set($remaining);}publicfunctionrecordDuration(float$seconds,string$handler):void{$histogram$this-factory-makeHistogram(seckill_request_duration_seconds,[handler]);$histogram-with(handler,$handler)-observe($seconds);}}注意MetricFactoryInterface创建的指标是单例多次调用makeCounter同名指标会返回同一对象带标签时需使用with指定标签值。步骤 2在秒杀控制器中埋点修改app/Controller/SeckillController.php注入SeckillMetric在关键路径记录指标。useApp\Metric\SeckillMetric;#[Inject]privateSeckillMetric$metric;publicfunctionbuy(){$startmicrotime(true);$productId(int)$this-request-input(product_id);$userId$this-request-getAttribute(user_id,0);$statussuccess;// ... 锁逻辑略// Lua 扣减$script...;$result$this-redis-eval($script,[seckill:stock:.$productId],1);if(!$result){$statusfail;$this-metric-incRequest(fail);$durationmicrotime(true)-$start;$this-metric-recordDuration($duration,buy);// 仍然需要更新库存 Gauge$stock(int)$this-redis-get(seckill:stock:.$productId);$this-metric-setStock($productId,$stock);return[code0,message已抢光];}// 成功$this-metric-incRequest(success);$stock(int)$this-redis-get(seckill:stock:.$productId);$this-metric-setStock($productId,$stock);$durationmicrotime(true)-$start;$this-metric-recordDuration($duration,buy);// 发送异步消息...// 返回}库存 Gauge 更新策略除了在秒杀接口中更新还可以通过定时任务每 10 秒从 Redis 读取一次库存并设置 Gauge这样即使没有请求大屏也能看到最新库存。创建app/Cron/StockGaugeCron.php或使用 Swoole Timer// 在启动时添加定时器useSwoole\Timer;useHyperf\Metric\MetricFactoryInterface;// 在 OnWorkerStart 中Timer::tick(10000,function()use($factory){$redis...;$stock$redis-get(seckill:stock:1)?:0;$gauge$factory-makeGauge(seckill_stock_remaining,[product_id]);$gauge-with(product_id,1)-set((int)$stock);});为简化可在控制器中每次请求时更新即可。步骤 3验证指标暴露启动订单服务访问http://localhost:9507/metrics订单服务 HTTP 端口搜索seckill应看到类似# HELP seckill_requests_total ... # TYPE seckill_requests_total counter seckill_requests_total{statussuccess} 1023 seckill_requests_total{statusfail} 452 # HELP seckill_stock_remaining ... # TYPE seckill_stock_remaining gauge seckill_stock_remaining{product_id1} 89577确认 Prometheus 能抓取在prometheus.yml中添加order-service:9507的 job。步骤 4在 Grafana 中搭建秒杀大屏登录 Grafana (http://localhost:3000)新建 Dashboard。面板 1秒杀 QPSQuery:rate(seckill_requests_total[1m])Legend:{{status}}类型时间序列面板 2成功率Query:sum(rate(seckill_requests_total{statussuccess}[1m])) / sum(rate(seckill_requests_total[1m])) * 100类型Stat单位percent面板 3当前库存数字Query:seckill_stock_remaining{product_id1}类型Stat可添加阈值小于 1000 黄色小于 100 红色。面板 4库存消耗趋势Query:seckill_stock_remaining随时间下降类型时间序列面板 5P99 延迟Query:histogram_quantile(0.99, rate(seckill_request_duration_seconds_bucket[1m]))类型时间序列面板 6最近错误日志可选如果日志已入 ES可使用 Elasticsearch 数据源展示表格否则靠 Prometheus 的seckill_requests_total{statusfail}增量即可。设置刷新间隔为 5s全屏模式即为大屏。步骤 5库存低位告警在 Grafana 面板上创建告警规则条件seckill_stock_remaining 10或 1% 初始库存评估频率1m通知渠道之前配置的钉钉/邮件。Prometheus AlertManager 同理可在 Prometheus 中配置规则。步骤 6整合到总体监控仪表盘将新建的面板复制到已有的“Hyperf微服务监控”大屏中或者创建单独的“秒杀活动监控”文件夹方便展示。四、成果测试与演示约 1 小时1. 压测驱动指标生成使用昨天的wrk压测脚本对秒杀接口进行一段时间的施压观察 Grafana 大屏各面板变化QPS 曲线波动与压测工具一致。成功率随库存减少而变化。库存数字实时递减。2. 模拟库存耗尽继续压测直到库存归零Grafana 面板中库存变为 0成功率下降失败标签增加如果有库存告警应触发通知查看 AlertManager 或 Grafana 通知历史。3. 实时大屏演示设置 Grafana 全屏模式按钮在顶部自动刷新将浏览器投屏到大显示器模拟“作战中心”。4. 测试清单检验项方法通过标准自定义指标暴露访问/metrics搜索 seckill指标存在且值正确Prometheus 抓取Prometheus Targets 中订单服务 Up状态 UpGrafana 面板正确渲染打开 Dashboard所有面板有数据无 No data库存实时更新压测过程中库存数字递减数值连续变化告警触发库存低于阈值时Grafana 告警状态变为Alerting并发送通知收到通知全屏刷新全屏模式数据随压测动态刷新无延迟感五、今日作业与学习产出提交代码SeckillMetric类、修改后的秒杀控制器、定时器代码、Prometheus 配置、Grafana Dashboard JSON 导出。完善大屏添加用户维度监控如“正在秒杀的用户数”通过 RedisSCARD统计活跃用户 Set。集成Kibana 日志面板在 Grafana 中嵌入 Kibana iframe可查看错误日志。学习笔记列举秒杀活动中最重要的 5 个监控指标并说明其业务意义。解释 Prometheus Histogram 如何计算 P99为什么比平均值更关键。挑战任务使用Grafana Alerting的Dashboard快速创建告警并配置钉钉机器人通知研究webhook格式。为每个秒杀商品创建独立的库存仪表盘通过变量$product_id实现下拉切换。通过今天的学习你的秒杀系统具备了完整的可观测性大屏能够实时感知业务动态并为即将到来的项目复盘和演示提供了直观的数据支撑。明天我们将进行整个电商核心系统的最终复盘与文档编写。