因为在快递行业,双十一的流量高峰往往是在13,14,15,到现在21号双十一高峰差不多接近尾声,中间遇到了有些问题值得思考
大流量击垮redis集群
- 12号下午5点20开始,流量洪峰第一波到达,直接击垮了其中一个非常重要redis集群。 我们生产环境有多个redis集群,这是其中最重要的一个,十几G的数据访问速度极慢,连接马上打满了服务器,发生雪崩,客服大量反馈服务不可用,用户投诉。 根本原因暂时还不确定,因为没时间去查,领导也暂时在高峰期不让去查这个重大生产事故,目前的猜测:
- bgsave导致redis卡住,间接拖垮了这个集群,因为当时的OPS是将近13W,还是蛮恐怖的。
- 因为双十一前进行了扩充节点,和这台redis集群有关系的机器总共扩了10台,其中每台连接数设置在80左右,然而redis集群的最大连接数当时是设置的3000,没有考虑扩redis连接数。
- 有人为的在redis集群的某机器上操作了什么命令,导致了卡住。
解决方案:关闭了某直接面向用户的大流量应用,重启redis集群,并且扩大连接数到1W,同时当天晚上紧急迁移走大量的热key到redis4.0的集群(出问题的redis集群使用2.8版本), 只保留了将近12G的不好迁移的数据在2.8版本的集群上。
GC导致的应用停顿,继而引发小型雪崩
13号那天早上值早班,生产机器偶尔出现大量告警ERROR,伴随着一些RPC调用超时。 内网间调用RPC接口是非常快的,但是看超时时间是2S,出问题时间段处理结果到达的时间是2.2s,有的甚至达到10s+ 这问题很诡异,我们有个活动的微服务,RPC接口被调用非常频繁,其中超时出错最多的出现在4号机器。 GC日志也特别奇怪,youngGC的次数非常频繁,且经常出现2s+的情况,4号机器的swap分区使用远远比其他机器要高。 当时果断增加了内存,这一点其实很奇怪因为活动微服务的集群都是用的同样的配置, 唯一不一样的地方就是开机时间,4号机器的开机时间最久远,已经500+天没有重启过了。 但是发现扩内存禁用swap分区之后还是会存在超时的问题。 马上想到了是否又GC导致的,查了下GC日志,活动的没问题了,但是调用方出事了。 调用方集群的应用配置的最大内存是4G 且有以下配置信息:
-XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps -XX:+DisableExplicitGC -XX:+ExplicitGCInvokesConcurrent
-XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=3 -XX:GCLogFileSize=5M -Dsun.rmi.dgc.client.gcInterval=3600000 -Dsun.rmi.dgc.server.gcInterval=3600000
猜测是历史原因,当初加入RMI配置的时候发现fullGC的次数太频繁,因为默认是一次,所以加上了 -Dsun.rmi.dgc.client.gcInterval=3600000
,一小时一次fullGC。 发现fullGC还是太频繁了,就加上了 -XX:+DisableExplicitGC
,完全禁用掉了系统自动的gc,这样导致了只有当老年代放不下,分配不了空间的时候才会引发一个fullGC, 所以在zabbix日志里我看到每次内存占用到了3G+的时候就开始一次fullGC,耗时10s+,这对吞吐量要求高流量高的应用是很危险的。
不进行规律性的垃圾回收对于IO密集型的非常不友好,特别是网络IO,比如一次长时间的外网接口调用结束后,对象直接活到过了年轻代的阈值晋升老年代去了。 还有单台应用的内存为12G还不如多台应用2G,垃圾回收的耗时代价是很恐怖的,不要小看设置大内存的fullGC耗时,对于吞吐量高要求的应用有时候会是致命的。
15号某后台管理系统机器频繁宕机。
傍晚的时候持续收到告警短信,XX机器宕机,脚本拉起中。。。 首先看zabbix发现堆内存一分钟内被打满了,管理系统的堆内存被打满,这是不太可能的事情,当时想到的就是某人在导数据,数据量特别大 jmap日志一看大量的xxxxExcelxxx对象在堆里,该功能是导出近200W的数据,估计耗时要十几分钟,运营人员拿不到结果很着急持续点击,导致内存溢出。
所以任何报表类的业务都不应该出现在生产的业务/管理系统里,这种情况应该走数据平台。
暂时想到的就这些,有时间再补充