从师父那里接了个服务,每天单机的流量并不大,峰值tips也并不高,但是CPU却高的异常。由于,服务十分重要,这个服务最高时占用了100个docker节点在跑,被逼无奈开始了异常曲折的查因和优化过程。

一般情况下,服务的主要性能瓶颈都在cpu和内存,关于内存的瓶颈之前遇到过一次,这次是第一次遇到Cpu的瓶颈。首先介绍下背景,浏览器的插件服务主要服务与QQ浏览器和所有tbs终端,每天的日活超过5亿,而服务的每天流量超过30亿。

这个服务非常重要,从师父那里接过来后一直没有任何改变,直到又一次告警才意外发现这个服务已经自动扩容了100个docker节点了。。。而且每台的负载都还很高(峰值超过70%),然后迫于运维的压力和服务的稳定性考虑,就开始了曲折的查因过程。值得注意的是,这个服务虽然日活很高(因为包含TBS),但是整体的流量不算太多,尤其平分到每个节点上流量并不大。那么问题来了,cpu到底跑哪里了。

一、perf跑火焰图

分析CPU瓶颈,最直接的方法就是用perf看看服务的Cpu到底跑哪里去了,跑的结果也很诡异:

结果显示,CPU并没有耗费在服务的具体某个函数上(火焰图也没看出来),从上面来看服务的主要消耗在int和string的构造和析构上,也就是内存的频繁申请和释放?我把这个结果在组里同步下,组里的各位大神提出了一些建议。其中,bj大神认为,既然都在内存的申请和释放上,建议我把tcmalloc编译进去用于代替libc中内存回收,说对于小内存的频繁释放用tcmalloc会好很多。ok,于是我就照做了,然而吧tcmalloc静态编进去之后,依然没用,所以,应该不是回收机制原因,所以,fail。

二、性能分析

用perf跑出来的东西并没有帮我找到瓶颈,那么只能尝试着换换方法。

于是乎:(1)尝试着查下这个进程在用户态和系统态的cpu时间比,然后想通过strace和time等分析下是不是系统调用等方面的问题,然而我分析了半天和其他服务比较了下,依然没有收获。

(2)这个时候,偶然想到可以看看服务的线程cpu占比是否均衡或者都耗在哪些线程上了。

这个时候就发现诡异的事情了,这个服务的核心线程有30个,其中20个imp主线程,10个异步回调线程,还有些其他的日志线程等。然后,其中有10个线程cpu占比是其他的7到8倍,然后用gstack打了堆栈之后,发现这10个线程居然是回调线程!!!这就奇怪了,为啥回调线程会占这么高的CPU,这个时候结合服务本身的特性,对回调后的插件过滤部分做了和主线程一样的缓存,发到线上,cpu有一定程度的降低,然而,还是没有发现根本原因。因为在单机流量并不大的情况下,服务的CPU到底跑哪里了?按照同等流量下,这个服务的CPU应该是在40%以下,然后实际是80%。而这10个异步线程为啥会这么耗CPU,我review了n遍代码,还是没能解决。。。

三、服务自身优化

这个时候,春节将至,而我查了半个月,发了4个线上版本都没有根本性改变。运维要缩容,服务由很重要,真的头疼。这个时候,就请组里的大佬(xianyi)向他们请教类似的经历和优化方法。这个时候,我们认为,虽然服务的流量不大,但是插件服务没有做任何的缓存和控制,每次请求都会做完整的计算。于是,希望通过和终端联合改版,通过其他方式把服务的计算次数降下来。然而,终端改版要时间,服务的cpu快满了,看来春节是不好过了。。。

四、找到问题or真相

万般无奈下,xianyi告诉我了他们之前关于染色debug日志优化的事情,让我试试改改说不定可以降低很多,于是乎就是下面这段代码:

#define LOG_DEBUG if(mtt_taf_debug_log()||mtt_dye_log()) (MT_LOG->debug(MT_LOG_TAG))<<
发到线上后,奇迹发生了,CPU降了60%!!!
啊,难道说那么多CPu都耗到染色滚动日志上了?我又再一次打印了线程的堆栈,
异步线程的cpu和其他的也差不多了。这个时候我查了下代码,在异步回调时,debug日志的主要是这段代码:
这里,差不多会把每次600多个插件的一些信息做循环打印,也就是说异步线程的CPU就耗在这里了吧?(后续再发个版本验证下。)总之,通过优化debug打印,确实可以优化下来很多的cpu,这个是确定的(尤其是循环打印)。这里更深层次的原因,后续还要分析下。
五、总结
曲折的优化过程,最后却是以比较简单的日志优化解决了。从中可以看出,在日常服务维护当中,经验扮演着至关重要的作用。这里要感谢xianyizhang大神的指导,同时懂得如何找问题以及找问题的方法也至关重要。

