内容简介:今天双十一,木有节目!!!静静写个文章吧 :-D2018年元旦前夕,公司业务系统流量突然增加5~6倍,然而并无相关预演或准备,于是乎系统瘫痪了,钱也不再进账了,对于小公司来说,痛并快乐着!经过此次扑火抢救,个人总结了一些小经验,大厂用不上,但对总共就几个人的小微公司而言可能有些帮助。
今天双十一,木有节目!!!静静写个文章吧 :-D
2018年元旦前夕,公司业务系统流量突然增加5~6倍,然而并无相关预演或准备,于是乎系统瘫痪了,钱也不再进账了,对于小公司来说,痛并快乐着!
经过此次扑火抢救,个人总结了一些小经验,大厂用不上,但对总共就几个人的小微公司而言可能有些帮助。
PHP 技术栈,然而道理是相通的,不必纠结
简略版
- 升级至 PHP 7
- 启用 OPcache
- 借日志识别隐患和瓶颈
- 清理数据库慢查询
- 关闭 Debug 及 Log
-
增加缓存时间
补充版
-
还没升级到 PHP7 的,如果可以,建议升级。个人认为,无关性能,这一种拥抱变化、敢于挑战的追求,万年 CentOS 6.x 甚至 5.x 式的稳定就小公司而言不太好。小公司的稳定应该是花最少的钱,做最多的事,让产品迅速上线、高效运转,源源不断的正向现金流。技术债必须欠,但不应该欠太多啊!简单地说,产品技术栈不愿升级的坏处就是无法充分享受开源的好处,造轮子并非小公司的强项,当然如果是钱多得没地花的话当我没说过。
-
启用OPcache,鸟哥博客文章 《让PHP7达到最高性能的几个Tips》 第一条。
-
日志建议重点关注两点:
- php-fpm 的 slow log (如代码中是否出现usleep一类的函数?实在有必要吗?)
- 数据库的慢查询日志 (索引、触发器、存储过程等可能造成慢查询甚至锁表)
-
清理数据库慢查询
个人认为,就一般互联网小公司而言,系统瓶颈一般先出现在数据库。可能平时业务量小,硬件资源充足,问题不显现,估计都不太重视这问题。数据库连接池的问题并不是瓶颈,面对大量的慢查询再多的连接池也不管用啊,先把慢查询处掉就好了,查询慢甚至锁表可能只是个索引的问题。。。
- 关闭 Debug 这个没啥好说的,但就怕忘记了!!!至于 Log 嘛,看情况吧,要注意非异步的、可能引起阻塞的 Log (比如说直接在每一个 request 里同步写日志就不合适)
太长不看版 (复盘)
2018年元旦前夕,系统流量瞬间猛增5~6倍,可近期并无广告推广投入啊,当时第一反应是遭到攻击了,但冷静一想,哪个闲着没事盯上个小公司,多大仇啊。查看各种数据推断此次为自然流量。
由于无相关演练和应急预案,系统瘫痪了,公司收入也基本停了,痛并快乐着!
我当时首先建议升级PHP。将其中一台服务器升级后发现内存和CPU消耗减半 (注:其实并未真正解决问题)。
接着其它服务器也升级了,可尴尬的是,没过多就,系统又瘫痪了,而且多了很多错误日志。我司用的PHP框架是 Thinkphp 3.x,叠加历史遗留问题,根本不可能平滑升级。于是乎降级回到5.6的版本。
回到原点,而且问题没有解决!!!
于是乎,下一个尝试是,增加服务器数量、提高数据库连接数上限(阿里云的数据库)。然而都加倍了,压力还是没有缓解!没有缓解!换句话说,关键不在此,再加就是花冤枉钱。
接着我拿到了一台服务器的 SSH 账户。
注:我个人负责的工作比较杂乱,从 Android 到 iOS,到 JAVA web 再到 PHP web,但却没管过公司服务器的维护工作,当然我个人负责的外包项目的话就是从服务器选购、系统环境配置到项目开发、部署、维护……,从0到1全包了。
我首先启用Opcache,然后调整了 nginx 和 php-fpm 的一些参数,起到了一定的作用,但并未解决问题。
然后我顺手把 PHP 的慢执行日志 slow log 打开了。由于系统堵得厉害,一大堆的 log,没能抓到关键,当天无果。
推荐个好用的工具mosh,关键时候不掉线哦
毕竟用户也是要休息的,慢慢流量下去了,系统恢复正常。不过晚上也没梦到解决方案 :-D
第二天,继续排查,各种调参无果。中午吃过饭后,妈给我来了个电话,问我是不是在加班。这。。。
挂电话后,我犀利的眼睛注意到了一条不起眼的日志,顺着日志指示的行数,我翻看了一下代码,发现该行调用了个usleep()函数,5秒钟,我的天,没必要吧,于是乎我直接把它注释掉,重启 php-fpm,奇迹出现了,该台服务器瞬间畅通!接着排查了所有代码中出现的usleep函数,统统注释掉,重启 php-fpm。
系统恢复正常服务,钱也开始进来了。。。
然而故事到了这里还没结束!
下午流量又逐渐增加,到傍晚饭点的时候,系统又响应缓慢了,但当时我在外吃饭,没带电脑,一时也赶不回去,没办法,我只好掏出手机试试了。还好下午有先见之明,准备了个批量重启服务器php-fpm的工具,一重启它就恢复正常了,过段时间堵了就再重启,本来是有效的,可流量还在增加,慢慢地就不管用了,不过这时我已经吃完饭回到家。马上电脑打开,继续奋战!
再推荐个小工具PSSH (Parallel SSH)
最后同事定位到的原因是,另一个子系统的数据库的 session 数据表没添加索引,导致 session 过期的时批量删除的时间过长,估计是锁表了。
主系统还可能出问题的地方我都检查过了(其实我是不清楚还有个老系统在跑☺),而且 session 的驱动也从 mysql 换到了 redis,没想到的是拖后腿的是个子系统,一款已上线多年的App (此次流量全是它引来的),把数据库拖垮了。
session 表添加索引后,系统又恢复正常了。
回顾整个扑火,关键点有两个,一是usleep函数,二是数据库索引,启用OPcache是有些作用的,而关闭数据库触发器啥的也起到了不小的作用,而增加接口缓存时间的操作其实治标不治本,没有从根本上解决问题,而且这次连表面上解决问题的作用也没起到。
此次扑救的突破口在于日志,一个是 php-fpm 的日志,二个是 mysql 的慢查询日志。
在服务器资源一定的情况下,php-fpm 的进程数同样有限,如果出现进程休眠(例如usleep)或数据库连接数达上限(慢查询导致)的话,服务器资源充足的情况下没问题,但 php-fpm 的进程一旦排长队,接下来很可能就是雪崩效应,系统就瘫痪了。
以上是本人的一点经验总结,可能存在不少错误和不足,欢迎各位小伙伴来指正和讨论,谢谢!
本人普通985工科院校,经管类专业,双学位。小公司工作5年+,全包工程师,近期在寻求珠三角地区的新坑,倾向于金融沾边的方向,求介绍啊!
以上所述就是小编给大家介绍的《复盘一次小公司遇突发流量的扑火抢救》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。