关于go-zero服务自动收集问题分析

 更新时间:2022年12月14日 16:16:25   作者:Mikaelemmmm  
这篇文章主要介绍了关于go-zero服务自动收集问题,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

前言

​ 对于pprof,相信熟悉go语言的程序员基本都不陌生,一般线上的问题都是靠它可以快速定位。但是实际项目中,很多时候我们为了性能都不会开启它,但是出了问题又要靠它来分析。好在go-zero已经帮我们很好的集成进来了,我们只需要像开关一样去开启、关闭它即可,这样我们就可以配合运维监控,当出现cpu、内存等异常情况时候,自动开始开启收集,比如大半夜你睡的正香的时候,那么第二天可以通过分析当时的采样还原现场,那我们看看go-zero是如何做的。

源码分析

​ 我们可以看go-zero源码位置 https://github.com/zeromicro/go-zero/blob/master/core/proc/signals.go

func init() {
	go func() {
		......
		signals := make(chan os.Signal, 1)
		signal.Notify(signals, syscall.SIGUSR1, syscall.SIGUSR2, syscall.SIGTERM)
		for {
			v := <-signals
			switch v {
			....
			case syscall.SIGUSR2:
				if profiler == nil {
					profiler = StartProfile()
				} else {
					profiler.Stop()
					profiler = nil
				}
		.......
		}
	}()
}

服务启动的时候,go-zero在init初始化了监听信号操作(gracefulStop也是通过这里通知的,这里不展开讲了),可以看到在接收到 syscall.SIGUSR2 信号时候,如果是第一次就开始收集,第二次就停止收集,看到这块可能瞬间就明白了,我们只需要在服务器执行 “kill -usr2 [服务进程id]” 就可以开始收集这个服务的pprof信息了,在执行一次就停止了收集,就可以将这些文件导出到本地,使用go tool pprof分析。

一次线上实战

我们线上有一个mq的服务监控告警,内存占用比较高,这时候我打开grafna看到服务内存累计占用的确异常,如下图:

这时候到线上找到这个服务的服务器,执行了ps aux | grep xxx_mq ,查询到了这个mq服务的进程ID 21181,我们这时候就可以给这个xxx_mq服务发送信号收集pprof信息 “kill -usr2 21181”

第一次执行了这个命令后,在对应服务的access.log日志中可以看到enable了pprof,当我们再次执行 “ kill -usr2 21181” access.log日志中可以看到disable了pprof信息,这时候代表收集完成了。值得注意的是收集的信息都在/tmp文件夹下,以这个服务名命名的如下:

  • xxxx-mq-cpu-xxx.pprof
  • xxxx-mq-memory-xxx.pprof
  • xxxx-mq-mutex-xxx.pprof
  • xxxx-mq-block-xxx.pprof

这时候就可以下载对应的pprof去本地分析,可以使用go tool pprof xxxx-mq-memory-xxx.pprof,也可以配合graphviz使用web ui查看,由于我这边通过命令行就快速定位了问题,就没用使用web ui。

我使用go tool pprof xxxx-**-mq-memory-xxx.pprof 然后进入命令行交互,使用top 30查看前面占用较高的资源

前面基本是底层序列化等操作,发现主要问题集中在红色框中导致持续上涨的内存,因为业务同学在mq中消费完了消息又向下游其他的mq服务使用publisher发送一个mq消息,每次发送都调用一个NewPublisher然后在defer close,恰恰这个mq服务又大量消息消费又特别频繁,导致内存不断上涨,最终解决方案将NewPublisher在svcCtx中初始化一个client就可以了,没必要每次都要NewPublisher,世界又恢复清净了。

写在最后

想一下go-zero给了我们pprof开关,让我们很方便的实现分析问题,但是不是所有问题都是一直存在的,比如半夜突发内存、cpu过高,早上起来服务正常了,这怎么排查?所以我们希望如果异常了,能保留问题现场,那我们是不是可以配合运维监控实现自动保存问题现场呢?比如内存、cpu连续超过80%指标3分钟的话,我们就调用这个开关收集,之后我们就可以根据这个文件来分析问题了,这样就达到自动化了。

项目地址

go-zero微服务框架:https://github.com/zeromicro/go-zero

go-zero微服务最佳实践项目:https://github.com/Mikaelemmmm/go-zero-looklook

到此这篇关于关于go-zero服务自动收集问题分析的文章就介绍到这了,更多相关go-zero服务自动收集内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 深入了解Golang网络编程Net包的使用

    深入了解Golang网络编程Net包的使用

    net包主要是增加 context 控制,封装了一些不同的连接类型以及DNS 查找等等,同时在有需要的地方引入 goroutine 提高处理效率。本文主要和大家分享下在Go中网络编程的实现,需要的可以参考一下
    2022-07-07
  • Go语言中嵌入式缓存库的用法详解

    Go语言中嵌入式缓存库的用法详解

    Go 语言中有一些非常高效的嵌入式缓存库,groupcache 和 bigcache 是两个非常流行且高性能的库,本文将详细介绍一下二者的用法,有需要的小伙伴可以参考下
    2025-01-01
  • Go语言封装MinIO相关操作详解

    Go语言封装MinIO相关操作详解

    MinIO 是一个高性能的对象存储服务,兼容 Amazon S3 API,广泛用于存储和管理海量数据,本文将介绍如何用 Go 语言封装一个简单的 MinIO 操作包,需要的可以参考下
    2024-11-11
  • Go语言实现JSON解析的方法详解

    Go语言实现JSON解析的方法详解

    在日常项目中,使用Json格式进行数据封装是比较常见的操作。本文将详细讲解如何利用Go语言实现JSON的解析,感兴趣的小伙伴可以学习一下
    2022-04-04
  • Go语言reflect.TypeOf()和reflect.Type通过反射获取类型信息

    Go语言reflect.TypeOf()和reflect.Type通过反射获取类型信息

    这篇文章主要介绍了Go语言reflect.TypeOf()和reflect.Type通过反射获取类型信息,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-04-04
  • 利用go语言判断是否是完全二叉树

    利用go语言判断是否是完全二叉树

    这篇文章主要介绍了利用go语言判断是否是完全二叉树,当一个节点存在右子节点但是不存在左子节点这颗树视为非完全二叉树,通过利用GO语言判断来判断出否是完全二叉树,详细内容参考如下
    2022-05-05
  • go语言文件正则表达式搜索功能示例

    go语言文件正则表达式搜索功能示例

    这篇文章主要介绍了go语言文件正则表达式搜索功能,涉及Go语言文件目录的遍历及正则操作相关技巧,需要的朋友可以参考下
    2017-01-01
  • Golang Gin框架实现多种数据格式返回结果详解

    Golang Gin框架实现多种数据格式返回结果详解

    这篇文章主要介绍了Golang Gin框架实现多种数据格式返回结果,我们都知道,一个完整的请求包含请求和处理请求以及结果返回三个步骤,在服务器端对请求处理完成以后,会将结果返回给客户端,在gin框架中,支持返回多种请求数据格式,下面我们一起来看看
    2023-05-05
  • 详解Go函数和方法之间有什么区别

    详解Go函数和方法之间有什么区别

    这篇文章就简单和大家聊一聊在Go中函数与方法之间的区别,文章通过代码示例介绍的非常详细,对我们的学习或工作有一定的帮助,感兴趣的小伙伴跟着小编一起来看看吧
    2023-07-07
  • 详解Go语言Sync.Pool为何不加锁也能够实现线程安全

    详解Go语言Sync.Pool为何不加锁也能够实现线程安全

    在这篇文章中,我们将剖析sync.Pool内部实现中,介绍了sync.Pool比较巧妙的内部设计思路以及其实现方式。在这个过程中,也间接介绍了为何不加锁也能够实现线程安全,感兴趣的可以学习一下
    2023-04-04

最新评论