一次漫长的服务CPU优化过程的更多相关文章

  1. Linux(2)---记录一次线上服务 CPU 100%的排查过程

    Linux(2)---记录一次线上服务 CPU 100%的排查过程 当时产生CPU飙升接近100%的原因是因为项目中的websocket时时断开又重连导致CPU飙升接近100% .如何排查的呢 是通过 ...

  2. 记一次线上服务CPU 100%的处理过程

    告警 正在开会,突然钉钉告警声响个不停,同时市场人员反馈客户在投诉系统登不进了,报504错误.查看钉钉上的告警信息,几台业务服务器节点全部报CPU超过告警阈值,达100%. 赶紧从会上下来,SSH登录 ...

  3. SQL优化笔记—CPU优化

    补充:常规服务器动态管理对象包括,下面有些资料可能会应用到 dm_db_*:数据库和数据库对象dm_exec_*:执行用户代码和关联的连接dm_os_*:内存.锁定和时间安排dm_tran_*:事务和 ...

  4. PHP服务缓存优化之ZendOpcache、xcache、eAccelerator

    PHP服务缓存优化原理 Nginx 根据扩展名或者过滤规则将PHP程序请求传递给解析PHP的FCGI,也就是php-fpm进程 缓存操作码(opcode) Opcode,PHP编译后的中间文件,缓存给 ...

  5. Spark Tungsten揭秘 Day4 内存和CPU优化使用

    Spark Tungsten揭秘 Day4 内存和CPU优化使用 今天聚焦于内存和CPU的优化使用,这是Spark2.0提供的关于执行时的非常大的优化部分. 对过去的代码研究,我们会发现,抽象的提高, ...

  6. Mysql服务配置优化

    mysql服务器优化包含 硬件优化.操作系统配置优化(cpu调度.网络.内存.虚拟内存.磁盘io).Mysql服务配置优化(最大连接数.表缓存等.存储引擎).表结构优化.索引优化 总共5个方面. 本片 ...

  7. Spark Mllib里的协调过滤的概念和实现步骤、LS、ALS的原理、ALS算法优化过程的推导、隐式反馈和ALS-WR算法

    不多说,直接上干货! 常见的推荐算法 1.基于关系规则的推荐 2.基于内容的推荐 3.人口统计式的推荐 4.协调过滤式的推荐 (广泛采用) 协调过滤的概念 在现今的推荐技术和算法中,最被大家广泛认可和 ...

  8. 一个扩展搜索API的优化过程

    概述 API 是一个服务的门面,就像衣装是人的形象一样. 优雅的 API 设计,能让业务方使用起来倍儿爽,提升开发效率,降低维护成本:糟糕的 API 设计,则让业务方遭心,陷入混沌. 本文将展示一个扩 ...

  9. Netty源码解析 -- 服务端启动过程

    本文通过阅读Netty源码,解析Netty服务端启动过程. 源码分析基于Netty 4.1 Netty是一个高性能的网络通信框架,支持NIO,OIO等多种IO模式.通常,我们都是使用NIO模式,该系列 ...

随机推荐

  1. PHP——修改数据库1

    主页面——0126.php 代码: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" " ...

  2. 1.重学javascript (一)

    一.script标签解析 <script>xxx</script>这组标签,是用于在html 页面中插入js的主要方法.它主要有以下 几个属性: 1.charset:可选.表示 ...

  3. 你所不知道的JSON

    译者按: 老司机们,你知道JSON.stringify还有第二个和第三个可选参数吗?它们是什么呢? JSON已经逐渐替代XML被全世界的开发者广泛使用.本文深入讲解JavaScript中使用JSON. ...

  4. 常用gitignore模板

    作用是让临时文件和中间文件都不提交到代码库中 工程相关的.gitignore 放在根目录 常用 的有: Android.gitignore C++.gitignore C.gitignore CMak ...

  5. PHP多进程编程(3):多进程抓取网页的演示

    我们知道,从父进程到子经常的数据传递相对比较容易一些,但是从子进程传递到父进程就比较的困难. 有很多办法实现进程交互,在php中比较方便的是 管道通信.当然,还可以通过 socket_pair 进行通 ...

  6. sql 语句 查询两个字段都相同的方法

    这是替代方法 先使用着 select * from ofgroup where groupId in (select groupId from ofgroup where  uid ='". ...

  7. 无偏估计(Unbiased Estimator)

    无偏估计是参数的样本估计量的期望值等于参数的真实值. 一个简单的例子(https://www.zhihu.com/question/22983179/answer/23470969): 比如我要对某个 ...

  8. 小结:A* & IDA* & 迭代深搜

    概要: 在dfs中,如果答案的深度很小但是却很宽,而且bfs还不一定好做的情况下,我们就综合bfs的优点,结合dfs的思想,进行有限制的dfs.在这里A*.IDA*和迭代深搜都是对dfs的优化,因此放 ...

  9. 【HDU】3622 Bomb Game(2-SAT)

    http://acm.hdu.edu.cn/showproblem.php?pid=3622 又是各种逗.. 2-SAT是一种二元约束,每个点可以置于两种状态,但只能处于一种状态,然后图是否有解就是2 ...

  10. linux下面bin,sbin不理解的查阅

    在一下的文件中得到答案, 突然想想自己有点傻,自己有代码,为什么不自己查看一下代码呢 http://blog.csdn.net/ithomer/article/details/9839957