PLG 可观测栈生产化:Prometheus/Loki/Grafana 上线前必须补的参数清单

PLG 能跑 ≠ 能生产,这 40 个参数决定它会不会炸 第 1 步:目标——别把"能跑"当成"能上线" 某开发者第一次搭 Prometheus + Loki + Grafana 的时候,docker-compose 一把梭,数据能出图、日志能搜到,觉得"这不就完了吗"。 直到有一天:磁盘写满、Loki 摄入速率爆了、Prometheus 查询超时、Grafana 裸奔在公网被扫——才意识到玩具和生产是两回事。 这篇把 PLG 生产化的参数和注意事项一次性讲透,分四块: 组件 生产化核心问题 Prometheus 数据存多久?查询会不会拖垮?挂了怎么办? Loki 日志会不会把磁盘写爆?摄入限额?标签会不会爆炸? Promtail 标签设计红线 + 采集可靠性 Grafana 认证、数据库、配置管理、备份 📌 定位:写给后端开发兼职运维的人——不追求架构极客,只求上线后别半夜被磁盘告警叫醒。 第 2 步:前置——先理解 PLG 各自的生产"命门" 四件套的生产风险完全不一样,先建立直觉: flowchart LR APP["应用/主机"] -->|"指标 scrape"| P["Prometheus时序数据库"] APP -->|"日志 push"| PT["Promtail日志采集"] PT -->|"HTTP push"| L["Loki日志存储"] P --> G["Grafana可视化"] L --> G classDef root fill:#0f172a,stroke:#3b82f6,stroke-width:2.5px,color:#bfdbfe,font-weight:bold; classDef process fill:#1e1e24,stroke:#6b7280,stroke-width:2px,color:#e5e7eb; classDef data fill:#052e16,stroke:#16a34a,stroke-width:2px,color:#bbf7d0,font-weight:bold; class APP root; class P,L data; class PT,G process; 组件 生产命门 典型事故 Prometheus 内存(TSDB 缓存)、磁盘(时序数据)、查询并发 OOM、磁盘写满、查询拖垮 Loki 磁盘(日志量)、摄入速率、流数量(标签基数) 磁盘爆、摄入拒绝、流爆炸 Promtail 标签设计、位置文件、网络缓冲 流爆炸、重启重采日志 Grafana 认证、数据库、配置漂移 裸奔被入侵、配置丢失 第 3 步:Prometheus 生产参数——存储、查询、高可用 3.1 数据保留期(默认 15 天,必须显式设置) # docker-compose 启动参数 prometheus: command: - '--storage.tsdb.retention.time=30d' # 按时间保留(推荐) - '--storage.tsdb.retention.size=50GB' # 按大小保留(和上面二选一或都用) 为什么:默认 15 天,生产一般要 30 ~ 90 天。但保留期越长磁盘越大——50GB 磁盘 + 30 天保留,要提前算好每台机器的指标量(一般每 target 每小时几百 KB,几十个 target 一天约 1 ~ 2GB)。 ...

十一月 12, 2023 · 5 分钟 · 904 字 · yaomingye

Prometheus 告警体系搭建:从 Alertmanager 到 AI ChatOps 一条龙

告警别只发通知,让 AI 替你干活 第 1 步:目标——从"看面板"到"手机响" 上一篇把 Prometheus + Grafana 搭起来,指标也采进来了。但有个问题:指标不会自己说话。 某开发者当时的状态是:白天盯着 Grafana 面板看 CPU 曲线,晚上睡觉心里发毛——万一凌晨 3 点服务挂了,谁叫我? 这篇文章的目标很直白: ❌ 旧世界:出问题 → 用户投诉 → 你爬起来开电脑 → SSH → 查日志 → 修复 ✅ 新世界:出问题 → 手机响 → 聊天框里说"查一下" → AI 排查完给你结论 具体拆成三个里程碑: 里程碑 内容 产出 ① 告警规则 Prometheus 检测 CPU/内存/磁盘异常 8 条可用的告警规则 ② Alertmanager 告警去重分组、统一出口 一个能收敛告警的中枢 ③ ChatOps 告警 → webhook → AI → Telegram 手机上收告警 + 动嘴指挥 📌 前置知识:假设你已经跑通了上一篇的 Prometheus + Grafana + node-exporter,知道 up 、 rate() 这些基本 PromQL。 ...

