面对的问题:

做后台程序经常会被问一句话,你的程序能撑多少人。一般官方一点的回答是这个得根据实际情况而定。实际上后台程序的性能是可以被量化的。我们开发的每一个服务器程序,对性能都非常有底,以为我们有数据。So,能撑多少人不少随便猜的,让数据报表来说话。

另外一种情况经常发生在开发人员之中,甲乙丙一起讨论接口实现,经常会说这么实现效率太低,那么实现效率才高等。实际上,效率高低都是相对而言的。一个函数1ms执行完毕够快吗?看起来挺快,若某接口需要此函数100次循环,那么情况就不是很乐观了。但是若此接口又是十天半个月才会被触发一次,似乎事情又变的不是很严重。说到这里想起《unix编程艺术》上关于性能优化的总结:

  • 最有效的优化往往是优化之外的,如清晰干净的设计
  • 最有效的优化就是不优化,摩尔定律会为你优化
  • 如果确定要优化,必须找到真正的瓶颈

还有一种跟性能有关的情况是,后台程序经常有很多组件组成。比如在运行期发生接口调用性能下降的情况,必须知道是那些组件性能下降引起的。如果可以实时的知道所有接口的性能数据,以上的问题都可迎刃而解。

总结如下原因,必须开启实时性能监控:

  • 我们需要知道系统的吞吐量,以此参数做部署等。
  • 实时了解各个系统组件的性能,某组件发生故障,可以及时发现
  • 获得程序接口调用热点,调用多且慢的接口才需要优化

解决方案:

后台程序开发一个专门统计性能的组件,其需要有如下功能:

  • 可以汇总性能数据,如定时将1小时内说有接口调用开销、次数等数据汇总到文件
  • 可以非常方便的与逻辑层接口集成,比如在现有接口增加一行代码即可
  • 直观的报表,性能数据写入文件必须按照通用的格式,方便工具分析数据,生成报表

性能监控组件

我实现了一个性能组件performance_daemon_t。接口如下:

//! 性能监控
class performance_daemon_t
{
public:struct perf_tool_t{perf_tool_t(const char* mod_):mod(mod_){gettimeofday(&tm, NULL);}~perf_tool_t(){struct timeval now;gettimeofday(&now, NULL);long cost = (now.tv_sec - tm.tv_sec)*1000000 + (now.tv_usec - tm.tv_usec);singleton_t<performance_daemon_t>::instance().post(mod, cost);}const char*    mod;struct timeval tm;};
public:performance_daemon_t();~performance_daemon_t();//! 启动线程,创建文件int start(const string& path_, int seconds_);//! 关闭线程int stop();//! 增加性能监控数据void post(const string& mod_, long us);

perf_tool_t 是工具类,构造和析构自动调用两次gettimeofday获取函数调用开销,例外有辅助宏定义如下:

#define AUTO_PERF() performance_daemon_t::perf_tool_t __tmp__(__FUNCTION__)#define PERF(m)     performance_daemon_t::perf_tool_t __tmp__(m)

使用示例:

void foo()
{AUTO_PERF();//! TODO -----
}int main(int argc, char* argv[])
{singleton_t<performance_daemon_t>::instance().start("perf.txt", 5); foo();
}

performance_daemon_t 每隔5秒将性能统计数据输出到perf.txt, perf.txt的内容是CVS文件格式。

报表工具:

perf.txt 文件内容还不够直观,示例内容如下:

time,mod,max_cost[us],min_cost[us],per_cost[us],request_per_second,exe_times
20120606-17:01:41,dumy,515,174,254,3937,390
20120606-17:01:41,foo,5924,4,506,1976,1030
20120606-17:01:41,test,304,8,243,4115,185
time,mod,max_cost[us],min_cost[us],per_cost[us],request_per_second,exe_times
20120606-17:11:41,dumy,1086,222,280,5571,312
20120606-17:11:41,foo,5707,194,503,1988,770
20120606-17:11:41,test,807,8,265,3773,142
time,mod,max_cost[us],min_cost[us],per_cost[us],request_per_second,exe_times
20120606-17:21:41,dumy,1086,222,680,2571,512
20120606-17:21:41,foo,5707,194,403,1388,470
20120606-17:21:41,test,807,8,265,4773,442

为生成足够友好、直观的报表,我实现了一个WEB报表页面,http://ffown.sinaapp.com/perf/, 将perf.txt 内容直接粘贴到web 页面,点击转换输出如下报表:

各个接口性能监控-折线图:

此图显示了三个接口随时间顺序的走势,可以非常清楚foo、test、dumy三个接口那个时间性能高,哪个时间性能低,一目了然。

接口热点分布图:

显示三个接口随时间调用次数走势,可以很清楚显示哪个时间段是高峰期。大饼图显示了哪个接口是热点接口,很明显,foo 接口调用次数最多,优化当优先优化foo。

组件实现浅析:

post 接口:

程序把接口调用开销投递到性能组件任务队列中,保证了对接口性能影响最小。

timer定时回调:

timer_service_t 是我用epoll 实现的定时器,主要实现如下:

void timer_service_t::run()
{struct epoll_event ev_set[64];//! interupt();struct timeval tv;do{::epoll_wait(m_efd, ev_set, 64, m_min_timeout);if (false == m_runing)//! cancel
        {break;}gettimeofday(&tv, NULL);long cur_ms = tv.tv_sec*1000 + tv.tv_usec / 1000;process_timer_callback(cur_ms);}while (true) ;
}

process_timer_callback 中检测链表内所有的定时任务,若超时,触发回调函数。

