最近在用golang写一个server。压力测试过程发现反应比较慢,但是由于中间的操作都是串行的,无法知道在哪个操作消耗了比较多时间。
一开始想到的是打log。但是单个请求又是很快的,于是想到如下方案
在调用每个函数的时候,统计该函数的时耗,然后利用channel把同一个函数调用发送到同一个地方,利用map进行累计统计(这里可以更近一步,比如统计每个worker甚至每个services的状态,包括最长请求时间,最短请求时间,平均消耗等等,如果加上runtime还可以记录其他的运行相关信息)。
一开始在思考是否有一个类似c++的static变量的东西,好在golang的闭包就支持有状态的行为,而且比static更进一步,闭包的每次调用都能得到一个新的局部变量实体,所以,并发的时耗,在不同的地方,调用就可以得到不同的结果。
直接上代码。
func preReportStatus(funcName string) func(reportType int, input chan<- *RequestProf) {
var startTime = time.Now()
var reportFunc = funcName
a := func(reportType int, input chan<- *RequestProf) {
consumeTime := int64(time.Now().Sub(startTime) / 1000)
requestProf := &RequestProf{
apiName: reportFunc,
consumeTime: consumeTime,
invokeTimes: 1,
successCount: 0,
errorCount: 0,
}
if reportType == kSuccess {
requestProf.successCount = 1
} else {
requestProf.errorCount = 1
}
input <- requestProf
}
return a
}
var requestProfChan = make(chan *RequestProf,500)
var requestProfMap = make(map[string]*RequestProf)
func funcA() error {
report := preReportStatus("funcA")
err := funcB()
if err != nil {
report(kFail, requestProfChan)
return errors.New("funcA error.")
}
report(kSuccess, requestProfChan)
return nil
}
原文:http://www.cnblogs.com/weijiaen/p/3970466.html