十一月 6, 2023 · 5 分钟 · 1062 字 · yaomingye

Dapper 模型:TraceId 与 SpanId 的传播之道

Dapper 模型 本文是分布式算法科普系列第七篇,也是收官之作。前面六篇从服务发现、共识、流控、事务、消息、负载均衡一路讲过来——现在整个分布式系统已经跑起来了。但最后一个问题:一个请求跨了十几个服务,慢了,到底是哪个服务慢了? 一、故事:Google 搜索到底慢在哪 2008 年前后,Google 的搜索基础设施已经是一个超级复杂的分布式系统——一个用户搜索请求从前端 Web 服务器进入后,要经过拼写检查、查询改写、广告检索、文档索引查询、图片搜索、个性化排序等几十个服务,每个服务又有数十到数百台机器。 问题来了——运维团队收到告警:“搜索延迟上涨了 200ms”。全链路跨了几十个服务,研发团队只能挨个翻日志、看监控、拍脑门猜测到底是哪个服务变慢了。运气不好的时候——一个延迟问题排查一天是常有的事,而且经验依赖极高——只有老员工大概知道"这种情况一般是索引服务慢了"。 2010 年,Google 发表了《Dapper, a Large-Scale Distributed Systems Tracing Infrastructure》技术报告,公布了他们内部从 2005 年就开始使用的分布式追踪系统。Dapper 的核心贡献不是工程实现,而是一个极其简洁的数据模型——用两个 ID 和一个父引用,就能还原出任意复杂度的调用链路。 这个模型后来成为所有现代分布式追踪系统的理论基础——Twitter 的 Zipkin(2012)、Uber 的 Jaeger(2017)、Apache SkyWalking(2015)、以及 OpenTelemetry 标准(2019),全部沿用了 Dapper 的 TraceId + SpanId 模型。 二、前置:没有追踪时,排查有多痛苦 先感受一下一个典型的微服务调用链: 用户点击"下单" → API Gateway(网关——接收HTTP请求) → OrderService(订单服务——创建订单) → InventoryService(库存服务——扣库存) → Redis(缓存——检查库存标记) → AccountService(账户服务——扣余额) → CouponService(优惠券服务——核销优惠券) → NotificationService(通知服务——发短信) 总共 7 个服务节点。如果用户反馈"下单等了 3 秒才成功"——研发需要翻 7 个服务的日志,靠时间戳手工对——“订单服务的这条日志是 14:03:52.123,库存服务好像对应的日志是 14:03:52.245……这两条是同一个请求吗?"——没人知道。 写过的都懂——凌晨三点被叫起来排查线上问题,对着七八个服务的日志靠 grep + 时间戳对,好不容易对出大概链路,发现只是 Redis 慢了一下。没有追踪系统的日子,就是这么过的。 ...

一月 24, 2023 · 3 分钟 · 538 字 · yaomingye

一个商城项目的结构化日志改造实录

结构化日志改造实录 第1步:目标说明 — 结构化日志到底解决什么问题 某开发者接手了一个 Spring Boot 商城项目的维护。项目跑得挺稳,直到某天凌晨收到告警——短信发送失败了,但翻遍日志找不到任何记录,因为 catch(Exception e) 的块是空的。 这就是非结构化日志的典型场景:日志看似写了,但关键信息全丢了。 结构化日志(Structured Logging)不是一门新技术,而是一种日志编写规范。它的核心目标只有一句话: 让日志既可以被人快速理解,也可以被机器(ELK、Loki、Splunk)精确检索。 本次教程通过一个真实商城项目的日志审计和改造过程,教会读者: 如何识别团队代码中的日志反模式 如何用 SLF4J 的参数化语法替代字符串拼接 如何配置 logback 实现 dev 控制台 + prod 文件持久化 的双环境策略 如何避免异常栈丢失、日志级别混乱等常见坑 完成本教程后,读者能独立完成一个 Spring Boot 项目的日志规范化改造。 第2步:前置条件 — 需要准备什么 开始之前,确保本地环境满足以下条件。 前置项 版本要求 说明 JDK 1.8+ Spring Boot 2.x 编译和运行 Spring Boot 2.x 自带 spring-boot-starter-logging(Logback + SLF4J) Lombok 1.18+ 提供 @Slf4j 注解,免去手写 Logger 声明 Maven 3.6+ 项目构建工具 验证命令: # 检查 JDK java -version # 检查 Maven mvn -version # 检查 Lombok 依赖(在 IDE 中确认 @Slf4j 可用) 📌 前置知识:读者需要了解 Java 异常体系的基本概念(checked / unchecked exception)、Spring Boot 项目的基本结构(Controller → Service → Mapper),以及日志级别 TRACE / DEBUG / INFO / WARN / ERROR 的含义。 ...

