最近在使用GraphQL编写golang程序,但GraphQL框架在golang上的实践比较少,很多性能上的资料也不够全面。考虑到线上抗压的问题,笔者决定对自己开发的服务模块进行性能压测,评估下服务的整体性能。测试的工具链使用Vegeta+PPof+go-torch,PProf、go-torch上一篇文章Golang工具链 已经总结过不再赘述,vegeta会简单讲解下。

工具-vegeta

Vegeta是一个用Go语言编写的多功能的HTTP负载测试工具,提供命令行工具和开发包。安装见vegeta 说明。

Usage: vegeta [global flags] <command> [command flags]global flags:-cpus int使用CUP的数量 (默认 4 个)-profile stringEnable profiling of [cpu, heap]-version打印版本并退出attack command:-body string请求的主体文件-cert stringTLS客户PEM编码的证书文件-connections int没个目标主机最大打开闲置链接数 (默认 10000)-duration duration持续攻击时间 [0 = forever]-header value请求头-insecure忽略无效的服务器TLS证书-keepalive使用持久链接 (default true)-key stringTLS客户端PEM编码的私钥文件-laddr value本地IP地址 (default 0.0.0.0)-lazy延迟懒散的读取目标-output string输出文件 (default "stdout")-rate uint每秒请求数 (default 50)-redirects int遵循重定向的次数. -1 不会遵循重定向但会标记为成功 (默认 10)-root-certs valueTLS根证书文件 (逗号分隔列表)-targets string目标文件 (default "stdin")-timeout duration请求超时时间 (default 30s)-workers uint初始化进程数 (default 10)report command:-inputs string输入文件 (comma separated) (default "stdin")-output string输出文件 (default "stdout")-reporter string表报字符格式 [text, json, plot, hist[buckets]] (default "text")text 文本格式json json格式plot 在 Dygraphs 上生成一个可以交互式的HTML5基础页面hist 计算并打印一个基于文本的直方图dump command:-dumper stringDumper [json, csv] (default "json") 指定转储格式-inputs stringInput files (comma separated) (default "stdin") 指定转储含有统计结果的输入文件,多个逗号分隔-output stringOutput file (default "stdout") 指定把转储文件写入到输出文件举例:echo "GET http://localhost/" | vegeta attack -duration=5s | tee results.bin | vegeta reportvegeta attack -targets=targets.txt > results.binvegeta report -inputs=results.bin -reporter=json > metrics.jsoncat results.bin | vegeta report -reporter=plot > plot.htmlcat results.bin | vegeta report -reporter="hist[0,100ms,200ms,300ms]"

注意

  • -targets 指定一行分隔文件中的攻击目标,格式如下:

    • 简单目标
    GET http://goku:9090/path/to/dragon?item=balls
    GET http://user:password@goku:9090/path/to
    HEAD http://goku:9090/path/to/success
    • 自定义请求头的目标
    GET http://user:password@goku:9090/path/to
    X-Account-ID: 8675309DELETE http://goku:9090/path/to/remove
    Confirmation-Token: 90215
    Authorization: Token DEADBEEF
    • 自定义请求的主体
    POST http://goku:9090/things
    @/path/to/newthing.jsonPATCH http://goku:9090/thing/71988591
    @/path/to/thing-71988591.json
    • 自定义请求头和请求主体
    POST http://goku:9090/things
    X-Account-ID: 99
    @/path/to/newthing.json
  • 进行负载测试时,不能因为Vegeta自身机器的性能瓶颈限制无法达到预期结果,例如打开的文件数、内存大小、CPU和网络带宽,分布式的使用Vegeta是非常好的解决方案。

    • 为了确保打开文件描述和进程限制设置得高一些,可以在机器上使用ulimit命令
    • 可以使用pdsh分布式运维工具,对目标执行分布式攻击。

程序性能分析过程

使用vegeta工具压测http服务接口

