golang使用pprof检查goroutine泄露
有一段时间,我们的推送服务socket占用非常不正常,我们自己统计的同一时候在线就10w的用户,可是占用的socket居然达到30w,然后查看goroutine的数量,发现已经60w+。
每一个用户占用一个socket,而一个socket,有read和write两个goroutine,简化的代码例如以下:
c, _ := listerner.Accept()
go c.run()
func (c *conn) run() {
go c.onWrite()
c.onRead()
}
func (c *conn) onRead() {
stat.AddConnCount(1)
//on something
stat.AddConnCount(-1)
//clear
//notify onWrite to quit
}
当时我就怀疑,用户同一时候在线的统计是正确的,也就是之后的clear阶段出现了问题,导致两个goroutine都无法正常结束。在检查代码之后,我们发现了一个可疑的地方,由于我们不光有自己的统计,还会将一些统计信息发送到我们公司的统计平台,代码例如以下:
ch = make([]byte, 100000)
func send(msg []byte) {
ch <- msg
}
//在还有一个goroutine的地方,
msg <- msg
httpsend(msg)
我们channel的缓存分配了10w,假设公司统计平台出现了问题,可能会导致channel堵塞。但究竟是不是这个原因呢?
幸运的是,我们先前已经在代码里面内置了pprof的功能,通过pprof goroutine的信息,发现大量的goroutine的当前执行函数在httpsend里面,也就是说,公司的统计平台在大并发以下服务不可用,尽管我们有http超时的处理,可是由于发送的数据量太频繁,导致总体堵塞。
暂时的解决的方法就是关闭了统计信息的发送,兴许我们会考虑将其发送到自己的mq上面,尽管也可能会出现mq服务不可用的问题,可是说句实话,比起自己实现的mq,公司的统计平台更让我不可信。
这同一时候也给了我一个教训,訪问外部服务一定要好优点理外部服务不可用的情况,即使可用,也要考虑压力问题。
对于pprof怎样查看了goroutine的问题,能够通过一个简单的样例说明:
package main
import (
"net/http"
"runtime/pprof"
)
var quit chan struct{} = make(chan struct{})
func f() {
<-quit
}
func handler(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "text/plain")
p := pprof.Lookup("goroutine")
p.WriteTo(w, 1)
}
func main() {
for i := 0; i < 10000; i++ {
go f()
}
http.HandleFunc("/", handler)
http.ListenAndServe(":11181", nil)
}
这上面的样例中,我们启动了10000个goroutine,并堵塞,然后通过訪问http://localhost:11181/,我们就能够得到整个goroutine的信息,仅列出关键信息:
goroutine profile: total 10004
10000 @ 0x186f6 0x616b 0x6298 0x2033 0x188c0
# 0x2033 main.f+0x33 /Users/siddontang/test/pprof.go:11
能够看到,在main.f这个函数中,有10000个goroutine正在运行,符合我们的预期。
在go里面,还有非常多执行时查看机制,能够非常方便的帮我们定位程序问题,不得不赞一下。
golang使用pprof检查goroutine泄露的更多相关文章
- 如何让xcode自动检查内存泄露
在project-setting中找到 “Run Static Analyzer” 键,然后把值修改为“YES”.这样在编码的时候,xcode就可以自动为我们检查内存泄露了. 原图片:http://b ...
- iOS-如何让xcode自动检查内存泄露
在project-setting中找到 “Run Static Analyzer” 键,然后把值修改为“YES”.这样在编码的时候,xcode就可以自动为我们检查内存泄露了.
- pprof 查看goroutine
package main import ( "net/http" "runtime/pprof" ) var quit chan struct{} = make ...
- Go 笔记之如何防止 goroutine 泄露
今天来简单谈谈,Go 如何防止 goroutine 泄露. 概述 Go 的并发模型与其他语言不同,虽说它简化了并发程序的开发难度,但如果不了解使用方法,常常会遇到 goroutine 泄露的问题.虽然 ...
- Golang使用pprof和qcachegrind进行性能监控
Golang为我们提供了非常方便的性能测试工具pprof,使用pprof可以非常方便地对Go程序的运行效率进行监测.本文讲述如何使用pprof对Go程序进行性能测试,并使用qcachegrind查看性 ...
- golang 使用pprof和go-torch做性能分析
软件开发过程中,项目上线并不是终点.上线后,还要对程序的取样分析运行情况,并重构现有的功能,让程序执行更高效更稳写. golang的工具包内自带pprof功能,使找出程序中占内存和CPU较多的部分功能 ...
- Golang(三)Goroutine原理
前言 最近用到了一些 Golang 异步编程的地方,感觉 Golang 相对于其他语言(如 Java)对多线程编程的支持非常大,使用起来也非常方便.于是决定了解一下 Goroutine 的底层原理. ...
- 在Blade中结合gperftools检查内存泄露
Blade是我们开发的大规模C++项目构建工具. gperftools是google开发的性能工具,由高效内存分配器,CPU性能分析器,堆分析器,堆检查器等工具组成. 和其他构建工具不同,结合gtes ...
- [Go] golang原子函数实现goroutine同步
启动了两个goroutine,并完成一些工作.在各自循环的每次迭代之后,在goroutine 会使用LoadInt64 来检查shutdown 变量的值.这个函数会安全地返回shutdown 变量的一 ...
随机推荐
- oracle scn浅析
1. 系统SCN号 查询系统SCN号的方法: select dbms_flashback.get_system_change_number from dual commit后系统SCN号会增长,但是即 ...
- QTP的基本功能介绍
• QTP的基本功能介绍 HP QuickTest Professional 支持功能測试和回归測试自己主动化,用于每一个主要软件应用程序和环境.此解决方式使用keyword驱动的測试概念,简化了測试 ...
- RelativeLayout的属性详解
1. android:layout_below="@+id/first" //在某元素的的下方: android:layout_alignBottom="@+id/fir ...
- 快速傅里叶变换应用之二 hdu 4609 3-idiots
快速傅里叶变化有不同的应用场景,hdu4609就比较有意思.题目要求是给n个线段,随机从中选取三个,组成三角形的概率. 初始实在没发现这个怎么和FFT联系起来,后来看了下别人的题解才突然想起来:组合计 ...
- Java进阶03 IO基础
链接地址:http://www.cnblogs.com/vamei/archive/2013/04/11/3000905.html 作者:Vamei 出处:http://www.cnblogs.com ...
- redis 消息队列(发布订阅)、持久化(RDB、AOF)、集群(cluster)
一:订阅: 192.168.10.205:6379> SUBSCRIBE test Reading messages... (press Ctrl-C to quit) 1) "sub ...
- 常用字符串string
字符串 特性: 不可变性 当一个字符串赋新值时,老值依旧在(靠GC来回收) 可以看做是char类型的只读数组 eg:string str="abcd"; str[0]---> ...
- [Android] 更改关联的源码路径
右击选中工程 → Java Build Path → Libraries → Android 4.1.2 → 点开android.jar → 选中Source attachment → Edit,即可 ...
- tomcat下部署activemq(转)
转自:http://marshal.easymorse.com/archives/1414 activemq可以单独部署和执行,比如类似ActiveMQ的最简单应用中提到的安装和执行方式.但是有时候需 ...
- [置顶] 浅谈Android的资源编译过程
Android APK 一.APK的结构以及生成 APK是Android Package的缩写,即Android application package文件或Android安装包.每个要安装到Andr ...