备注:

有人可能当心AUTO_PERF(); 会影响接口性能,其实其平均开销大约为1us

代码实现:

https://ffown.googlecode.com/svn/trunk/example/ff_performance

WEB 报表生成工具:

http://ffown.sinaapp.com/perf/

文档:

http://ffown.sinaapp.com/perf/perf.pdf

C++ 后台程序实时性能监控相关推荐

  1. .NetCore使用skywalking实现实时性能监控

    一.简介 很久之前写了一篇 <.Net Core 2.0+ InfluxDB+Grafana+App Metrics 实现跨平台的实时性能监控>关于NetCore性能监控的文章,使用Inf ...

  2. ASP.NET Core之跨平台的实时性能监控(2.健康检查)

    前言 上篇我们讲了<如何使用App Metrics 做一个简单的APM监控>,最后提到过健康检查这个东西. 这篇主要就是讲解健康检查的内容. 没看过上篇的,请移步:ASP.NET Core ...

  3. MySQL 的实时性能监控利器

    操作系统及MySQL数据库的实时性能状态数据尤为重要,特别是在有性能抖动的时候,这些实时的性能数据可以快速帮助你定位系统或MySQL数据库的性能瓶颈,就像你在Linux系统上使用「top,sar,io ...

  4. ASP.NET Core之跨平台的实时性能监控

    前言 前面我们聊了一下一个应用程序 应该监控的8个关键位置. 应用程序的8个关键性能指标以及测量方法 最后卖了个小关子,是关于如何监控ASP.NET Core的. 今天我们就来讲讲如何监控它,下面上效 ...

  5. .Net Core 2.0+ InfluxDB+Grafana+App Metrics 实现跨平台的实时性能监控

    一.简介 最近这段时间一直在忙,没时间写博客,负责了一个项目,从前端到后端一直忙,同时还有其他第几个项目的系统架构要处理. 去年就开始关注net core了,只是平时写写demo,没用在项目中,正好这 ...

  6. JVM-Java程序性能监控-初级篇

    前篇 - 小伙们都知道,java程序的性能监控主要是针对jvm中heap的监控~ 那么在做压力测试时如何对heap.线程等一系列的指标进行的监控的呢? 首先-你若不懂命令,那么就需要了解一套Java程 ...

  7. AspNet Core下利用 app-metrics+Grafana + InfluxDB实现高大上的性能监控界面

    在日常系统工作中,我们为了洞察系统的问题和运作情况通常会记录日志的方式来进行分析,但是在很多情况下都是被动的在出问题后才会去查日志.在很多时候,我们可能更需要相对实时的了解整个系统或者某一时段的运行的 ...

  8. 专访刘刚:360手机卫士的性能监控与优化

    作为一款移动端产品,除了要保证安全性之外,手机卫士还需要考虑尽量减少对手机资源的消耗,而要做到这些,360手机卫士对于自身的性能优化.性能监控,以及对不同产品的适配问题,有哪些改进之处值得我们借鉴呢? ...

  9. 第四章——SQLServer2008-2012资源及性能监控(1)

    原文: 第四章--SQLServer2008-2012资源及性能监控(1) 性能优化的第一步是发现问题,而发现问题通常又有两类:突发问题的侦测和常规问题的侦测,对于常规问题的侦测,通常需要有一个长效的 ...

最新文章

  1. 百度一 29 岁程序员因使用CURL命令“篡改数据”被判有期徒刑一年九个月,并没收所有违法所得
  2. 那些到了 30 岁的技术人,后来都去哪了?
  3. android-oculus
  4. version `ZLIB_1.2.3.4' not found 解决方法
  5. 架构之:软件架构漫谈
  6. Python中曲率与弯曲的转换_黎曼几何学习笔记(3)——共形数量曲率与高斯曲率...
  7. hdu 2089 不要62【数位dp】
  8. jni hook java_java通过jni调用hook无效
  9. java常用string inputStream转换
  10. 搜索python代码的软件_python小说爬虫工具,小说搜索下载软件附源码
  11. 再生核希尔伯特空间:Hilbert Space与RKHS基础
  12. 我曾经学习过的地方--中国欧盟可用性研究中心
  13. JavaScript名词shim与polyfill
  14. [转载]推荐两篇文章
  15. 在计算机中常见的硬盘接口类型有,硬盘接口类型主要有哪几种?
  16. 20210209PC版微信 网络不可用,请检查你的网络设置 的解决方法
  17. JAVA钓鱼游戏_5个小时写一个扑克牌游戏——金钩钓鱼
  18. Revit启动后,如何把你的命令显示在Revit的Ribbon(工具栏)上?
  19. 数据库查询_同时选修了两门课的学生姓名、学号
  20. 误GHOST、误一键恢复灾难应急方案

热门文章

  1. python装饰器_Python基础-装饰器
  2. Adobe illustrator 调整图例为2列 - 连载 16
  3. 新鲜出炉 | 临床基因组学数据分析实战开课啦!!!
  4. iBiology |专业的生信科普网站
  5. 送书《R语言数据分析和可视化》 | 这个为生信学习和生信作图打造的开源R教程真香!!!...
  6. 他靠一生仅有的三篇论文改变了摩尔根,后来却从生物学界销声匿迹了
  7. fcpx插件:Chinese New Year Logo Reveal农历新年logo标志片头展示
  8. c++语言while循环,c++ c语言while 循环语句入门基础教程
  9. python sqlserver 列名_报表自动化,三流用Excel,二流用Python,一流用它
  10. number输入框限制输入数字位数、字体随数字长度变化