命令

  • echo "POST http://192.168.168.189:8181/graphql" | vegeta attack -body /tmp/rqst/rqst.txt -duration=10s -rate=400 > r.bin

    • http://192.168.168.189:8181/graphql执行post请求,post的body放置在/tmp/rqst/rqst.txt目录下,对目标地址进行持续10s的攻击,每次发送400个请求, 将请求的结果统计到r.bin文件。

    • rqst.txt的内容如下,此处对部署在远端GraphQL服务直接发送Post请求,请求的操作名称jobInfoList:

    {                                                                                                                                     "query":"query jobInfoList(  $projectId: String!){\n\tjobInfoList(projectId: $projectId) {\n    algorithmInfo {\n      algorithmId\n      descInfo\n      location\n      name\n      sourceFormat\n      status\n      targetFormat\n      version\n    }\n  }\n}",  "variables":{"projectId":"pr-testproject"},"operationName":"jobInfoList"
    }
    

结果

  • text格式

    /home# vegeta report -inputs=r.bin -reporter=text //查看text格式分析数据,默认为该格式,可不写
    Requests      [total, rate]            4000, 400.10
    Duration      [total, attack, wait]    10.0081328s, 9.997499937s, 10.632863ms
    Latencies     [mean, 50, 95, 99, max]  3.978566ms, 3.635816ms, 6.189994ms, 11.539779ms, 18.534089ms
    Bytes In      [total, mean]            148000, 37.00
    Bytes Out     [total, mean]            1380000, 345.00
    Success       [ratio]                  100.00%
    Status Codes  [code:count]             200:4000 
  • json格式

    /home# vegeta report -inputs=r.bin -reporter=json
    {
    "latencies:{"total":15914265193,"mean":3978566,"50th":3635816,"95th":6189994,"99th":11539779,"max":18534089},
    "bytes_in":{"total":148000,"mean":37},
    "bytes_out":{"total":1380000,"mean":345},
    "earliest":"2018-04-20T15:31:11.400851579+08:00","latest":"2018-04-20T15:31:21.398351516+08:00","end":"2018-04-20T15:31:21.408984379+08:00",
    "duration":9997499937,
    "wait":10632863,
    "requests":4000,
    "rate":400.10002752751205,
    "success":1,
    "status_codes":{"200":4000},
    "errors":null
    }

查看生成的pprof分析的可视化图片

pprof常用作cpu、内存分析,需要使用pprof的场景

  • 定位内存泄露
  • 程序效率瓶颈
  • 查看程序的调用图

下面这张图是CPU profile,可以清楚看到程序运行时的调用状态,主要分析各个方法的耗时。下图有些部分是虚线,是因为耗时比较少的节点没有在图上体现出来 ,但要把图连起来,有的地方就使用虚线了。

go-torch更直观的分析工具

上面的图在调用链比较简单的情况下,会比较直观,但在如此复杂的调用链下,确实看着有点乱,使用Uber开源的火焰图绝对让你打开新世界的大门。

命令
  • 执行命令go-torch -u http://192.168.168.189:8181 -t 10

  • 执行命令后bash展示如下内容:

    INFO[14:16:19] Run pprof command: go tool pprof -raw -seconds 10 http://192.168.168.189:8181/debug/pprof/profile
    INFO[14:16:30] Writing svg to torch.svg

火焰图展示

  • 下图为使用go-torch生成的火焰图,看起来比pprof分析的要更加直观一些。

    火焰图是具有互动性的:

    • 鼠标悬浮: 火焰的每一层都会标注函数名,鼠标悬浮时会显示完整的函数名、抽样抽中的次数、占据总抽样次数的百分比。

    • 点击放大:在某一层点击,火焰图会水平放大,该层会占据所有宽度,显示详细信息。

    • 搜索:按下Ctrl + F 会显示一个搜索框,可输入关键字或正则表达式,所有符合条件的函数名会高亮显示

总结

通过以上一系列分析,笔者定位到GraphQL的解析库对程序的性能造成了一定的影响,这边总结了几种解决方式:

  • 用grpc替代GraphQL
  • http的Client和Server之间使用长连接进行通信
  • 使用http2代替http1.1

参考资料

  • Go代码调优利器-火焰图
  • Golang服务的性能调优与问题定位