一月 10, 2023 · 11 分钟 · 2305 字 · yaomingye

SkyWalking 中间件集成与链路分析实战

SkyWalking 中间件集成 📖 前置阅读:本文假设读者已搭建 SkyWalking 并了解 Trace/Span/Segment 概念。如果还不熟悉,建议先阅读 SkyWalking 分布式链路追踪——从零搭建 APM 平台。 一、⚡ 全链路通了——但只有 HTTP 调用——Dubbo 和 gRPC 看不到 上一篇搭好了 SkyWalking——/api/orders 的调用链能看到了——HTTP → Feign → MySQL 都有。 但我们的系统不止 HTTP: 真实调用链路: Browser → Gateway → order-service ├─ Feign → user-service (HTTP) ✅ SkyWalking 自动追踪 ├─ Dubbo → account-service (RPC) ❌ 看不到——Dubbo Span 没出来 ├─ gRPC → inventory-service (RPC) ❌ 看不到——gRPC Span 没出来 ├─ Sentinel → 限流熔断 ❌ 看不到——被限流的请求没有标记 ├─ RocketMQ → payment-service (异步) ❌ 看不到——MQ 跨进程 Trace 断了 └─ @Async → sendEmail (异步) ❌ 看不到——异步线程 Trace 丢了 Agent 不是万能的——不同中间件需要不同配置——有些还需要手动埋点。 ...

十二月 20, 2022 · 15 分钟 · 3027 字 · yaomingye

SkyWalking 分布式链路追踪——从零搭建 APM 平台

SkyWalking 分布式链路追踪 📖 前置阅读:本文假设读者已了解微服务基本概念和 Docker。如果已搭建 Prometheus + Grafana,理解本文会更快——两者互补。建议先阅读 Prometheus + Grafana 环境搭建与指标采集。 一、⚡ QPS 正常——但用户说"下单很慢"——是哪个服务慢了? 前两篇搭好了 Prometheus + Grafana——指标面板很漂亮——QPS、RT、错误率一目了然。 但凌晨 3 点的告警是这样的: PagerDuty:order-service P99 延迟从 50ms 涨到 3s——错误率 2%——还没触发告警阈值(5%) 你打开 Grafana: ✅ order-service:QPS 正常——RT 涨了但不知道原因 ✅ user-service:所有指标正常——没问题 ✅ product-service:所有指标正常——没问题 ✅ inventory-service:所有指标正常——没问题 ✅ payment-service:所有指标正常——没问题 → 你盯着仪表盘——所有服务看起来都"还行"——但订单就是慢了 有了 SkyWalking 链路追踪: ① 找到那条慢了 3s 的 /api/orders 请求的完整调用链路 ② 看到调用链:order-service → user-service(50ms) → product-service(45ms) → inventory-service(2800ms!!!) ← 找到了 ③ 展开 inventory-service 的 Span——MySQL SELECT 语句执行了 2.5s ④ 点开 SQL——SELECT * FROM inventory WHERE product_id = ?——没有索引——全表扫描 → 2 分钟定位——加索引——P99 回到 50ms Prometheus 告诉你"出问题了"——SkyWalking 告诉你"为什么出问题"。两者不是替代关系——是互补关系: ...

十二月 19, 2022 · 11 分钟 · 2142 字 · yaomingye

所有中间件指标接入 Prometheus——统一仪表盘实战

