ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

微服务日常巡检的检查顺序

微服务日常巡检的检查顺序 微服务日常巡检的检查顺序微服务巡检不是每天把所有指标看一遍。更有效的做法是先确认用户路径是否异常再沿入口、依赖、线程与连接池、JVM 和基础设施逐层缩小范围。顺序清楚值班人员才能知道下一步该看什么也能避免一看到 CPU 抖动就重启服务。巡检项要跟随系统风险和依赖变化维护。新接入消息队列、修改线程池、升级 JDK 或调整注册中心后对应检查也要更新一份多年不变的静态清单很快会与真实架构脱节。第一层先看用户请求和近期变更从关键入口的成功率、目标延迟和任务完成情况开始并按路由或业务类型分组。整体平均值正常可能仍有一个高价值接口持续失败。流量接近零时成功率也可能失真应同时看请求量和绝对错误数。把当前异常与最近发布、配置变更、依赖升级和流量变化放在同一时间轴。时间接近不等于根因已经确认但它能帮助确定优先排查范围。没有异常时日常报告也应标明当前版本和上次变更方便后来对比。健康检查只是一条信号。Liveness 回答进程是否需要重启Readiness 决定实例能否接流业务路径则验证关键功能。端口可访问不能证明线程池、数据库和注册状态正常反过来下游短时波动也不应触发所有实例的 Liveness 失败并反复重启。第二层检查依赖和流量放大查看上游到本服务、再到数据库、缓存、消息队列和其他 RPC 的调用关系。重点是超时、重试、连接等待和拒绝。入口流量没有变化、内部调用却明显增加可能出现重试放大或重复消费。依赖异常时先确认是所有实例都失败还是某个可用区、连接池或目标版本集中出错。DNS、证书和权限错误通常不会通过原样重试恢复连接中断或明确的临时错误才可能在预算内有限重试。巡检报告需要保留错误分类而不是统一写成“下游不稳定”。服务发现要同时看控制面与调用端实际视图。注册中心有实例不代表客户端缓存已经更新实例心跳正常也不代表业务处理能力正常。可以抽查注册版本、实例状态和一次真实路由结果但不要让巡检绕过正常负载均衡直接修改注册信息。第三层看线程池、连接池和队列Java 服务常见的“CPU 不高却很慢”往往与等待有关。检查业务线程池的 active、pool size、queue size 和 reject数据库连接池的 active、idle 与等待时间以及 HTTP 客户端的连接获取与进行中请求。每个指标都要带池名称不能把某个自定义executor.queued当成整个 Tomcat 或 WebFlux 的状态。队列长度必须结合处理速率。短时出现几个等待任务未必有问题持续增长且完成速率跟不上入口才说明无法收敛。无界队列不会显示“满”却会让内存和等待时间不断增长因此配置巡检还要确认队列类型与容量。连接池达到上限时不要立刻调大。先看连接为何长期占用、超时是否生效、下游是否变慢。扩大每个实例的池后再乘以副本数可能超过数据库或服务端能承受的总连接。第四层再进入 JVMJVM 巡检关注堆、非堆、GC 暂停、分配速率、线程和类加载但没有一条固定阈值适合所有服务。先建立当前 JDK、GC 和负载下的基线再看趋势与用户延迟是否同时变化。Metaspace 的max可能没有配置成有限值此时简单计算使用比例没有意义。更值得观察的是类加载数量、使用量是否在稳定流量下持续增长以及 Full GC 后能否回落。动态代理、脚本和频繁创建类加载器只是可能原因需要结合 Heap Dump、类加载统计和版本变更验证。GC 暂停也不能孤立解读。记录暂停分布、发生原因、堆占用和分配速率再与请求长尾对齐。偶发暂停不一定影响用户持续高分配导致频繁回收才需要继续定位。Heap Dump 与线程 Dump 可能包含业务数据应限制触发、访问和保留时间。Actuator 数据先由监控系统统一采集Spring Boot Actuator 与 Micrometer 可以暴露运行指标但具体名称、标签和可用性取决于版本与已注册组件。建立 Prometheus 等采集系统后日常巡检优先查询统一时序数据而不是额外脚本并发轮询每个 Pod。后者会制造新负载也难以保留趋势。小型环境确实需要只读脚本时要把“指标缺失”与“指标为零”分开并保护 Actuator 入口。下面的示例只检查健康状态不打印响应正文服务地址来自受控配置超时和并发都有限。它不能替代认证、TLS 和集中监控。from concurrent.futures import ThreadPoolExecutor, as_completed from dataclasses import dataclass from typing import Literal import requests dataclass(frozenTrue) class Service: name: str base_url: str dataclass(frozenTrue) class Result: service: str status: Literal[UP, DOWN, UNKNOWN] reason: str def inspect(service: Service) - Result: try: response requests.get( f{service.base_url}/actuator/health/readiness, timeout(1, 2), ) if response.status_code ! 200: return Result(service.name, DOWN, fhttp_{response.status_code}) payload response.json() status payload.get(status) if status UP: return Result(service.name, UP, readiness_up) return Result(service.name, DOWN, readiness_not_up) except (requests.RequestException, ValueError) as exc: return Result(service.name, UNKNOWN, type(exc).__name__) def inspect_all(services: list[Service]) - list[Result]: with ThreadPoolExecutor(max_workersmin(4, len(services))) as executor: futures [executor.submit(inspect, service) for service in services] return [future.result() for future in as_completed(futures)]UNKNOWN不能显示成绿色健康。网络、认证或响应格式问题都需要单独处理。脚本也不应自动重启实例先保留证据再由有权限和审计的处置流程决定动作。告警与日报处理不同时间尺度需要立即通知的是正在影响用户并且有人可以处理的状态例如关键路径持续失败、队列无法收敛或全部实例不可用。容量趋势、Metaspace 增长和依赖版本偏差更适合进入日报或工单。把所有异常都发成电话告警只会消耗值班注意力。去重不应仅按Service Metric。同一根因可能让几十个服务同时报警应按依赖或调用拓扑聚合同一指标在不同集群又可能是两起事件需要保留环境标签。静默规则设置开始、结束与负责人避免维护窗口结束后告警仍被永久压制。每条告警附上当前值、基线、持续时间、受影响路径和一条只读排查入口。若接收人无法根据内容决定继续观察、限流或升级就应重新设计这条告警。巡检本身也需要预算高频、昂贵的管理查询会影响被观察系统。健康接口保持轻量指标由拉取系统按容量采集日志查询限制时间和结果量。不要在业务高峰自动触发 Heap Dump也不要让巡检账号拥有修改配置或重启服务的权限。定期演练指标缺失、注册异常、线程池拒绝和下游超时确认告警能触发、说明足够、恢复条件明确。规则修改后先回放历史数据检查是否把已知波动重新变成噪声。一套可用的巡检顺序应该让值班人员从用户影响走到具体资源再回到变更和依赖证据。它不追求指标最多而是尽快回答现在是否影响用户问题在哪一层谁需要采取什么动作。
返回列表