设为首页 收藏本站
查看: 1046|回复: 0

[经验分享] golang系统性能监控初探

[复制链接]

尚未签到

发表于 2018-9-20 08:04:37 | 显示全部楼层 |阅读模式
  系统服务(这里不局限于golang写的后台服务,也包括c++,java等后台语言)需要考虑的两个问题
  1. 系统的资源使用情况(cpu利用率,内存分配情况等,runtime和syscall都提供了支持,这个是系统内部性质,往往是设计系统资源问题,需要在设计的时候慎重考虑)
  2. 系统的服务情况(就是服务时延,这个是client可以直接感知的,往往是client最关注的,决定了服务的qps)
  提前评估系统的资源消耗是很重要的,在公司里面,能提供选择的机器类型是很多种的。比如腾讯,往往动则上亿qq号的量,很多时候需要在内存中cache用户的实时信息,如果内存评估不对,后面如果要进行机器迁移,则比较麻烦。另外,cpu的数目太少,则并发性弱,影响服务的性能,特别是在一台机器上部署了多个服务后,抢cpu,抢内存的情况则格外严重,并且,如果把io密集程序跟cpu密集程序放到一起,io密集程序还可能会把耗内存的cpu程序给挤到swap中去导致服务出现间歇性的大量失败。
  我最近在用golang写一个server。压力测试过程却发现反应比较慢,但是由于设计的方案,中间的操作都是串行的,无法知道在哪个操作消耗了比较多时间。
  一开始想到的是打log。但是单个请求又是很快的,于是想到如下方案 (by 魏加恩 本文地址http://www.cnblogs.com/weijiaen/p/3970466.html)
  在调用每个函数的时候,统计该函数的时耗,然后利用channel把同一个函数调用发送到同一个地方,利用map进行累计统计(这里可以更近一步,比如统计每个worker甚至每个services的状态,包括最长请求时间,最短请求时间,平均消耗等等,如果加上runtime还可以记录其他的运行相关信息)。
  一开始在思考是否有一个类似c++的static变量的东西,好在golang的闭包就支持有状态的行为,而且比static更进一步,闭包的每次调用都能得到一个新的局部变量实体,所以,并发的时耗,在不同的地方,调用就可以得到不同的结果。
  直接上代码,关注点,系统资源利用统计,系统的服务时延统计,至于后续问题,比如何时log到文件等,以后有时间再补充进来。 
  

func preReportRusage(interval time.Duration) func(usage1 *syscall.Rusage, utilProf *SystemUtilProf) int {  
var lastUtime int64
  
var lastStime int64
  
var waitInterval time.Duration = interval
  

  
a := func(usage1 *syscall.Rusage, utilProf *SystemUtilProf) int {
  
if err := syscall.Getrusage(syscall.RUSAGE_SELF, usage1); err == nil {
  
utime := usage1.Utime.Sec*1000000000 + usage1.Utime.Usec
  
stime := usage1.Stime.Sec*1000000000 + usage1.Stime.Usec
  

  
utilProf.userCPUUtil = float64(utime-lastUtime) * 100 / float64(waitInterval) //用户cpu时间
  
utilProf.sysCPUUtil = float64(stime-lastStime) * 100 / float64(waitInterval)  //系统cpu时间
  
utilProf.memUtil = uint64(usage1.Maxrss * 1024)                               //系统内存使用情况
  
utilProf.memStats = runtime.MemStats{}
  

  
runtime.ReadMemStats(&utilProf.memStats)
  

  
lastUtime = utime
  
lastStime = stime
  

  
return kSuccess
  
} else {
  
return kFail
  
}
  
}
  

  
return a
  
}
  

  

  
func preReportStatus(funcName string) func(reportType int, input chan

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-598264-1-1.html 上篇帖子: 脱掉Golang的第一层衣裳 golang入坑系列 下篇帖子: Golang 处理 Json(二):解码
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表