golang程序性能分析相关推荐

  1. Golang程序性能分析(三)用pprof分析gRPC服务的性能

    这是Golang程序性能分析系列文章的最后一篇,这次我们的主要内容是如何使用pprof工具对gRPC服务的程序性能进行分析.关于gRPC这个框架的文章之前已经写过不少文章了,如果你对它还不太熟悉,不知 ...

  2. Golang程序性能分析(二)在Echo和Gin框架中使用pprof

    前言 今天继续分享使用Go官方库pprof做性能分析相关的内容,上一篇文章:Golang程序性能分析(一)pprof和go-torch中我花了很大的篇幅介绍了如何使用pprof采集Go应用程序的性能指 ...

  3. Golang程序性能分析(一)pprof和go-torch

    前言 最近计划用三篇文章讲述一下Golang应用性能分析,本文是第一篇,先来介绍Go语言自带的性能分析库pprof怎么使用,后面两篇会讲解怎么用pprof对Echo或者Gin框架开发的应用进行性能分析 ...

  4. Go程序性能分析pprof

    from: Go程序性能分析pprof     参考: http://blog.golang.org/profiling-go-programs http://google-perftools.goo ...

  5. 程序性能分析及性能测试

    这里所说的程序是指对外提供tcp/ip交互协议的服务性程序.网络程序性能分析很重要,比如随着网络请求流量越来越大,我们需要知道已部署的服务能不能满足需求.这里采用对网络服务程序进行建模的方法分析影响程 ...

  6. linux java火焰图_Linux程序性能分析和火焰图

    Linux程序性能分析和火焰图 Linux程序的性能分析工具数量比较多,涉及到整个操作系统的方方面面,可能是开源的原因吧,相对于Windows来说丰富太多.其中应用分析性能方面Dtrace, Syst ...

  7. Go程序性能分析方法(一文全解)

    文章目录 前言 采集方式 命令模式 调度图 监控方式 go-torch方法 FlameGraph工具 wrk压测工具(go-wrk) go-torch使用 Metricbeat 监控 自定义方法 前言 ...

  8. 【程序性能分析利器】Google Perf Tool 和 Valgrind 工具包简介

    Google Perf Tools 的安装和使用 Gperf 工具包包含如下几个工具: 一个优化的内存管理算法-tcmalloc性能优于malloc. 一个用于CPU profile的工具,用于检测程 ...

  9. 【.NET程序性能分析】使用VS自带的工具分析.NET程序的性能

    这篇博文给大家分享的是,如何使用VS自带的性能分析工具来分析我们编写的.NET程序,一边找出程序性能的瓶颈,改善代码的质量.在实际开发中,性能真的很重要,往往决定一个产品的生死~良好的用户体验的基础之 ...

最新文章

  1. Theme.NoTitleBar问题
  2. 基于 flyweight 的格式化文本处理的 Boost.Flyweight 示例
  3. python request file upload_Python request 上传文件
  4. ios 自定义圆环进度条
  5. 18.TCP使用的注意事项
  6. 15.Linux 高性能服务器编程 --- 进程池和线程池
  7. tar.bz2 解压命令以及使用指令
  8. DDD中的“领域模型”
  9. word自动编号+二级标题随一级标题变化
  10. 如何解决移动硬盘弹出时报错:设备正在使用中
  11. golang map 获取某个值
  12. 基于jsp+mysql+java+ssm高校学生成绩管理系统——计算机毕业设计
  13. 电脑wps可以语音录入吗_怎样用word进行语音录入文字
  14. java ide的配置(idea)
  15. 对于CNN的文献阅读和识别手写数字的复现
  16. 金九银十北漂记第2篇:《Java程序员面试宝典》读书笔记
  17. 计算机网络实验感想6,计算机网络实验项目六
  18. 一牛网:MTK软件,硬件芯片资料集锦(datasheet,规格书,原理图,参考设计,SDK等)二
  19. 数据库系统工程师任职要求
  20. java单例模式的应用场景_单例模式的常见应用场景

热门文章

  1. H.266/VVC代码学习:DC模式和Planar模式
  2. 1号店注册页(共5页)
  3. VUE使用自定义指令对普通 DOM 元素进行底层操作
  4. 判断qq内置浏览器和微信内置浏览器
  5. GNUPLOT的学习 3 极坐标作图,三维极坐标
  6. 微信小程序中bindtap和catchtap
  7. 【Python自制软件】健康码批量识别GUI版
  8. 福建省幼儿园园长证怎么考考试报名时间及报考流程
  9. Office365 - outlook弹出‘The set of folders cannot be opened.’错误的解决方案
  10. Ubuntu: :nss_util.cc(655)] NSS_VersionCheck(3.26) failed. NSS = 3.26 is required. Please upgrad