13-ysyThread-Prometheus 与 Grafana 配置
Prometheus 与 Grafana 配置Prometheus 介绍1. 什么是 Prometheus?Prometheus 是一个开源的系统监控和告警工具包 2. 特性 Prometheus 的主要特性包括: 一个多维数据模型,其中时间序列数据由指标名称和键/值对标识 PromQL,一种灵活的查询语言,用于利用这种多维性 不依赖分布式存储;单个服务器节点是自主的 时间序列收集通过 HTTP 上的拉取模型进行 通过中间网关支持推送时间序列 通过服务发现或静态配置发现目标 支持多种图形和仪表盘模式 3. 什么是指标(Metric)?指标在通俗意义上是数值测量,术语“时间序列”是指随时间记录的变化。用户希望测量的内容因应用程序而异。 对于 Web 服务器,可能是请求时间; 对于数据库,可能是活动连接数或活动查询数等等。 4. 架构 Prometheus 从 已埋点的作业中抓取指标,可以直接抓取,也可以通过中间推送网关抓取短生命周期作业的指标。它将所有抓取的样本 存储在本地,并根据这些数据运行规则,以聚合并记录现有数据中的新时间序列或生成告警。Grafana...
12-ysyThread-Micrometer监控的原理与误区
Micrometer监控的原理与误区Metrics 注册原理1. 基于首次注册对象引用获取指标先来看看这行代码的实际作用: 1Metrics.gauge(metricName("xxx"), tags, runtimeInfo, ThreadPoolRuntimeInfo::getXxx); 这行代码背后的执行逻辑是这样的: 如果这个 metric(包括名字 + tag)是第一次注册 ,Micrometer 会绑定 runtimeInfo 对象的引用 如果 metric 已经注册过了,这次调用不会更新引用 ,只是返回已存在的 Gauge(Micrometer 内部维护了一个缓存结构) 因此,即使后续你传入了新的 runtimeInfo 对象,但这个新对象并不会被绑定,Micrometer 仍然会读取最初绑定的老对象的引用值 第一次传入的runtimeInfo1被绑定后,之后无论你传入runtimeInfo2、3、4,Micrometer都会忽略,只会继续读取runtimeInfo1的字段值 2. 注册的 Metric...
11-ysyThread-动态线程池监控
动态线程池监控 仅靠“事发时的告警”远远不够。没有监控,开发人员排查问题只能靠猜,做性能调优也没底 所以强调,线程池监控不是只为了报警,它更重要的价值在于 辅助定位问题 :出故障时,能看到是线程数打满了,还是队列堆积了 支持容量规划 :通过长期趋势判断线程池配置是否合理 洞察系统瓶颈 :比如是否存在某些任务执行时间异常拉长,影响整体调度效率 本地日志监控实现1. 定时任务调度机制本地日志监控的核心是定时任务调度机制 2. 本地日志输出实现本地日志监控的实现相对简单,但需要确保 日志格式的规范性和可读性: 12345private void logMonitor(ThreadPoolRuntimeInfo runtimeInfo) { log.info("[ThreadPool Monitor] {} | Content: {}", runtimeInfo.getThreadPoolId(), ...
10-ysyThread-告警频率限制方法
告警频率限制方法前言当系统出现异常时,往往会在短时间内产生 大量重复告警,形成所谓的”告警风暴“。这不仅会对开发人员造成信息过载,还可能导致真正重要的告警被淹没在噪音中 为了解决这个问题,需要设计一套实用的告警限流机制 ,既要保证重要告警能够及时送达,又要避免无意义的重复通知 告警风暴问题分析在线程池监控场景中,告警风暴通常出现在以下情况: 队列积压告警 :当任务提交速度超过处理能力时,队列长度持续增长,可能每秒触发多次告警 拒绝策略告警 :线程池达到最大容量后,每个被拒绝的任务都可能触发一次告警 线程数异常告警 :活跃线程数超过阈值时,监控系统可能频繁发送通知 告警风暴会带来以下负面影响: 信息过载 :运维人员被大量重复信息淹没,难以快速定位问题 资源浪费 :频繁的网络请求消耗系统资源,影响正常业务 告警疲劳 :过多无效告警导致运维人员对告警系统失去信任 成本增加 :第三方通知服务(如钉钉、企业微信)按调用次数收费 解决方案核心思想是:在保证告警时效性的前提下,通过时间窗口限流算法控制同类型告警的发送频率 具体策略包括: 按线程池 ID 和告警类型进行分组...
9-ysyThread-阈值触发告警规则
阈值触发告警规则告警规则告警策略如下所示: 维度 触发条件 检测含义 活跃度 activeCount / maximumPoolSize 连续高于阈值(默认 80%) 线程资源已逼近瓶颈,需扩容或对入口流量做限流 队列负载 queueSize / queueCapacity 超过阈值 排队任务激增,处理能力被入口流量压制,易引发大面积超时 拒绝异常 监控到新的 RejectedExecutionException 线程池已无法接收新任务,属于阻断场景,应立刻介入 实现告警检查器1. 告警定时检查线程池状态监控通常采用定时任务方式进行,以延迟换取业务稳定性。此类定时检查无需引入额外框架,JDK 提供的 ScheduledExecutorService 已能满足稳定的调度需求 ThreadPoolAlarmChecker 利用一个单线程的调度器,定期扫描系统中所有已注册线程池的运行状态,并针对启用了告警的线程池执行各类运行指标检测,及时触发相关告警处理 2. 活跃度告警123456789101112131415161718192021/** *...
8-ysyThread-阻塞队列容量热更新
阻塞队列容量热更新业务说明什么是阻塞队列?在 Java 中它由接口 BlockingQueue 定义,虽然名称看起来抽象,底层实现却十分灵活,可以基于 数组,也可以使用 单向 或 双向链表 等结构 与普通队列相比,阻塞队列多了两项关键能力: 阻塞插入 :当队列已满时,执行 put 的线程会被挂起,直到出现空位 阻塞移除 :当队列为空时,执行 take 的线程同样会被挂起,直到有元素可取 如何实现阻塞队列热更新?1. 阻塞队列不支持更新容量在日常线程池调优过程中,我们可能会遇到一个真实的问题: 队列被塞满了,线程池也跑满了,但我又不能轻易重启服务,只是想把队列容量调大点,临时抗一波压力,有没有办法? 如果使用的是 LinkedBlockingQueue,可能会发现它的容量是固定的,根本不支持动态调整 12/** The capacity bound, or Integer.MAX_VALUE if none */ private final int capacity; 2....






