概述

公司的APP使用人数慢慢多起来了,偶尔会达到C10K的状态,特别是推出活动的时候,又一次来到了C10K的路口,过了C10K,就会进入一段快速成长期。

按照我多年的经验,C10K已经不是问题了,加上兄弟姐妹们都很给力,团队里面有好几个10+年经验的高手,大家都没把这次C10K当成一回事,不曾想,尽然栽了。

什么是C10K

C10K就是并发1万请求,这时候网络服务会出现效率低下甚至完全瘫痪的问题,这就是C10K问题。

按理来说,按照现在的网络带宽,计算能力,C10K应该早就不是什么问题了,所以我们是怎么引起的呢?

过程

问题出现在某个周一的中午,并发突然增大超过C10K,带宽被占满,然后,服务就满了,APP打开都是超时,怎么回事呢?

一群10+年的同事们开始各自按照自己以前处理的经验开始排查。

看日志

这是排查问题最直接的方式了,经过日志的查看,发现了一个重要的情况,是什么呢?

数据库连接池满了,无法分配新的连接了。所以看来是,因为系统无法获得新的数据库连接,所以请求都被挂起,导致后面的请求阻塞了。嗯,所以解决方案一,

增大数据库连接池

听客服说电话要打爆了,赶快解决吧,立刻改大了数据库连接池,从300增加到了1000,数据库服务器也增加到了2000。重启,嗯~~~ ,果然没有解决,一启动,立刻连接池又爆了,所以我们解决方案二,

负载均衡去掉,改成单机服务

这解决方案是哪个兄弟提的呢,这个兄弟说在测试环境里用工具并发测试完全没问题呀,所以难道是负载均衡配置问题,我们先去掉好不好?好吧,看着客服说电话已经打爆的份上,我们赶快把它解决掉,所以,去掉负载均衡配置,改为单点,重启Nginx,嗯~~~ ,果然又没有解决,一启动,立刻连接池又爆了,所以我们解决方案三,

检查数据库慢查询

好吧,这个提议算是走在正轨上了,至少也是从日志分析过来的嘛,所以我们打开了慢查询数据,呀,不多啊,也就是说没有因为慢查询导致的连接池长期被挂起的情况,所以呢,我们再去数据库里面看看处理进程,不多啊!!!所以,我们解决方案四,

检查连接池组件

嗯,提议这个的兄弟一定是想起了那年被C3P0支配的恐惧,嗯,我们改成Druid连接池吧,不用tomcat连接池了,嗯,tomcat都不用了,换成undertow!好吧,这些都做完了,嗯~~~ , 嗯!连接池不爆了,但是为什么还是慢啊,没有解决。我们需要冷静的思考一下,看还有什么遗漏的地方。

  • 程序问题,没有
  • 组件问题,没有
  • 配置问题,没有
  • 数据库问题,没有

那么问题在哪里呢?

这时候,一个弱弱的声音冒出来了,是不是因为加了触发器啊?What?加了触发器,为什么会有这个东西?因为我们做数据处理的童鞋用的触发器来添加新数据,那为什么会用触发器这个玩意,不应该是kafka吗?😓,好吧,大家突然想起来,当时太赶时间了,所以就简单的用了触发器的粗暴又弱智的方法来同步数据,啊,是自己给自己挖了坑,又没有及时填啊。

所以,最终解决方案。

触发器,拜拜

数据库的触发器在并发量较大时,会大幅度的降低性能,所以我们的性能被严重拖累了,指数级的拖累,那么,触发器,拜拜了。删除了触发器之后,C10K问题,没有了,并发一下窜到了12K以上,流量几乎顶满,还好及时扩容,并采用了CDN来分流,这次C10K就这样完美解决了。

总结

这次的总结就是,不要用触发器,但是转念一想,我自己写代码从来不用触发器啊,所以,我的问题在于没有及时向团队分享一些best practice,所以有些以前做传统软件过来写Web系统的童鞋还是用传统软件思维在做,一句话,再忙,再赶项目,code review都不能省啊。否则,这种12年前就已经跨越的栏杆还是能绊倒你。