共计 4430 个字符,预计需要花费 12 分钟才能阅读完成。
文|Junlong Liu
Shopee Digital Purchase & Local Services Engineering
本文 1743 字 浏览 6 分钟
贡献者前言
我是在开发工作过程中理解到 Holmes 的,为了保障系统稳定性须要一个性能排查工具,因而也须要一个保留现场的性能监控工具。当我在网上查问该方面的开源库时,发现可用的并不多。后续找到 MOSN 社区的 Holmes,发现这个开源库性能根本齐全、扩展性也高,特地是 GCHeapDump 这个业界当先的性能,对解决内存升高的问题非常有用。
2021 年年末理解到的 Holmes 组件,而后开始理解 Holmes 所在的 MOSN 社区。Holmes 作为性能排查工具,外围性能是及时发现性能指标异样,并对系统进行 Profiling。
因为 Holmes 还处于萌芽期,除了 Readme 之外的文档资料并不多。还有一些 Holmes 过后不反对的性能,比方动静配置调整与上报。Holmes 过后也还没公布第一个版本,然而本人对这方面也有趣味和了解,于是在 GitHub 上提了几个 Issue 探讨,社区回复的速度非常快。后续在社区前辈们的领导下提了 PR,也因而通过 Holmes 的代码设计学习到了很多对于开源组件的设计理念。
因而我决定参加开源社区并奉献代码,以解决理论需要。有了肯定的理解和教训之后,通过和人德前辈探讨,总结这样一篇分享文章。
本文将介绍 Holmes 的应用场景、疾速开始案例、多个监控类型、设计原理、扩大性能与如何借助 Holmes 搭建起一套简略的性能排查零碎,欢送大家留言领导。
Holmes 应用场景
对于零碎的性能尖刺问题,咱们通常应用 Go 官网内置的 pprof 包进行剖析,然而难点是对于一闪而过的“尖刺”,开发人员很难及时保留现场:当你收到告警信息,从被窝中爬起来,关上电脑链接 VPN,零碎说不定都曾经重启三四趟了。
MOSN 社区的 Holmes 是一个基于 Golang 实现的轻量级性能监控零碎,当利用的性能指标产生了异样稳定时,Holmes 会在第一工夫保留现场,让你第二天下班能够一边从容地喝着枸杞茶,一边追究问题的根因。
Quick Start
应用 Holmes 的形式非常简略,只须要在您的零碎初始化逻辑内增加以下代码:
// 配置规定
h, _ := holmes.New(holmes.WithCollectInterval("5s"), // 指标采集工夫距离
holmes.WithDumpPath("/tmp"), // profile 保留门路
holmes.WithCPUDump(10, 25, 80, 2 * time.Minute), // 配置 CPU 的性能监控规定
holmes.WithMemDump(30, 25, 80, 2 * time.Minute),// 配置 Heap Memory 性能监控规定
holmes.WithGCHeapDump(10, 20, 40, 2 * time.Minute), // 配置基于 GC 周期的 Heap Memory 性能监控规定
holmes.WithGoroutineDump(500, 25, 20000, 100*1000, 2 * time.Minute), // 配置 Goroutine 数量的监控规定
)
// enable all
h.EnableCPUDump().
EnableGoroutineDump().
EnableMemDump().
EnableGCHeapDump().Start()
相似于 holmes.WithGoroutineDump(min, diff, abs,max,2 * time.Minute) 的 API 含意为:
当 Goroutine 指标满足以下条件时,将会触发 Dump 操作。
当 Goroutine 数大于 Max 时,Holmes 会跳过本次 Dump 操作,因为当 Goroutine 数过大时,Goroutine Dump 操作老本很高。
2 * time.Minute 是两次 Dump 操作之间最小工夫距离,防止频繁 Profiling 对性能产生的影响。
更多应用案例见文末的 Holmes 应用案例文档。
Profile Types
Holmes 反对以下五种 Profile 类型,用户能够按需配置。
Mem: 内存调配
CPU: CPU 使用率
Thread: 线程数
Goroutine: 协程数
GCHeap: 基于 GC 周期监控的内存调配
指标采集
Mem、CPU、Thread、Goroutine 这四种类型是依据用户配置的 CollectInterval,每隔一段时间采集一次利用以后的性能指标,而 gcHeap 时基于 GC 周期采集性能指标。
本大节会剖析一下两种指标。
依据 CollectInterval 周期采集
Holmes 每隔一段时间采集利用各项指标,并应用一个固定大小的循环链表来存储它们。
依据 GC 周期采集
在一些场景下,咱们无奈通过定时的 memory dump 保留到现场。比方利用在一个 CollectInterval 周期内调配了大量内存,又疾速回收了它们。此时 Holmes 在周期前后的采集到内存使用率没有产生过大稳定,与理论状况不符。
为了解决这种状况,Holmes 开发了基于 GC 周期的 Profile 类型,它会在堆内存使用率飙高的前后两个 GC 周期内各 Dump 一次 Profile,而后开发人员能够应用 pprof –base 命令去比照两个时刻堆内存之间的差别。
依据 GC 周期采集到的数据也会放在循环列表中。
规定判断
本大节介绍 Holmes 是如何依据规定判断零碎出现异常的。
阈值含意
每个 Profile 都能够配置 min、diff、abs、coolDown 四个指标,含意如下:
以后指标小于 min 时,不视为异样。
以后指标大于 (100+diff)100% 历史指标,阐明零碎此时产生了稳定,视为异样。
以后指标大于 abs (绝对值)时,视为异样。
CPU 和 Goroutine 这两个 Profile 类型提供 Max 参数配置,基于以下思考:
CPU 的 Profiling 操作大概会有 5% 的性能损耗,所以当在 CPU 过高时,不该当进行 Profiling 操作,否则会拖垮零碎。
当 Goroutine 数过大时,Goroutine Dump 操作老本很高,会进行 STW 操作,从而拖垮零碎。(详情见文末参考文章)
Warming up
当 Holmes 启动时,会依据 CollectInterval 周期采集十次各项指标,在这期间内采集到的指标只会存入循环链表中,不会进行规定判断。
扩大性能
除了根本的监控之外,Holmes 还提供了一些扩大性能:
事件上报
您能够通过实现 Reporter 来实现以下性能:
发送告警信息,当 Holmes 触发 Dump 操作时。
将 Profiles 上传到其余中央,以防实例被销毁,从而导致 Profile 失落,或进行剖析。
type ReporterImpl struct{}
func (r *ReporterImple) Report(pType string, buf []byte, reason string, eventID string) error{// do something}
......
r := &ReporterImpl{} // a implement of holmes.ProfileReporter Interface.
h, _ := holmes.New(holmes.WithProfileReporter(reporter),
holmes.WithDumpPath("/tmp"),
holmes.WithLogger(holmes.NewFileLog("/tmp/holmes.log", mlog.INFO)),
holmes.WithBinaryDump(),
holmes.WithMemoryLimit(100*1024*1024), // 100MB
holmes.WithGCHeapDump(10, 20, 40, time.Minute),
)
动静配置
您能够通过 Set 办法在利用运行时更新 Holmes 的配置。它的应用非常简略,和初始化时的 New 办法一样。
有些配置时不反对动静更改的,比方 Core 数。如果在零碎运行期间更改这个参数,会导致 CPU 使用率产生微小稳定,从而触发 Dump 操作。
h.Set(WithCollectInterval("2s"),
WithGoroutineDump(10, 10, 50, 90, time.Minute))
落地案例
利用 Holmes 的 Set 办法,能够轻松地对接本人公司的配置核心,比方,将 Holmes 作为数据面,配置核心作为管制面。并对接告警零碎 (邮件 / 短信等) 搭建一套简略的监控零碎。
具体架构如下:
Holmes V1.0 版本公布
本文简略地介绍了 Holmes 的应用办法与原理。心愿 Holmes 能在您进步利用的稳定性时帮忙到你。
Holmes V1.0 在几周前正式公布了,作为贡献者和使用者,我非常举荐大家试用这个玲珑的工具库,有任何问题和疑难欢送大家来社区发问~
Holmes 是 MOSN 社区开源的 GO 语言 Continous Profiling 组件,能够主动发现 CPU、Memory、Goroutine 等资源的异样,并主动 Dump 异样现场 Profile,用于预先剖析定位。也反对上传 Profile 到主动剖析平台,实现主动问题诊断、报警。
「公布报告」:https://github.com/mosn/holmes/releases/tag/v1.0.0
「Holmes 原理介绍」:https://mosn.io/blog/posts/mosn-holmes-design/
本文简略地介绍了 Holmes 的应用办法与原理。心愿 Holmes 能在您进步利用的稳定性时帮忙到你。
「参考资料」
[1]《Holmes 文档》https://github.com/mosn/holmes
[2]《无人值守的主动 dump(一)》https://xargin.com/autodumper-for-go/
[3]《无人值守的主动 dump(二)》https://xargin.com/autodumper-for-go-ii/
[4]《go 语言 pprof heap profile 实现机制》https://uncledou.site/2022/go-pprof-heap/
[5]《goroutines pprofiling STW》https://github.com/golang/go/issues/33250
[6]《Holmes 应用案例文档》https://github.com/mosn/holmes/tree/master/example
[7]《go pprof 性能损耗》https://medium.com/google-cloud/continuous-profiling-of-go-programs-96d4416af77b
本周举荐浏览
邀请函|SOFA 周围年,开源正过后!
Nydus 镜像减速插件迁入 Containerd 旗下
异构注册核心机制在中国工商银行的摸索实际
SOFAArk Committer 专访|看它不爽,就间接入手改!