所有中间件指标接入 Prometheus 📖 前置阅读:本文假设读者已掌握 Prometheus + Grafana 的基础搭建和 PromQL 语法。如果还不熟悉,建议先阅读 Prometheus + Grafana 环境搭建与指标采集。 一、⚡ 你有 6 种中间件——但你知道一个请求穿过它们时发生了什么吗? 一个请求穿过整个微服务体系要走多少中间件? 浏览器请求 GET /api/orders/100: ① Gateway 收到请求——鉴权、路由匹配 ② Gateway 转发到 order-service(OpenFeign 或 Dubbo) ③ order-service 调 user-service(OpenFeign) ④ order-service 调 product-service(Dubbo) ⑤ 所有服务都在 Nacos 中发现对方 ⑥ Sentinel 在整个过程中限流/熔断 这 6 步中——任何一步慢了——整个请求就慢了 没有统一监控时——你不知道是 Gateway 慢了、OpenFeign 慢了、还是 Dubbo 慢了 这篇的目标——把每种中间件的指标接入 Prometheus,在一张 Grafana 仪表盘上看到全貌。 二、🏗️ 搭建教程——完整的 Docker Compose + Prometheus 配置 上一篇讲了 Prometheus + Grafana 的基础搭建——但那只是两个容器。这篇要接入 6 种中间件——需要一个完整的 Docker Compose 把 Prometheus、Grafana 和所有微服务编排在一起。 ...

十二月 18, 2022 · 9 分钟 · 1867 字 · yaomingye

Prometheus + Grafana 环境搭建与指标采集

Prometheus + Grafana 环境搭建 一、⚡ 微服务上线了——但你知道它现在是死是活吗? 前面写了 6 种中间件、拆了 5 个微服务、配了限流熔断、布了集群——一切看起来很完美。 凌晨 3 点,电话响了:“用户说下单超时——你看一下”。你打开电脑——但你能看什么? 没有监控时: ① SSH 到服务器——tail -f 看日志——满屏 WARN——不知道哪个先出问题 ② 查数据库——慢查询一大堆——不知道是不是今天的查询就变慢了 ③ 调 JVM 看线程——200 个线程在 BLOCKED——不知道是哪个接口引起的 → 30 分钟过去了——你在猜问题在哪 有了 Prometheus + Grafana: ① 打开 Grafana 看板——QPS 正常——但 RT 从 50ms 涨到 3s ② 看 JVM 仪表盘——线程数飚到 500——GC 频繁 ③ 看中间件面板——Dubbo 线程池满了——Sentinel 开始熔断 → 2 分钟定位——是商品服务的 Dubbo 线程池被打满了 监控不是运维的事——是每个后端开发必须掌握的技能。 二、🧩 Prometheus 是什么——拉模型 + 时序数据库 + PromQL 2.1 Prometheus 的 pull model——和传统监控的区别 大多数监控系统是push model——应用主动把指标推给监控 server。Prometheus 是pull model——它定期去应用那里"拉"指标: ...

十二月 17, 2022 · 5 分钟 · 1061 字 · yaomingye

Spring Boot 日志

Spring Boot 日志:打点位置、框架选型与线上排查全解析 🐛 问题切入:一段没有日志的代码 下面是一个新手开发者写的 Spring Boot 订单服务: @RestController @RequestMapping("/order") public class OrderController { @Autowired private OrderService orderService; @PostMapping("/create") public Result<Order> createOrder(@RequestBody CreateOrderRequest req) { Order order = orderService.createOrder(req); return Result.success(order); } } @Service public class OrderService { @Autowired private OrderMapper orderMapper; @Autowired private InventoryService inventoryService; @Transactional public Order createOrder(CreateOrderRequest req) { // 扣减库存 boolean deducted = inventoryService.deduct(req.getProductId(), req.getQuantity()); if (!deducted) { throw new BusinessException("库存不足"); } // 创建订单 Order order = new Order(); order.setUserId(req.getUserId()); order.setAmount(req.getAmount()); orderMapper.insert(order); return order; } } 某天线上出现了一个问题:用户投诉"我付了钱但订单没创建成功"。后端同学打开服务器,面对空荡荡的日志文件(只有 Spring Boot 默认的启动 banner),完全不知道从哪里下手。 ...

九月 30, 2022 · 13 分钟 · 2638 字 · yaomingye
Cat Radio