容器环境下 go 服务性能诊断方案设计与实现

背景

业务上量以后,对程序进行 profiling 性能诊断对很多后端程序员来说就是家常便饭。一个趁手的工具往往能让这个事情做起来事半功倍。

在这方面,go 有着天然的优势:继承 Google’s pprof C++ profiler 的衣钵,从出生就有 go tool pprof 工具。并且,标准库里面提供 runtime/pprof 和 net/http/pprof 两个package, 使得 profiling 可编程化。

在非容器环境下,我们的研发同学喜欢使用 net/http/pprof 来提供http接口供 go tool pprof 工具进行 profiling:

1import _ "net/http/pprof"
2func main(){
3    ...
4    go func() {
5        log.Println(http.ListenAndServe("localhost:6060", nil))
6    }()
7    ...
8}

获取 CPU profile 数据:

1go tool pprof http://localhost:6060/debug/pprof/profile

但是,当架构逐步演进为微服务架构并使用k8s等容器化技术进行部署以后,这种这种方式面临的问题也越来越多:

1、我们生产环境使用k8s进行容器编排和部署。service类型是 NodePort. 因此研发同学无法直接对某个 service 的特定 pod 进行 profiling. 之前的解决方式是:

(1)如果要诊断的问题是这个service普遍存在的问题,则直接进行 profiling。

(2)如果要诊断的问题只出现在这个service的某个特定的pod上,则由运维同学定位到该pod所处的宿主机后登录到该容器中进行profiling。耗时耗力,效率低。

2、架构微服务化以后,服务数量呈量级增加。以前那种出现问题再去诊断服务现场的方式越来越难满足频率和数量越来越多的profiling需求(很多情况下,我们才做好profiling的准备,问题可能已经过去了……)。我们迫切的需要一种能够在程序出问题时,自动对程序进行profiling的方案,最大可能获取程序现场数据。

3、同时,我们希望这种自动profiling机制对程序性能影响尽可能小,并且可以与现有告警系统集成,直接将诊断结果通知到程序的owner.

方案设计与实现

1、我们使用 heapster 对k8s的容器集群进行监控。并将监控到的时序数据写入influxDB进行持久化。

2、gopprof 是我们容器环境下对其他 go 服务进行性能诊断的核心服务:

(1)通过对influxDB中的监控数据分析,对于异常的pod自动进行 profiling. 当前设置的策略是如果该pod在两个1分钟分析周期内,资源使用率都超过设定的阈值0.8,则触发profiling。

(2)将 gopprof 作为一个服务部署在k8s集群中主要是使其可以通过内网IP直接访问pod的 http profile接口,已实现对特定pod的profiling:

1go tool pprof http://POD_LAN_IP:NodePort/debug/pprof/profile

(3)gopprof 完成profiling后,会自动生成 profile svg 调用关系图,并将profile 数据和调用关系图上传云存储,并向服务的owner推送诊断结果通知:

(4)由于 gopprof 依赖工具 go tool pprofgraphivz, 因此gopprof的基础镜像需要预装这两个工具。参考Dockerfile

 1# base image contains golang env and graphivz
 2FROM ubuntu:16.04
 3MAINTAINER Daniel liudan@codoon.com
 4RUN apt-get update
 5RUN apt-get install wget -y
 6RUN wget -O go.tar.gz https://dl.google.com/go/go1.9.2.linux-amd64.tar.gz && \
 7    tar -C /usr/local -xzf go.tar.gz && \
 8    rm go.tar.gz
 9ENV PATH=$PATH:/usr/local/go/bin
10RUN go version
11RUN apt-get install graphviz -y

(5)gopprof 向研发同学提供了对特定pod以及特定一组pod进行手动profiling的的接口。在解放运维同学生产力的同时,也让研发同学在出现难以复现的问题时,能够有更大可能性获取到程序现场。

(6)在高可用方面,当前只支持部署一个 gopprof pod, 服务可用性依赖于k8s的的auto restart. 后期如果有这方面的需求,可能会修改为依赖于etcd支持多个gopprof pod部署。

小结

gopprof 服务已经在我们内部落地试运行了一段时间,整个上达到了我们的设计预期,并辅助我们发现和解决了一些之前没有意识到的性能问题。由于有一些内部代码依赖,暂时还无法开源出来。但是整个方案所依赖的组件都是通用的,因此你也可以很容易的实现这个方案。如果你对我们实现中的一些细节感兴趣,欢迎评论和留言。

版权申明:内容来源网络,版权归原创者所有。除非无法确认,我们都会标明作者及出处,如有侵权烦请告知,我们会立即删除并表示歉意。谢谢。

原文发布于微信公众号 - Golang语言社区(Golangweb)

原文发表时间:2018-05-27

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏安恒信息

云环境下Web应用防护解决之道

  随着越来越多的用户将传统的业务系统迁移至虚拟化环境或者一些云服务商提供的云平台中,而目前众多云平台企业关注的更多是基础实施的完善和业务的开展,对于安全层面的...

5687
来自专栏aoho求索

云原生概述

1. 什么是云原生 1.1 CNCF组织 在讲云原生之前,我们先了解一下CNCF,即云原生计算基金会,2015年由谷歌牵头成立,基金会成员目前已有一百多企业与机...

4268
来自专栏IT大咖说

向Kubernetes容器云平台迁移,你必须知道的9件事

内容来源:2017 年 11 月 25 日,当当网数字业务事业部技术总监李志伟在“Kubernetes Meetup | 北京站”进行《Kubernetes容器...

2403
来自专栏DevOps时代的专栏

如何落地全球最大 Kubernetes 生产集群

JDOS 就是京东数据中心操作系统,随着数据中心规模不断的扩大,我们需要对数据中心做综合的考虑。所以一开始就先说数据中心的层面,大家知道数据中心里面有服务器、网...

2062
来自专栏云端漫步

基于gitlab ci构建devops平台

devops的概念很多,理解也很多。我的理解,它属于软件工程范畴。它定义了一种理念,基于这种理念,能够快速的开发,交付软件及成果物。各个团队直接在这个体系中,高...

9293
来自专栏沃趣科技

翻过那座山,就能看见海|kubernetes让DBA更优雅地管理数据库

标题中的DBA其实包含两层含义:Database Architect 与 Database Administrator,我在这里都简称DBA了。

6138
来自专栏携程技术中心

干货 | 携程容器云实践

作者简介 吴毅挺,携程系统研发部高级总监。2012年加入携程,从零组建携程云平台团队,目前负责携程私有云、虚拟桌面云、网站应用持续交付等研发。 一、在线旅游与弹...

6368
来自专栏信安之路

你在github上泄漏的密码改了吗

大家作为安全爱好者或者从业者,大部分也是一个程序员,既然是程序员就离不开写代码,写代码就离不开 github,用 github 就喜欢在上面公开分享一些自己写的...

1480
来自专栏企鹅号快讯

分布式科学计算与Docker

在科学计算领域,早些年的程序语言基本都是C/C++或者FORTRAN的天下,因为科学计算本身非常耗时,选择一门运行速度比较快的语言能大大的节约数据计算时间。但是...

28810
来自专栏企鹅号快讯

微信小程序更新新能力:四大功能让小程序更火爆!一起来了解更新吧,快来学习吧

“ 小程序升级实时音视频录制及播放能力,开放 Wi-Fi、NFC(HCE) 等硬件连接功能。同时提供按需加载、自定义组件和更多访问层级等新特性,增强了第三方平台...

2117

扫码关注云+社区

领取腾讯云代金券